[Interest] CBOR Questions

Thiago Macieira thiago.macieira at intel.com
Tue Mar 5 19:23:19 CET 2019


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.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products






More information about the Interest mailing list