New CBOR (RFC 7049) processing library

Status
Not open for further replies.

shawn

Well-known member
Hello. I just completed a first version of a library that does CBOR (RFC 7049, Concise Binary Object Representation) processing.

The link: libCBOR

I find this format useful for storing and transmitting JSON-like structured data (well, it is designed to work as a binary representation of JSON).
 
Please excuse my ignorance for a few questions, since I'm not familiar with CBOR, but this seems very useful!
1. What's the difference between CBOR and sharing a common set of structs? I've often transferred binary data between Teensy devices by defining structs in a library, which is included in the code base for both Teensy devices. Then sending data between them is as easy as sending the data (via serial, i2c, etc with appropriate header bytes and crc's) and memcpy'ing between a buffer and the struct. If I'm transferring data between different architectures, or want to minimize the number of bytes I send, I can just use pragma to push a 1 byte boundary.
2. The big advantage of JSON, in my opinion, is that I can look at the portion of the string that's important to that particular device. For example, in the following, I can look at just the data field while ignoring the time field.
Code:
{
  "sensor": "gps",
  "time": 1351824120,
  "data": [
    48.75608,
    2.302038
  ]
}
Is that possible with CBOR or do the structs need be identical on each device that is communicating?

Thanks! Looks potentially useful for several projects I'm working on.
Brian
 
CBOR doesn't define application structure in the same way that JSON doesn't define application structure. It's merely an encoding format for somewhat-structured data. By "somewhat-structured" I mean that there's basic types and arrays and maps, but that's it. With CBOR encoding (note that they call it "object representation" in the spec), you still have to define and have a shared meaning between devices or applications.

CBOR has maps, similar to JSON objects. You can read and write key/value pairs and choose to examine the associated value for only the keys you're interested in. But it's up to the application using this library to process and handle and store everything. libCBOR merely encodes and decodes, and also provides some convenience functions.

Hope this answers your questions.

Curious, what is this "pragma to push a 1 byte boundary" of which you speak?
 
CBOR doesn't define application structure in the same way that JSON doesn't define application structure. It's merely an encoding format for somewhat-structured data. By "somewhat-structured" I mean that there's basic types and arrays and maps, but that's it. With CBOR encoding (note that they call it "object representation" in the spec), you still have to define and have a shared meaning between devices or applications.

CBOR has maps, similar to JSON objects. You can read and write key/value pairs and choose to examine the associated value for only the keys you're interested in. But it's up to the application using this library to process and handle and store everything. libCBOR merely encodes and decodes, and also provides some convenience functions.

Hope this answers your questions.

Curious, what is this "pragma to push a 1 byte boundary" of which you speak?

That makes sense, thanks! I'll have to play with your library some when I get a chance.

Data structures are typically aligned with padding bytes. So, for instance, you can define a struct like:
Code:
struct SomeStruct {
  float x;
  char y[1];
};
Which would be 5 bytes if you just sum the sizes of the struct members, but the struct might be 8 bytes long because of padding added to the struct to maintain alignment. If you're working with two Teensy devices and don't care about the overhead of sending the 3 extra bytes, then you don't need to worry. If you are using different devices, or do care about the size of the struct, then you either have to be careful with building your struct such that you maintain alignment or you can use the following to force the compiler to use a 1 byte boundary:
Code:
#pragma pack(push, 1)
struct SomeStruct {
  float x;
  char y[1];
};
#pragma pack(pop)
 
Status
Not open for further replies.
Back
Top