[Interest] CBOR Questions

Jason H jhihn at gmx.com
Tue Mar 5 20:09:52 CET 2019





> Sent: Tuesday, March 05, 2019 at 1:23 PM
> From: "Thiago Macieira" <thiago.macieira at intel.com>
> To: interest at qt-project.org
> Subject: Re: [Interest] CBOR Questions
>
> On Tuesday, 5 March 2019 09:13:29 PST Jason H wrote:
> > > The parser will tell you when it's done. Both QCborStreamReader and
> > > QCborValue will read exactly one top-level value from the byte array or
> > > QIODevice and return it to you. If you have more than one value, only the
> > > first one will be read. It's up to you to decide to read more, if your
> > > protocol or file format implied that.
> > 
> > Ok, so this sounds like as long as my top-level is a QCborMap, then I should
> > get the complete map, or nothing at all. Given: 
> 
> No, you will get a partial map. My point is that you will never get more than 
> one top-level QCborValue from the parsing, but whether it's complete or not 
> can only be inferred by looking at the parser's error status.
> 
> > A1            # map(1)
> >    63         # text(3)
> >       6D6170  # "map"
> >    A3         # map(3)
> >       61      # text(1)
> >          61   # "a"
> >       19 FFFF # unsigned(65535)
> >       61      # text(1)
> >          62   # "b"
> >       20      # negative(0)
> >       61      # text(1)
> >          63   # "c"
> >       61      # text(1)
> >          66   # "f"
> > 
> > I should get the entirety of it in one read?
> 
> If all the bytes are available when you parse, yes. But if some bytes are 
> missing, you'll find that elements will be missing too. For example, if the 
> last three or four bytes are missing, you'll see the inner QCborMap with a 
> size() == 2, despite the stream clearly saying it should have had 3 items.
> 
> DO NOT rely on how the parser currently returns incomplete data. That will 
> change in the future. I'll probably insert some elements at the end to 
> indicate that the parsing is incomplete, so when resuming is possible, I can 
> find out where to continue resuming from.
> 
> > > If there's less than one full value, you'll get a parsing error. Both
> > > classes will return the partially-read value to you, but how complete
> > > that will be is really dependent on what they could make of the content.
> > > QCborStreamReader can resume parsing when you have more data (call
> > > addData() or reparse()), while QCborValue cannot yet. I have an idea how
> > > to implement that but haven't yet.
> > However if byte 0 was A2 (map(2)) that would be partial read.
> 
> Yes. And like above, the returned top QCborMap would indicate size() == 1.
> 
> > > > Fundamentally I am sending 256-1024 byte objects around which correspond
> > > > to
> > > > a QVariantMap, so ideally I would like to do: QCborMap map =
> > > > QCborValue::fromDevice(socket).toMap();
> > > > if (map.size()==0) { /* partial or no object read, retry on next
> > > > ReadyRead
> > > > */ } or
> > > > QCborMap map = QCborValue::fromByteArray(socket, &byteArray).toMap(); /*
> > > > modifies bytearray on successful decode to start at next object */
> > > 
> > > Right now, because QCborValue cannot resume parsing, you need to perform
> > > your own buffering. If you told it to read from a sequential QIODevice
> > > (like a socket) and the contents are incomplete, you won't be able to
> > > parse again, as the bytes will have been read from the socket.
> > 
> > So I'll need an application level buffer, ok.
> 
> Yes. When I have a chance to implement the parse-resuming functionality, I'll 
> post here to get feedback.

Thank you Thiago.

It seems the simplest, most reliable way to implement complete reads is to serialize the QByteArray data in a QDataStream. Unfortunately it looks like CBOR types do not have QDataStream support? If I were to request anything in terms of new API that would probably be it. 


More information about the Interest mailing list