lib_buffer_unpack.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <msgpack.h>
  2. #include <stdio.h>
  3. #include <assert.h>
  4. typedef struct receiver {
  5. msgpack_sbuffer sbuf;
  6. size_t rest;
  7. } receiver;
  8. void receiver_init(receiver *r) {
  9. msgpack_packer pk;
  10. msgpack_sbuffer_init(&r->sbuf);
  11. msgpack_packer_init(&pk, &r->sbuf, msgpack_sbuffer_write);
  12. /* 1st object */
  13. msgpack_pack_array(&pk, 3);
  14. msgpack_pack_int(&pk, 1);
  15. msgpack_pack_true(&pk);
  16. msgpack_pack_str(&pk, 7);
  17. msgpack_pack_str_body(&pk, "example", 7);
  18. /* 2nd object */
  19. msgpack_pack_str(&pk, 6);
  20. msgpack_pack_str_body(&pk, "second", 6);
  21. /* 3rd object */
  22. msgpack_pack_array(&pk, 2);
  23. msgpack_pack_int(&pk, 42);
  24. msgpack_pack_false(&pk);
  25. r->rest = r->sbuf.size;
  26. }
  27. size_t receiver_recv(receiver *r, char* buf, size_t try_size) {
  28. size_t off = r->sbuf.size - r->rest;
  29. size_t actual_size = try_size;
  30. if (actual_size > r->rest) actual_size = r->rest;
  31. memcpy(buf, r->sbuf.data + off, actual_size);
  32. r->rest -= actual_size;
  33. return actual_size;
  34. }
  35. size_t receiver_to_unpacker(receiver* r, size_t request_size,
  36. msgpack_unpacker *unpacker)
  37. {
  38. size_t recv_len;
  39. // make sure there's enough room, or expand the unpacker accordingly
  40. if (msgpack_unpacker_buffer_capacity(unpacker) < request_size) {
  41. msgpack_unpacker_reserve_buffer(unpacker, request_size);
  42. assert(msgpack_unpacker_buffer_capacity(unpacker) >= request_size);
  43. }
  44. recv_len = receiver_recv(r, msgpack_unpacker_buffer(unpacker),
  45. request_size);
  46. msgpack_unpacker_buffer_consumed(unpacker, recv_len);
  47. return recv_len;
  48. }
  49. #define EACH_RECV_SIZE 4
  50. void unpack(receiver* r) {
  51. /* buf is allocated by unpacker. */
  52. msgpack_unpacker* unp = msgpack_unpacker_new(100);
  53. msgpack_unpacked result;
  54. msgpack_unpack_return ret;
  55. size_t recv_len;
  56. int recv_count = 0;
  57. int i = 0;
  58. msgpack_unpacked_init(&result);
  59. while (true) {
  60. recv_len = receiver_to_unpacker(r, EACH_RECV_SIZE, unp);
  61. if (recv_len == 0) break; // (reached end of input)
  62. #if defined(_MSC_VER) || defined(__MINGW32__)
  63. printf("receive count: %d %Id bytes received.\n", recv_count++, recv_len);
  64. #else // defined(_MSC_VER) || defined(__MINGW32__)
  65. printf("receive count: %d %zd bytes received.\n", recv_count++, recv_len);
  66. #endif // defined(_MSC_VER) || defined(__MINGW32__)
  67. ret = msgpack_unpacker_next(unp, &result);
  68. while (ret == MSGPACK_UNPACK_SUCCESS) {
  69. msgpack_object obj = result.data;
  70. /* Use obj. */
  71. printf("Object no %d:\n", ++i);
  72. msgpack_object_print(stdout, obj);
  73. printf("\n");
  74. /* If you want to allocate something on the zone, you can use zone. */
  75. /* msgpack_zone* zone = result.zone; */
  76. /* The lifetime of the obj and the zone, */
  77. ret = msgpack_unpacker_next(unp, &result);
  78. }
  79. if (ret == MSGPACK_UNPACK_PARSE_ERROR) {
  80. printf("The data in the buf is invalid format.\n");
  81. msgpack_unpacked_destroy(&result);
  82. return;
  83. }
  84. }
  85. msgpack_unpacked_destroy(&result);
  86. msgpack_unpacker_free(unp);
  87. }
  88. int main(void) {
  89. receiver r;
  90. receiver_init(&r);
  91. unpack(&r);
  92. return 0;
  93. }
  94. /* Output */
  95. /*
  96. receive count: 0 4 bytes received.
  97. receive count: 1 4 bytes received.
  98. receive count: 2 4 bytes received.
  99. Object no 1:
  100. [1, true, "example"]
  101. receive count: 3 4 bytes received.
  102. receive count: 4 4 bytes received.
  103. Object no 2:
  104. "second"
  105. receive count: 5 1 bytes received.
  106. Object no 3:
  107. [42, false]
  108. */