[Interest] CBOR Questions

Jason H jhihn at gmx.com
Tue Mar 5 18:13:29 CET 2019

Questions embedded below.

> Sent: Tuesday, March 05, 2019 at 11:33 AM
> From: "Thiago Macieira" <thiago.macieira at intel.com>
> To: interest at qt-project.org
> Subject: Re: [Interest] CBOR Questions
> On Tuesday, 5 March 2019 08:15:40 PST Jason H wrote:
> > I am looking at adapting some code to move from JSON/packed data to CBOR.
> > However the first question I have is how do I know when a CBOR object is
> > done?  If I have multiple or partial CBOR objects in a QByteArray how do I
> > handle that? What if it's coming in through a QIODevice? With JSON I could
> > just look for a } of the same stack level (0) and know the object was done.
> >  How is this handled in Qt/CBOR?
> 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:
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 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.

> > 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.

> If you use the QByteArray overload of QCborValue::fromCbor, the number of 
> bytes used to parse will be stored in the QCborParserError output parameter 
> (offset member). In fact, you should use that parameter to determine whether 
> the returned QCborValue is complete or not: if the error member is NoError or 
> EndOfFile. It's entirely possible that the returned object *looks* complete 
> but isn't.

That's good to know.

Many thanks!

More information about the Interest mailing list