123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #include <msgpack.h>
- #include <stdio.h>
- #include <assert.h>
- typedef struct receiver {
- msgpack_sbuffer sbuf;
- size_t rest;
- } receiver;
- void receiver_init(receiver *r) {
- msgpack_packer pk;
- msgpack_sbuffer_init(&r->sbuf);
- msgpack_packer_init(&pk, &r->sbuf, msgpack_sbuffer_write);
- /* 1st object */
- 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);
- /* 2nd object */
- msgpack_pack_str(&pk, 6);
- msgpack_pack_str_body(&pk, "second", 6);
- /* 3rd object */
- msgpack_pack_array(&pk, 2);
- msgpack_pack_int(&pk, 42);
- msgpack_pack_false(&pk);
- r->rest = r->sbuf.size;
- }
- size_t receiver_recv(receiver *r, char* buf, size_t try_size) {
- size_t off = r->sbuf.size - r->rest;
- size_t actual_size = try_size;
- if (actual_size > r->rest) actual_size = r->rest;
- memcpy(buf, r->sbuf.data + off, actual_size);
- r->rest -= actual_size;
- return actual_size;
- }
- size_t receiver_to_unpacker(receiver* r, size_t request_size,
- msgpack_unpacker *unpacker)
- {
- size_t recv_len;
- // make sure there's enough room, or expand the unpacker accordingly
- if (msgpack_unpacker_buffer_capacity(unpacker) < request_size) {
- msgpack_unpacker_reserve_buffer(unpacker, request_size);
- assert(msgpack_unpacker_buffer_capacity(unpacker) >= request_size);
- }
- recv_len = receiver_recv(r, msgpack_unpacker_buffer(unpacker),
- request_size);
- msgpack_unpacker_buffer_consumed(unpacker, recv_len);
- return recv_len;
- }
- #define EACH_RECV_SIZE 4
- void unpack(receiver* r) {
- /* buf is allocated by unpacker. */
- msgpack_unpacker* unp = msgpack_unpacker_new(100);
- msgpack_unpacked result;
- msgpack_unpack_return ret;
- size_t recv_len;
- int recv_count = 0;
- int i = 0;
- msgpack_unpacked_init(&result);
- while (true) {
- recv_len = receiver_to_unpacker(r, EACH_RECV_SIZE, unp);
- if (recv_len == 0) break; // (reached end of input)
- #if defined(_MSC_VER) || defined(__MINGW32__)
- printf("receive count: %d %Id bytes received.\n", recv_count++, recv_len);
- #else // defined(_MSC_VER) || defined(__MINGW32__)
- printf("receive count: %d %zd bytes received.\n", recv_count++, recv_len);
- #endif // defined(_MSC_VER) || defined(__MINGW32__)
- ret = msgpack_unpacker_next(unp, &result);
- while (ret == MSGPACK_UNPACK_SUCCESS) {
- msgpack_object obj = result.data;
- /* Use obj. */
- printf("Object no %d:\n", ++i);
- msgpack_object_print(stdout, obj);
- printf("\n");
- /* If you want to allocate something on the zone, you can use zone. */
- /* msgpack_zone* zone = result.zone; */
- /* The lifetime of the obj and the zone, */
- ret = msgpack_unpacker_next(unp, &result);
- }
- if (ret == MSGPACK_UNPACK_PARSE_ERROR) {
- printf("The data in the buf is invalid format.\n");
- msgpack_unpacked_destroy(&result);
- return;
- }
- }
- msgpack_unpacked_destroy(&result);
- msgpack_unpacker_free(unp);
- }
- int main(void) {
- receiver r;
- receiver_init(&r);
- unpack(&r);
- return 0;
- }
- /* Output */
- /*
- receive count: 0 4 bytes received.
- receive count: 1 4 bytes received.
- receive count: 2 4 bytes received.
- Object no 1:
- [1, true, "example"]
- receive count: 3 4 bytes received.
- receive count: 4 4 bytes received.
- Object no 2:
- "second"
- receive count: 5 1 bytes received.
- Object no 3:
- [42, false]
- */
|