messagepack implementation for embedded systems (mbed / arduino)

Dependents:   hello_message_pack

msgpack-c & msgpack-c++ https://github.com/msgpack/msgpack-c implementation for embedded systems (mbed / Arduino)

Committer:
hideakitai
Date:
Mon Feb 22 01:43:48 2016 +0000
Revision:
4:bd0c06dd6e92
Parent:
0:3f9dbf1e2cb0
fix throw error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hideakitai 0:3f9dbf1e2cb0 1 /*
hideakitai 0:3f9dbf1e2cb0 2 * MessagePack for C zero-copy buffer implementation
hideakitai 0:3f9dbf1e2cb0 3 *
hideakitai 0:3f9dbf1e2cb0 4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
hideakitai 0:3f9dbf1e2cb0 5 *
hideakitai 0:3f9dbf1e2cb0 6 * Distributed under the Boost Software License, Version 1.0.
hideakitai 0:3f9dbf1e2cb0 7 * (See accompanying file LICENSE_1_0.txt or copy at
hideakitai 0:3f9dbf1e2cb0 8 * http://www.boost.org/LICENSE_1_0.txt)
hideakitai 0:3f9dbf1e2cb0 9 */
hideakitai 0:3f9dbf1e2cb0 10 #include "include/vrefbuffer.h"
hideakitai 0:3f9dbf1e2cb0 11 #include <stdlib.h>
hideakitai 0:3f9dbf1e2cb0 12 #include <string.h>
hideakitai 0:3f9dbf1e2cb0 13
hideakitai 0:3f9dbf1e2cb0 14 #define MSGPACK_PACKER_MAX_BUFFER_SIZE 9
hideakitai 0:3f9dbf1e2cb0 15
hideakitai 0:3f9dbf1e2cb0 16 struct msgpack_vrefbuffer_chunk {
hideakitai 0:3f9dbf1e2cb0 17 struct msgpack_vrefbuffer_chunk* next;
hideakitai 0:3f9dbf1e2cb0 18 /* data ... */
hideakitai 0:3f9dbf1e2cb0 19 };
hideakitai 0:3f9dbf1e2cb0 20
hideakitai 0:3f9dbf1e2cb0 21 bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
hideakitai 0:3f9dbf1e2cb0 22 size_t ref_size, size_t chunk_size)
hideakitai 0:3f9dbf1e2cb0 23 {
hideakitai 0:3f9dbf1e2cb0 24 size_t nfirst;
hideakitai 0:3f9dbf1e2cb0 25 struct iovec* array;
hideakitai 0:3f9dbf1e2cb0 26 msgpack_vrefbuffer_chunk* chunk;
hideakitai 0:3f9dbf1e2cb0 27
hideakitai 0:3f9dbf1e2cb0 28 vbuf->chunk_size = chunk_size;
hideakitai 0:3f9dbf1e2cb0 29 vbuf->ref_size =
hideakitai 0:3f9dbf1e2cb0 30 ref_size > MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ?
hideakitai 0:3f9dbf1e2cb0 31 ref_size : MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ;
hideakitai 0:3f9dbf1e2cb0 32
hideakitai 0:3f9dbf1e2cb0 33 nfirst = (sizeof(struct iovec) < 72/2) ?
hideakitai 0:3f9dbf1e2cb0 34 72 / sizeof(struct iovec) : 8;
hideakitai 0:3f9dbf1e2cb0 35
hideakitai 0:3f9dbf1e2cb0 36 array = (struct iovec*)malloc(
hideakitai 0:3f9dbf1e2cb0 37 sizeof(struct iovec) * nfirst);
hideakitai 0:3f9dbf1e2cb0 38 if(array == NULL) {
hideakitai 0:3f9dbf1e2cb0 39 return false;
hideakitai 0:3f9dbf1e2cb0 40 }
hideakitai 0:3f9dbf1e2cb0 41
hideakitai 0:3f9dbf1e2cb0 42 vbuf->tail = array;
hideakitai 0:3f9dbf1e2cb0 43 vbuf->end = array + nfirst;
hideakitai 0:3f9dbf1e2cb0 44 vbuf->array = array;
hideakitai 0:3f9dbf1e2cb0 45
hideakitai 0:3f9dbf1e2cb0 46 chunk = (msgpack_vrefbuffer_chunk*)malloc(
hideakitai 0:3f9dbf1e2cb0 47 sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
hideakitai 0:3f9dbf1e2cb0 48 if(chunk == NULL) {
hideakitai 0:3f9dbf1e2cb0 49 free(array);
hideakitai 0:3f9dbf1e2cb0 50 return false;
hideakitai 0:3f9dbf1e2cb0 51 }
hideakitai 0:3f9dbf1e2cb0 52 else {
hideakitai 0:3f9dbf1e2cb0 53 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
hideakitai 0:3f9dbf1e2cb0 54
hideakitai 0:3f9dbf1e2cb0 55 ib->free = chunk_size;
hideakitai 0:3f9dbf1e2cb0 56 ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
hideakitai 0:3f9dbf1e2cb0 57 ib->head = chunk;
hideakitai 0:3f9dbf1e2cb0 58 chunk->next = NULL;
hideakitai 0:3f9dbf1e2cb0 59
hideakitai 0:3f9dbf1e2cb0 60 return true;
hideakitai 0:3f9dbf1e2cb0 61 }
hideakitai 0:3f9dbf1e2cb0 62 }
hideakitai 0:3f9dbf1e2cb0 63
hideakitai 0:3f9dbf1e2cb0 64 void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
hideakitai 0:3f9dbf1e2cb0 65 {
hideakitai 0:3f9dbf1e2cb0 66 msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
hideakitai 0:3f9dbf1e2cb0 67 while(true) {
hideakitai 0:3f9dbf1e2cb0 68 msgpack_vrefbuffer_chunk* n = c->next;
hideakitai 0:3f9dbf1e2cb0 69 free(c);
hideakitai 0:3f9dbf1e2cb0 70 if(n != NULL) {
hideakitai 0:3f9dbf1e2cb0 71 c = n;
hideakitai 0:3f9dbf1e2cb0 72 } else {
hideakitai 0:3f9dbf1e2cb0 73 break;
hideakitai 0:3f9dbf1e2cb0 74 }
hideakitai 0:3f9dbf1e2cb0 75 }
hideakitai 0:3f9dbf1e2cb0 76 free(vbuf->array);
hideakitai 0:3f9dbf1e2cb0 77 }
hideakitai 0:3f9dbf1e2cb0 78
hideakitai 0:3f9dbf1e2cb0 79 void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf)
hideakitai 0:3f9dbf1e2cb0 80 {
hideakitai 0:3f9dbf1e2cb0 81 msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next;
hideakitai 0:3f9dbf1e2cb0 82 msgpack_vrefbuffer_chunk* n;
hideakitai 0:3f9dbf1e2cb0 83 while(c != NULL) {
hideakitai 0:3f9dbf1e2cb0 84 n = c->next;
hideakitai 0:3f9dbf1e2cb0 85 free(c);
hideakitai 0:3f9dbf1e2cb0 86 c = n;
hideakitai 0:3f9dbf1e2cb0 87 }
hideakitai 0:3f9dbf1e2cb0 88
hideakitai 0:3f9dbf1e2cb0 89 {
hideakitai 0:3f9dbf1e2cb0 90 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
hideakitai 0:3f9dbf1e2cb0 91 msgpack_vrefbuffer_chunk* chunk = ib->head;
hideakitai 0:3f9dbf1e2cb0 92 chunk->next = NULL;
hideakitai 0:3f9dbf1e2cb0 93 ib->free = vbuf->chunk_size;
hideakitai 0:3f9dbf1e2cb0 94 ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
hideakitai 0:3f9dbf1e2cb0 95
hideakitai 0:3f9dbf1e2cb0 96 vbuf->tail = vbuf->array;
hideakitai 0:3f9dbf1e2cb0 97 }
hideakitai 0:3f9dbf1e2cb0 98 }
hideakitai 0:3f9dbf1e2cb0 99
hideakitai 0:3f9dbf1e2cb0 100 int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
hideakitai 0:3f9dbf1e2cb0 101 const char* buf, size_t len)
hideakitai 0:3f9dbf1e2cb0 102 {
hideakitai 0:3f9dbf1e2cb0 103 if(vbuf->tail == vbuf->end) {
hideakitai 0:3f9dbf1e2cb0 104 const size_t nused = (size_t)(vbuf->tail - vbuf->array);
hideakitai 0:3f9dbf1e2cb0 105 const size_t nnext = nused * 2;
hideakitai 0:3f9dbf1e2cb0 106
hideakitai 0:3f9dbf1e2cb0 107 struct iovec* nvec = (struct iovec*)realloc(
hideakitai 0:3f9dbf1e2cb0 108 vbuf->array, sizeof(struct iovec)*nnext);
hideakitai 0:3f9dbf1e2cb0 109 if(nvec == NULL) {
hideakitai 0:3f9dbf1e2cb0 110 return -1;
hideakitai 0:3f9dbf1e2cb0 111 }
hideakitai 0:3f9dbf1e2cb0 112
hideakitai 0:3f9dbf1e2cb0 113 vbuf->array = nvec;
hideakitai 0:3f9dbf1e2cb0 114 vbuf->end = nvec + nnext;
hideakitai 0:3f9dbf1e2cb0 115 vbuf->tail = nvec + nused;
hideakitai 0:3f9dbf1e2cb0 116 }
hideakitai 0:3f9dbf1e2cb0 117
hideakitai 0:3f9dbf1e2cb0 118 vbuf->tail->iov_base = (char*)buf;
hideakitai 0:3f9dbf1e2cb0 119 vbuf->tail->iov_len = len;
hideakitai 0:3f9dbf1e2cb0 120 ++vbuf->tail;
hideakitai 0:3f9dbf1e2cb0 121
hideakitai 0:3f9dbf1e2cb0 122 return 0;
hideakitai 0:3f9dbf1e2cb0 123 }
hideakitai 0:3f9dbf1e2cb0 124
hideakitai 0:3f9dbf1e2cb0 125 int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
hideakitai 0:3f9dbf1e2cb0 126 const char* buf, size_t len)
hideakitai 0:3f9dbf1e2cb0 127 {
hideakitai 0:3f9dbf1e2cb0 128 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
hideakitai 0:3f9dbf1e2cb0 129 char* m;
hideakitai 0:3f9dbf1e2cb0 130
hideakitai 0:3f9dbf1e2cb0 131 if(ib->free < len) {
hideakitai 0:3f9dbf1e2cb0 132 msgpack_vrefbuffer_chunk* chunk;
hideakitai 0:3f9dbf1e2cb0 133 size_t sz = vbuf->chunk_size;
hideakitai 0:3f9dbf1e2cb0 134 if(sz < len) {
hideakitai 0:3f9dbf1e2cb0 135 sz = len;
hideakitai 0:3f9dbf1e2cb0 136 }
hideakitai 0:3f9dbf1e2cb0 137
hideakitai 0:3f9dbf1e2cb0 138 chunk = (msgpack_vrefbuffer_chunk*)malloc(
hideakitai 0:3f9dbf1e2cb0 139 sizeof(msgpack_vrefbuffer_chunk) + sz);
hideakitai 0:3f9dbf1e2cb0 140 if(chunk == NULL) {
hideakitai 0:3f9dbf1e2cb0 141 return -1;
hideakitai 0:3f9dbf1e2cb0 142 }
hideakitai 0:3f9dbf1e2cb0 143
hideakitai 0:3f9dbf1e2cb0 144 chunk->next = ib->head;
hideakitai 0:3f9dbf1e2cb0 145 ib->head = chunk;
hideakitai 0:3f9dbf1e2cb0 146 ib->free = sz;
hideakitai 0:3f9dbf1e2cb0 147 ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
hideakitai 0:3f9dbf1e2cb0 148 }
hideakitai 0:3f9dbf1e2cb0 149
hideakitai 0:3f9dbf1e2cb0 150 m = ib->ptr;
hideakitai 0:3f9dbf1e2cb0 151 memcpy(m, buf, len);
hideakitai 0:3f9dbf1e2cb0 152 ib->free -= len;
hideakitai 0:3f9dbf1e2cb0 153 ib->ptr += len;
hideakitai 0:3f9dbf1e2cb0 154
hideakitai 0:3f9dbf1e2cb0 155 if(vbuf->tail != vbuf->array && m ==
hideakitai 0:3f9dbf1e2cb0 156 (const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
hideakitai 0:3f9dbf1e2cb0 157 (vbuf->tail-1)->iov_len += len;
hideakitai 0:3f9dbf1e2cb0 158 return 0;
hideakitai 0:3f9dbf1e2cb0 159 } else {
hideakitai 0:3f9dbf1e2cb0 160 return msgpack_vrefbuffer_append_ref(vbuf, m, len);
hideakitai 0:3f9dbf1e2cb0 161 }
hideakitai 0:3f9dbf1e2cb0 162 }
hideakitai 0:3f9dbf1e2cb0 163
hideakitai 0:3f9dbf1e2cb0 164 int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
hideakitai 0:3f9dbf1e2cb0 165 {
hideakitai 0:3f9dbf1e2cb0 166 size_t sz = vbuf->chunk_size;
hideakitai 0:3f9dbf1e2cb0 167
hideakitai 0:3f9dbf1e2cb0 168 msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc(
hideakitai 0:3f9dbf1e2cb0 169 sizeof(msgpack_vrefbuffer_chunk) + sz);
hideakitai 0:3f9dbf1e2cb0 170 if(empty == NULL) {
hideakitai 0:3f9dbf1e2cb0 171 return -1;
hideakitai 0:3f9dbf1e2cb0 172 }
hideakitai 0:3f9dbf1e2cb0 173
hideakitai 0:3f9dbf1e2cb0 174 empty->next = NULL;
hideakitai 0:3f9dbf1e2cb0 175
hideakitai 0:3f9dbf1e2cb0 176 {
hideakitai 0:3f9dbf1e2cb0 177 const size_t nused = (size_t)(vbuf->tail - vbuf->array);
hideakitai 0:3f9dbf1e2cb0 178 if(to->tail + nused < vbuf->end) {
hideakitai 0:3f9dbf1e2cb0 179 struct iovec* nvec;
hideakitai 0:3f9dbf1e2cb0 180 const size_t tosize = (size_t)(to->tail - to->array);
hideakitai 0:3f9dbf1e2cb0 181 const size_t reqsize = nused + tosize;
hideakitai 0:3f9dbf1e2cb0 182 size_t nnext = (size_t)(to->end - to->array) * 2;
hideakitai 0:3f9dbf1e2cb0 183 while(nnext < reqsize) {
hideakitai 0:3f9dbf1e2cb0 184 size_t tmp_nnext = nnext * 2;
hideakitai 0:3f9dbf1e2cb0 185 if (tmp_nnext <= nnext) {
hideakitai 0:3f9dbf1e2cb0 186 nnext = reqsize;
hideakitai 0:3f9dbf1e2cb0 187 break;
hideakitai 0:3f9dbf1e2cb0 188 }
hideakitai 0:3f9dbf1e2cb0 189 nnext = tmp_nnext;
hideakitai 0:3f9dbf1e2cb0 190 }
hideakitai 0:3f9dbf1e2cb0 191
hideakitai 0:3f9dbf1e2cb0 192 nvec = (struct iovec*)realloc(
hideakitai 0:3f9dbf1e2cb0 193 to->array, sizeof(struct iovec)*nnext);
hideakitai 0:3f9dbf1e2cb0 194 if(nvec == NULL) {
hideakitai 0:3f9dbf1e2cb0 195 free(empty);
hideakitai 0:3f9dbf1e2cb0 196 return -1;
hideakitai 0:3f9dbf1e2cb0 197 }
hideakitai 0:3f9dbf1e2cb0 198
hideakitai 0:3f9dbf1e2cb0 199 to->array = nvec;
hideakitai 0:3f9dbf1e2cb0 200 to->end = nvec + nnext;
hideakitai 0:3f9dbf1e2cb0 201 to->tail = nvec + tosize;
hideakitai 0:3f9dbf1e2cb0 202 }
hideakitai 0:3f9dbf1e2cb0 203
hideakitai 0:3f9dbf1e2cb0 204 memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
hideakitai 0:3f9dbf1e2cb0 205
hideakitai 0:3f9dbf1e2cb0 206 to->tail += nused;
hideakitai 0:3f9dbf1e2cb0 207 vbuf->tail = vbuf->array;
hideakitai 0:3f9dbf1e2cb0 208
hideakitai 0:3f9dbf1e2cb0 209 {
hideakitai 0:3f9dbf1e2cb0 210 msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
hideakitai 0:3f9dbf1e2cb0 211 msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
hideakitai 0:3f9dbf1e2cb0 212
hideakitai 0:3f9dbf1e2cb0 213 msgpack_vrefbuffer_chunk* last = ib->head;
hideakitai 0:3f9dbf1e2cb0 214 while(last->next != NULL) {
hideakitai 0:3f9dbf1e2cb0 215 last = last->next;
hideakitai 0:3f9dbf1e2cb0 216 }
hideakitai 0:3f9dbf1e2cb0 217 last->next = toib->head;
hideakitai 0:3f9dbf1e2cb0 218 toib->head = ib->head;
hideakitai 0:3f9dbf1e2cb0 219
hideakitai 0:3f9dbf1e2cb0 220 if(toib->free < ib->free) {
hideakitai 0:3f9dbf1e2cb0 221 toib->free = ib->free;
hideakitai 0:3f9dbf1e2cb0 222 toib->ptr = ib->ptr;
hideakitai 0:3f9dbf1e2cb0 223 }
hideakitai 0:3f9dbf1e2cb0 224
hideakitai 0:3f9dbf1e2cb0 225 ib->head = empty;
hideakitai 0:3f9dbf1e2cb0 226 ib->free = sz;
hideakitai 0:3f9dbf1e2cb0 227 ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
hideakitai 0:3f9dbf1e2cb0 228 }
hideakitai 0:3f9dbf1e2cb0 229 }
hideakitai 0:3f9dbf1e2cb0 230
hideakitai 0:3f9dbf1e2cb0 231 return 0;
hideakitai 0:3f9dbf1e2cb0 232 }