Parsing cbor stream

Viewed 682

I'm trying to parse CBOR stream using tinyCBOR. Goal is to write a generic parsing code for "map type"(because i don't know how many keys are there and which are they, in cbor stream)but not for a json, I just want to get values using "key",but for getting values from key i have to know the key. Im simply able to parse the value by passing "key" in function

cbor_value_map_find_value(&main_value,"Age",&map_value);

but few things still not clear to me.

What sequence to follow, for getting key and values from CBOR stream?

For eg. following is my data in map format -

{"Roll_number": 7, "Age": 24, "Name": "USER"}

here is this binary format from cbor.me link -

   A3                        # map(3)
   6B                        # text(11)
   526F6C6C5F6E756D626572    # "Roll_number"
   07                        # unsigned(7)
   63                        # text(3)
   416765                    # "Age"
   18 18                     # unsigned(24)
   64                        # text(4)
   4E616D65                  # "Name"
   64                        # text(4)
   55534552                  # "USER"

1.How to get key from stream. like - Roll_number or AGE from stream?(sequentially getting key and values also fine).

2.After getting Roll_number value, how can i jump to next element ("Age") for getting "key" and "value".

3.How to identify that i'm reached at the "end of stream" and now there is no data ??

Any snippet code, that how to parse and which sequence of function need to follow.

Any help is appreciate. Thanks!!!

1 Answers

The example code is pretty helpful for understanding the API. To iterate over the keys and values of a map, you call cbor_value_enter_container, then cbor_value_advance until cbor_value_at_end returns true (as long as there are no nested maps or arrays you want to look inside). For example:

cbor_parser_init(input, sizeof(input), 0, &parser, &it);
if (!cbor_value_is_map(&it)) {
  return 1;
}
err = cbor_value_enter_container(&it, &map);
if (err) return 1;
while (!cbor_value_at_end(&map)) {
  // get the key.  Remember, keys don't have to be strings.
  if (!cbor_value_is_text_string(&map)) {
    return 1;
  }
  char *buf;
  size_t n;
  // Note: this also advances to the value
  err = cbor_value_dup_text_string(&map, &buf, &n, &map);
  if (err) return 1;
  printf("Key: '%*s'\n", (int)n-1, buf);

  if (strncmp(buf, "Age", n-1) == 0) {
    if (cbor_value_is_integer(&map)) {
      // Found the expected key and value type
      err = cbor_value_get_int(&map, &val);
      if (err) return 1;
      printf("age: %d\n", val);
    }
    // note: can't break here, have to keep going until the end if you want
    // `it` to still be valid.
  }
  free(buf);
  err = cbor_value_advance(&map);
  if (err) return 1;
}
err = cbor_value_leave_container(&it, &map);
if (err) return 1;
Related