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 memory pool 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/zone.h"
hideakitai 0:3f9dbf1e2cb0 11 #include <stdlib.h>
hideakitai 0:3f9dbf1e2cb0 12 #include <string.h>
hideakitai 0:3f9dbf1e2cb0 13
hideakitai 0:3f9dbf1e2cb0 14 struct msgpack_zone_chunk {
hideakitai 0:3f9dbf1e2cb0 15 struct msgpack_zone_chunk* next;
hideakitai 0:3f9dbf1e2cb0 16 /* data ... */
hideakitai 0:3f9dbf1e2cb0 17 };
hideakitai 0:3f9dbf1e2cb0 18
hideakitai 0:3f9dbf1e2cb0 19 static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
hideakitai 0:3f9dbf1e2cb0 20 {
hideakitai 0:3f9dbf1e2cb0 21 msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
hideakitai 0:3f9dbf1e2cb0 22 sizeof(msgpack_zone_chunk) + chunk_size);
hideakitai 0:3f9dbf1e2cb0 23 if(chunk == NULL) {
hideakitai 0:3f9dbf1e2cb0 24 return false;
hideakitai 0:3f9dbf1e2cb0 25 }
hideakitai 0:3f9dbf1e2cb0 26
hideakitai 0:3f9dbf1e2cb0 27 cl->head = chunk;
hideakitai 0:3f9dbf1e2cb0 28 cl->free = chunk_size;
hideakitai 0:3f9dbf1e2cb0 29 cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
hideakitai 0:3f9dbf1e2cb0 30 chunk->next = NULL;
hideakitai 0:3f9dbf1e2cb0 31
hideakitai 0:3f9dbf1e2cb0 32 return true;
hideakitai 0:3f9dbf1e2cb0 33 }
hideakitai 0:3f9dbf1e2cb0 34
hideakitai 0:3f9dbf1e2cb0 35 static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
hideakitai 0:3f9dbf1e2cb0 36 {
hideakitai 0:3f9dbf1e2cb0 37 msgpack_zone_chunk* c = cl->head;
hideakitai 0:3f9dbf1e2cb0 38 while(true) {
hideakitai 0:3f9dbf1e2cb0 39 msgpack_zone_chunk* n = c->next;
hideakitai 0:3f9dbf1e2cb0 40 free(c);
hideakitai 0:3f9dbf1e2cb0 41 if(n != NULL) {
hideakitai 0:3f9dbf1e2cb0 42 c = n;
hideakitai 0:3f9dbf1e2cb0 43 } else {
hideakitai 0:3f9dbf1e2cb0 44 break;
hideakitai 0:3f9dbf1e2cb0 45 }
hideakitai 0:3f9dbf1e2cb0 46 }
hideakitai 0:3f9dbf1e2cb0 47 }
hideakitai 0:3f9dbf1e2cb0 48
hideakitai 0:3f9dbf1e2cb0 49 static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
hideakitai 0:3f9dbf1e2cb0 50 {
hideakitai 0:3f9dbf1e2cb0 51 msgpack_zone_chunk* c = cl->head;
hideakitai 0:3f9dbf1e2cb0 52 while(true) {
hideakitai 0:3f9dbf1e2cb0 53 msgpack_zone_chunk* n = c->next;
hideakitai 0:3f9dbf1e2cb0 54 if(n != NULL) {
hideakitai 0:3f9dbf1e2cb0 55 free(c);
hideakitai 0:3f9dbf1e2cb0 56 c = n;
hideakitai 0:3f9dbf1e2cb0 57 } else {
hideakitai 0:3f9dbf1e2cb0 58 cl->head = c;
hideakitai 0:3f9dbf1e2cb0 59 break;
hideakitai 0:3f9dbf1e2cb0 60 }
hideakitai 0:3f9dbf1e2cb0 61 }
hideakitai 0:3f9dbf1e2cb0 62 cl->head->next = NULL;
hideakitai 0:3f9dbf1e2cb0 63 cl->free = chunk_size;
hideakitai 0:3f9dbf1e2cb0 64 cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
hideakitai 0:3f9dbf1e2cb0 65 }
hideakitai 0:3f9dbf1e2cb0 66
hideakitai 0:3f9dbf1e2cb0 67 void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
hideakitai 0:3f9dbf1e2cb0 68 {
hideakitai 0:3f9dbf1e2cb0 69 msgpack_zone_chunk_list* const cl = &zone->chunk_list;
hideakitai 0:3f9dbf1e2cb0 70 msgpack_zone_chunk* chunk;
hideakitai 0:3f9dbf1e2cb0 71
hideakitai 0:3f9dbf1e2cb0 72 size_t sz = zone->chunk_size;
hideakitai 0:3f9dbf1e2cb0 73
hideakitai 0:3f9dbf1e2cb0 74 while(sz < size) {
hideakitai 0:3f9dbf1e2cb0 75 size_t tmp_sz = sz * 2;
hideakitai 0:3f9dbf1e2cb0 76 if (tmp_sz <= sz) {
hideakitai 0:3f9dbf1e2cb0 77 tmp_sz = size;
hideakitai 0:3f9dbf1e2cb0 78 break;
hideakitai 0:3f9dbf1e2cb0 79 }
hideakitai 0:3f9dbf1e2cb0 80 sz = tmp_sz;
hideakitai 0:3f9dbf1e2cb0 81 }
hideakitai 0:3f9dbf1e2cb0 82
hideakitai 0:3f9dbf1e2cb0 83 chunk = (msgpack_zone_chunk*)malloc(
hideakitai 0:3f9dbf1e2cb0 84 sizeof(msgpack_zone_chunk) + sz);
hideakitai 0:3f9dbf1e2cb0 85 if (chunk == NULL) {
hideakitai 0:3f9dbf1e2cb0 86 return NULL;
hideakitai 0:3f9dbf1e2cb0 87 }
hideakitai 0:3f9dbf1e2cb0 88 else {
hideakitai 0:3f9dbf1e2cb0 89 char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
hideakitai 0:3f9dbf1e2cb0 90 chunk->next = cl->head;
hideakitai 0:3f9dbf1e2cb0 91 cl->head = chunk;
hideakitai 0:3f9dbf1e2cb0 92 cl->free = sz - size;
hideakitai 0:3f9dbf1e2cb0 93 cl->ptr = ptr + size;
hideakitai 0:3f9dbf1e2cb0 94
hideakitai 0:3f9dbf1e2cb0 95 return ptr;
hideakitai 0:3f9dbf1e2cb0 96 }
hideakitai 0:3f9dbf1e2cb0 97 }
hideakitai 0:3f9dbf1e2cb0 98
hideakitai 0:3f9dbf1e2cb0 99
hideakitai 0:3f9dbf1e2cb0 100 static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
hideakitai 0:3f9dbf1e2cb0 101 {
hideakitai 0:3f9dbf1e2cb0 102 fa->tail = NULL;
hideakitai 0:3f9dbf1e2cb0 103 fa->end = NULL;
hideakitai 0:3f9dbf1e2cb0 104 fa->array = NULL;
hideakitai 0:3f9dbf1e2cb0 105 }
hideakitai 0:3f9dbf1e2cb0 106
hideakitai 0:3f9dbf1e2cb0 107 static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
hideakitai 0:3f9dbf1e2cb0 108 {
hideakitai 0:3f9dbf1e2cb0 109 msgpack_zone_finalizer* fin = fa->tail;
hideakitai 0:3f9dbf1e2cb0 110 for(; fin != fa->array; --fin) {
hideakitai 0:3f9dbf1e2cb0 111 (*(fin-1)->func)((fin-1)->data);
hideakitai 0:3f9dbf1e2cb0 112 }
hideakitai 0:3f9dbf1e2cb0 113 }
hideakitai 0:3f9dbf1e2cb0 114
hideakitai 0:3f9dbf1e2cb0 115 static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
hideakitai 0:3f9dbf1e2cb0 116 {
hideakitai 0:3f9dbf1e2cb0 117 call_finalizer_array(fa);
hideakitai 0:3f9dbf1e2cb0 118 free(fa->array);
hideakitai 0:3f9dbf1e2cb0 119 }
hideakitai 0:3f9dbf1e2cb0 120
hideakitai 0:3f9dbf1e2cb0 121 static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
hideakitai 0:3f9dbf1e2cb0 122 {
hideakitai 0:3f9dbf1e2cb0 123 call_finalizer_array(fa);
hideakitai 0:3f9dbf1e2cb0 124 fa->tail = fa->array;
hideakitai 0:3f9dbf1e2cb0 125 }
hideakitai 0:3f9dbf1e2cb0 126
hideakitai 0:3f9dbf1e2cb0 127 bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
hideakitai 0:3f9dbf1e2cb0 128 void (*func)(void* data), void* data)
hideakitai 0:3f9dbf1e2cb0 129 {
hideakitai 0:3f9dbf1e2cb0 130 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
hideakitai 0:3f9dbf1e2cb0 131 msgpack_zone_finalizer* tmp;
hideakitai 0:3f9dbf1e2cb0 132
hideakitai 0:3f9dbf1e2cb0 133 const size_t nused = (size_t)(fa->end - fa->array);
hideakitai 0:3f9dbf1e2cb0 134
hideakitai 0:3f9dbf1e2cb0 135 size_t nnext;
hideakitai 0:3f9dbf1e2cb0 136 if(nused == 0) {
hideakitai 0:3f9dbf1e2cb0 137 nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
hideakitai 0:3f9dbf1e2cb0 138 72 / sizeof(msgpack_zone_finalizer) : 8;
hideakitai 0:3f9dbf1e2cb0 139
hideakitai 0:3f9dbf1e2cb0 140 } else {
hideakitai 0:3f9dbf1e2cb0 141 nnext = nused * 2;
hideakitai 0:3f9dbf1e2cb0 142 }
hideakitai 0:3f9dbf1e2cb0 143
hideakitai 0:3f9dbf1e2cb0 144 tmp = (msgpack_zone_finalizer*)realloc(fa->array,
hideakitai 0:3f9dbf1e2cb0 145 sizeof(msgpack_zone_finalizer) * nnext);
hideakitai 0:3f9dbf1e2cb0 146 if(tmp == NULL) {
hideakitai 0:3f9dbf1e2cb0 147 return false;
hideakitai 0:3f9dbf1e2cb0 148 }
hideakitai 0:3f9dbf1e2cb0 149
hideakitai 0:3f9dbf1e2cb0 150 fa->array = tmp;
hideakitai 0:3f9dbf1e2cb0 151 fa->end = tmp + nnext;
hideakitai 0:3f9dbf1e2cb0 152 fa->tail = tmp + nused;
hideakitai 0:3f9dbf1e2cb0 153
hideakitai 0:3f9dbf1e2cb0 154 fa->tail->func = func;
hideakitai 0:3f9dbf1e2cb0 155 fa->tail->data = data;
hideakitai 0:3f9dbf1e2cb0 156
hideakitai 0:3f9dbf1e2cb0 157 ++fa->tail;
hideakitai 0:3f9dbf1e2cb0 158
hideakitai 0:3f9dbf1e2cb0 159 return true;
hideakitai 0:3f9dbf1e2cb0 160 }
hideakitai 0:3f9dbf1e2cb0 161
hideakitai 0:3f9dbf1e2cb0 162
hideakitai 0:3f9dbf1e2cb0 163 bool msgpack_zone_is_empty(msgpack_zone* zone)
hideakitai 0:3f9dbf1e2cb0 164 {
hideakitai 0:3f9dbf1e2cb0 165 msgpack_zone_chunk_list* const cl = &zone->chunk_list;
hideakitai 0:3f9dbf1e2cb0 166 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
hideakitai 0:3f9dbf1e2cb0 167 return cl->free == zone->chunk_size && cl->head->next == NULL &&
hideakitai 0:3f9dbf1e2cb0 168 fa->tail == fa->array;
hideakitai 0:3f9dbf1e2cb0 169 }
hideakitai 0:3f9dbf1e2cb0 170
hideakitai 0:3f9dbf1e2cb0 171
hideakitai 0:3f9dbf1e2cb0 172 void msgpack_zone_destroy(msgpack_zone* zone)
hideakitai 0:3f9dbf1e2cb0 173 {
hideakitai 0:3f9dbf1e2cb0 174 destroy_finalizer_array(&zone->finalizer_array);
hideakitai 0:3f9dbf1e2cb0 175 destroy_chunk_list(&zone->chunk_list);
hideakitai 0:3f9dbf1e2cb0 176 }
hideakitai 0:3f9dbf1e2cb0 177
hideakitai 0:3f9dbf1e2cb0 178 void msgpack_zone_clear(msgpack_zone* zone)
hideakitai 0:3f9dbf1e2cb0 179 {
hideakitai 0:3f9dbf1e2cb0 180 clear_finalizer_array(&zone->finalizer_array);
hideakitai 0:3f9dbf1e2cb0 181 clear_chunk_list(&zone->chunk_list, zone->chunk_size);
hideakitai 0:3f9dbf1e2cb0 182 }
hideakitai 0:3f9dbf1e2cb0 183
hideakitai 0:3f9dbf1e2cb0 184 bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
hideakitai 0:3f9dbf1e2cb0 185 {
hideakitai 0:3f9dbf1e2cb0 186 zone->chunk_size = chunk_size;
hideakitai 0:3f9dbf1e2cb0 187
hideakitai 0:3f9dbf1e2cb0 188 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
hideakitai 0:3f9dbf1e2cb0 189 return false;
hideakitai 0:3f9dbf1e2cb0 190 }
hideakitai 0:3f9dbf1e2cb0 191
hideakitai 0:3f9dbf1e2cb0 192 init_finalizer_array(&zone->finalizer_array);
hideakitai 0:3f9dbf1e2cb0 193
hideakitai 0:3f9dbf1e2cb0 194 return true;
hideakitai 0:3f9dbf1e2cb0 195 }
hideakitai 0:3f9dbf1e2cb0 196
hideakitai 0:3f9dbf1e2cb0 197 msgpack_zone* msgpack_zone_new(size_t chunk_size)
hideakitai 0:3f9dbf1e2cb0 198 {
hideakitai 0:3f9dbf1e2cb0 199 msgpack_zone* zone = (msgpack_zone*)malloc(
hideakitai 0:3f9dbf1e2cb0 200 sizeof(msgpack_zone));
hideakitai 0:3f9dbf1e2cb0 201 if(zone == NULL) {
hideakitai 0:3f9dbf1e2cb0 202 return NULL;
hideakitai 0:3f9dbf1e2cb0 203 }
hideakitai 0:3f9dbf1e2cb0 204
hideakitai 0:3f9dbf1e2cb0 205 zone->chunk_size = chunk_size;
hideakitai 0:3f9dbf1e2cb0 206
hideakitai 0:3f9dbf1e2cb0 207 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
hideakitai 0:3f9dbf1e2cb0 208 free(zone);
hideakitai 0:3f9dbf1e2cb0 209 return NULL;
hideakitai 0:3f9dbf1e2cb0 210 }
hideakitai 0:3f9dbf1e2cb0 211
hideakitai 0:3f9dbf1e2cb0 212 init_finalizer_array(&zone->finalizer_array);
hideakitai 0:3f9dbf1e2cb0 213
hideakitai 0:3f9dbf1e2cb0 214 return zone;
hideakitai 0:3f9dbf1e2cb0 215 }
hideakitai 0:3f9dbf1e2cb0 216
hideakitai 0:3f9dbf1e2cb0 217 void msgpack_zone_free(msgpack_zone* zone)
hideakitai 0:3f9dbf1e2cb0 218 {
hideakitai 0:3f9dbf1e2cb0 219 if(zone == NULL) { return; }
hideakitai 0:3f9dbf1e2cb0 220 msgpack_zone_destroy(zone);
hideakitai 0:3f9dbf1e2cb0 221 free(zone);
hideakitai 0:3f9dbf1e2cb0 222 }