[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