[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