Search code examples
cdeserializationmsgpack

How to use unpacked data msgpack-c


I know how to unpack data but don't know how to use specific data from array or map, Here's the code :

#include <msgpack.h>
#include <stdio.h>

int main(void) {
  /* msgpack::sbuffer is a simple buffer implementation. */
  msgpack_sbuffer sbuf;
  msgpack_sbuffer_init(&sbuf);

  /* serialize values into the buffer using msgpack_sbuffer_write callback
   * function. */
  msgpack_packer pk;
  msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);

  msgpack_pack_array(&pk, 3);
  msgpack_pack_int(&pk, 1);
  msgpack_pack_true(&pk);
  msgpack_pack_str(&pk, 7);
  msgpack_pack_str_body(&pk, "example", 7);

  msgpack_unpacked result;
  size_t off = 0;
  msgpack_unpack_return ret;
  int i = 0;

  msgpack_unpacked_init(&result);
  ret = msgpack_unpack_next(&result, sbuf.data, sbuf.size, &off);
  while (ret == MSGPACK_UNPACK_SUCCESS) {
    msgpack_object obj = result.data;
    printf("Object on %d:\n", ++i);
    msgpack_object_print(stdout, obj);
    printf("\n");
    ret = msgpack_unpack_next(&result, sbuf.data, sbuf.size, &off);
  }
  msgpack_unpacked_destroy(&result);

  return 0;
}

How can I store the first index of the array in a variable ?


Solution

  • msgpack-c (C version) document is here: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview#object

    In your case, the variable obj's type is msgpack_object.

    typedef struct msgpack_object {
        msgpack_object_type type;
        msgpack_object_union via;
    } msgpack_object;
    

    msgpack_object_union is defined as follows:

    typedef union {
        bool boolean;
        uint64_t u64;
        int64_t  i64;
    #if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
        double   dec; /* obsolete*/
    #endif /* MSGPACK_USE_LEGACY_NAME_AS_FLOAT */
        double   f64;
        msgpack_object_array array;
        msgpack_object_map map;
        msgpack_object_str str;
        msgpack_object_bin bin;
        msgpack_object_ext ext;
    } msgpack_object_union;
    

    msgpack_object_array is defined as follows:

    typedef struct {
        uint32_t size;
        struct msgpack_object* ptr;
    } msgpack_object_array;
    

    obj.type is MSGPACK_OBJECT_ARRAY. You can access array elements using the member via. For example, you can access the first index of the array obj.via.array.ptr[0].

    When you pack as follows:

      msgpack_pack_array(&pk, 3);
      msgpack_pack_int(&pk, 1);
      msgpack_pack_true(&pk);
      msgpack_pack_str(&pk, 7);
      msgpack_pack_str_body(&pk, "example", 7);
    

    obj has the following values:


    • obj.via.array.size is 3.

    • obj.via.array.ptr[0].type is MSGPACK_OBJECT_POSITIVE_INTEGER.
    • obj.via.array.ptr[0].via.u64 is 1.

    • obj.via.array.ptr[1].type is MSGPACK_OBJECT_BOOLEAN.
    • obj.via.array.ptr[1].via.bool is true.

    • obj.via.array.ptr[2].type is MSGPACK_OBJECT_STR.
      • obj.via.array.ptr[2].via.str.ptr is "example" (The address of the memory that the first charactor e is stored).
      • obj.via.array.ptr[2].via.str.size is 7.

    How can I store the first index of the array in a variable ?

    So you can do that as follows:

    uint64_t store_value = obj.via.array.ptr[0].via.u64;