Question

How do I work with msgpack_pack_raw and msgpack_pack_raw_body to send an unsigned char array to more importantly, how to retrieve (unpack) it? What I have done is as follows:

msgpack_sbuffer* buffer = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
msgpack_sbuffer_clear(buffer);
msgpack_pack_array(pk, 10);

unsigned char a[10] = "0123456789";
msgpack_pack_raw(pk, 10);
msgpack_pack_raw_body(pk,a,10);

and in the receiver part I have:

msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);
msgpack_object obj = msg.data;
msgpack_object* p = obj.via.array.ptr;
int length = (*p).via.raw.size;
IDPRINT(length);
unsigned char* b = (unsigned char*) malloc(length);
memcpy(b,(*p).via.raw.ptr,length);

But it throws seg fault when executing "int length = (*p).via.raw.size;".

Any idea why?

Was it helpful?

Solution

Any idea why?

This is because msgpack_pack_array(pk, 10); is not required here, since you pack your data as a raw buffer of a given size. In other words msgpack_pack_raw and msgpack_pack_raw_body are sufficient.

At unpack time, you must access its fields as follow:

  1. length: obj.via.raw.size
  2. data: obj.via.raw.ptr

see: msgpack_object_raw in object.h.

Here's a recap of how to proceed:

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

int main(void) {
  unsigned char a[10] = "0123456789";

  char *buf = NULL;
  int size;

  /* -- PACK -- */
  msgpack_sbuffer sbuf;
  msgpack_sbuffer_init(&sbuf);
  msgpack_packer pck;
  msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);

  msgpack_pack_raw(&pck, 10);
  msgpack_pack_raw_body(&pck, a, 10);

  size = sbuf.size;
  buf = malloc(sbuf.size);
  memcpy(buf, sbuf.data, sbuf.size);
  msgpack_sbuffer_destroy(&sbuf);

  /* -- UNPACK -- */
  unsigned char *b = NULL;
  int bsize = -1;

  msgpack_unpacked msg;
  msgpack_unpacked_init(&msg);
  if (msgpack_unpack_next(&msg, buf, size, NULL)) {
    msgpack_object root = msg.data;
    if (root.type == MSGPACK_OBJECT_RAW) {
      bsize = root.via.raw.size;
      b = malloc(bsize);
      memcpy(b, root.via.raw.ptr, bsize);
    }
  }

  /* -- CHECK -- */
  assert(bsize == 10);
  assert(b != NULL);
  for (int i = 0; i < bsize; i++)
    assert(b[i] == a[i]);

  printf("ok\n");

  free(buf);
  free(b);

  return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top