MessagePack C implementation for mbed, modified from https://github.com/msgpack/msgpack-c

Dependents:   msgpack_example

Committer:
yihui
Date:
Sat Oct 25 16:32:57 2014 +0000
Revision:
0:1382f081365b
initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:1382f081365b 1 /*
yihui 0:1382f081365b 2 * MessagePack for C memory pool implementation
yihui 0:1382f081365b 3 *
yihui 0:1382f081365b 4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
yihui 0:1382f081365b 5 *
yihui 0:1382f081365b 6 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 0:1382f081365b 7 * you may not use this file except in compliance with the License.
yihui 0:1382f081365b 8 * You may obtain a copy of the License at
yihui 0:1382f081365b 9 *
yihui 0:1382f081365b 10 * http://www.apache.org/licenses/LICENSE-2.0
yihui 0:1382f081365b 11 *
yihui 0:1382f081365b 12 * Unless required by applicable law or agreed to in writing, software
yihui 0:1382f081365b 13 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 0:1382f081365b 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 0:1382f081365b 15 * See the License for the specific language governing permissions and
yihui 0:1382f081365b 16 * limitations under the License.
yihui 0:1382f081365b 17 */
yihui 0:1382f081365b 18 #include "msgpack/zone.h"
yihui 0:1382f081365b 19 #include <stdlib.h>
yihui 0:1382f081365b 20 #include <string.h>
yihui 0:1382f081365b 21
yihui 0:1382f081365b 22 struct msgpack_zone_chunk {
yihui 0:1382f081365b 23 struct msgpack_zone_chunk* next;
yihui 0:1382f081365b 24 /* data ... */
yihui 0:1382f081365b 25 };
yihui 0:1382f081365b 26
yihui 0:1382f081365b 27 static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
yihui 0:1382f081365b 28 {
yihui 0:1382f081365b 29 msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
yihui 0:1382f081365b 30 sizeof(msgpack_zone_chunk) + chunk_size);
yihui 0:1382f081365b 31 if(chunk == NULL) {
yihui 0:1382f081365b 32 return false;
yihui 0:1382f081365b 33 }
yihui 0:1382f081365b 34
yihui 0:1382f081365b 35 cl->head = chunk;
yihui 0:1382f081365b 36 cl->free = chunk_size;
yihui 0:1382f081365b 37 cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
yihui 0:1382f081365b 38 chunk->next = NULL;
yihui 0:1382f081365b 39
yihui 0:1382f081365b 40 return true;
yihui 0:1382f081365b 41 }
yihui 0:1382f081365b 42
yihui 0:1382f081365b 43 static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
yihui 0:1382f081365b 44 {
yihui 0:1382f081365b 45 msgpack_zone_chunk* c = cl->head;
yihui 0:1382f081365b 46 while(true) {
yihui 0:1382f081365b 47 msgpack_zone_chunk* n = c->next;
yihui 0:1382f081365b 48 free(c);
yihui 0:1382f081365b 49 if(n != NULL) {
yihui 0:1382f081365b 50 c = n;
yihui 0:1382f081365b 51 } else {
yihui 0:1382f081365b 52 break;
yihui 0:1382f081365b 53 }
yihui 0:1382f081365b 54 }
yihui 0:1382f081365b 55 }
yihui 0:1382f081365b 56
yihui 0:1382f081365b 57 static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
yihui 0:1382f081365b 58 {
yihui 0:1382f081365b 59 msgpack_zone_chunk* c = cl->head;
yihui 0:1382f081365b 60 while(true) {
yihui 0:1382f081365b 61 msgpack_zone_chunk* n = c->next;
yihui 0:1382f081365b 62 if(n != NULL) {
yihui 0:1382f081365b 63 free(c);
yihui 0:1382f081365b 64 c = n;
yihui 0:1382f081365b 65 } else {
yihui 0:1382f081365b 66 cl->head = c;
yihui 0:1382f081365b 67 break;
yihui 0:1382f081365b 68 }
yihui 0:1382f081365b 69 }
yihui 0:1382f081365b 70 cl->head->next = NULL;
yihui 0:1382f081365b 71 cl->free = chunk_size;
yihui 0:1382f081365b 72 cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
yihui 0:1382f081365b 73 }
yihui 0:1382f081365b 74
yihui 0:1382f081365b 75 void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
yihui 0:1382f081365b 76 {
yihui 0:1382f081365b 77 msgpack_zone_chunk_list* const cl = &zone->chunk_list;
yihui 0:1382f081365b 78
yihui 0:1382f081365b 79 size_t sz = zone->chunk_size;
yihui 0:1382f081365b 80
yihui 0:1382f081365b 81 while(sz < size) {
yihui 0:1382f081365b 82 sz *= 2;
yihui 0:1382f081365b 83 }
yihui 0:1382f081365b 84
yihui 0:1382f081365b 85 msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
yihui 0:1382f081365b 86 sizeof(msgpack_zone_chunk) + sz);
yihui 0:1382f081365b 87 if (chunk == NULL) return NULL;
yihui 0:1382f081365b 88 char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
yihui 0:1382f081365b 89 chunk->next = cl->head;
yihui 0:1382f081365b 90 cl->head = chunk;
yihui 0:1382f081365b 91 cl->free = sz - size;
yihui 0:1382f081365b 92 cl->ptr = ptr + size;
yihui 0:1382f081365b 93
yihui 0:1382f081365b 94 return ptr;
yihui 0:1382f081365b 95 }
yihui 0:1382f081365b 96
yihui 0:1382f081365b 97
yihui 0:1382f081365b 98 static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
yihui 0:1382f081365b 99 {
yihui 0:1382f081365b 100 fa->tail = NULL;
yihui 0:1382f081365b 101 fa->end = NULL;
yihui 0:1382f081365b 102 fa->array = NULL;
yihui 0:1382f081365b 103 }
yihui 0:1382f081365b 104
yihui 0:1382f081365b 105 static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
yihui 0:1382f081365b 106 {
yihui 0:1382f081365b 107 msgpack_zone_finalizer* fin = fa->tail;
yihui 0:1382f081365b 108 for(; fin != fa->array; --fin) {
yihui 0:1382f081365b 109 (*(fin-1)->func)((fin-1)->data);
yihui 0:1382f081365b 110 }
yihui 0:1382f081365b 111 }
yihui 0:1382f081365b 112
yihui 0:1382f081365b 113 static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
yihui 0:1382f081365b 114 {
yihui 0:1382f081365b 115 call_finalizer_array(fa);
yihui 0:1382f081365b 116 free(fa->array);
yihui 0:1382f081365b 117 }
yihui 0:1382f081365b 118
yihui 0:1382f081365b 119 static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
yihui 0:1382f081365b 120 {
yihui 0:1382f081365b 121 call_finalizer_array(fa);
yihui 0:1382f081365b 122 fa->tail = fa->array;
yihui 0:1382f081365b 123 }
yihui 0:1382f081365b 124
yihui 0:1382f081365b 125 bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
yihui 0:1382f081365b 126 void (*func)(void* data), void* data)
yihui 0:1382f081365b 127 {
yihui 0:1382f081365b 128 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
yihui 0:1382f081365b 129
yihui 0:1382f081365b 130 const size_t nused = (size_t)(fa->end - fa->array);
yihui 0:1382f081365b 131
yihui 0:1382f081365b 132 size_t nnext;
yihui 0:1382f081365b 133 if(nused == 0) {
yihui 0:1382f081365b 134 nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
yihui 0:1382f081365b 135 72 / sizeof(msgpack_zone_finalizer) : 8;
yihui 0:1382f081365b 136
yihui 0:1382f081365b 137 } else {
yihui 0:1382f081365b 138 nnext = nused * 2;
yihui 0:1382f081365b 139 }
yihui 0:1382f081365b 140
yihui 0:1382f081365b 141 msgpack_zone_finalizer* tmp =
yihui 0:1382f081365b 142 (msgpack_zone_finalizer*)realloc(fa->array,
yihui 0:1382f081365b 143 sizeof(msgpack_zone_finalizer) * nnext);
yihui 0:1382f081365b 144 if(tmp == NULL) {
yihui 0:1382f081365b 145 return false;
yihui 0:1382f081365b 146 }
yihui 0:1382f081365b 147
yihui 0:1382f081365b 148 fa->array = tmp;
yihui 0:1382f081365b 149 fa->end = tmp + nnext;
yihui 0:1382f081365b 150 fa->tail = tmp + nused;
yihui 0:1382f081365b 151
yihui 0:1382f081365b 152 fa->tail->func = func;
yihui 0:1382f081365b 153 fa->tail->data = data;
yihui 0:1382f081365b 154
yihui 0:1382f081365b 155 ++fa->tail;
yihui 0:1382f081365b 156
yihui 0:1382f081365b 157 return true;
yihui 0:1382f081365b 158 }
yihui 0:1382f081365b 159
yihui 0:1382f081365b 160
yihui 0:1382f081365b 161 bool msgpack_zone_is_empty(msgpack_zone* zone)
yihui 0:1382f081365b 162 {
yihui 0:1382f081365b 163 msgpack_zone_chunk_list* const cl = &zone->chunk_list;
yihui 0:1382f081365b 164 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
yihui 0:1382f081365b 165 return cl->free == zone->chunk_size && cl->head->next == NULL &&
yihui 0:1382f081365b 166 fa->tail == fa->array;
yihui 0:1382f081365b 167 }
yihui 0:1382f081365b 168
yihui 0:1382f081365b 169
yihui 0:1382f081365b 170 void msgpack_zone_destroy(msgpack_zone* zone)
yihui 0:1382f081365b 171 {
yihui 0:1382f081365b 172 destroy_finalizer_array(&zone->finalizer_array);
yihui 0:1382f081365b 173 destroy_chunk_list(&zone->chunk_list);
yihui 0:1382f081365b 174 }
yihui 0:1382f081365b 175
yihui 0:1382f081365b 176 void msgpack_zone_clear(msgpack_zone* zone)
yihui 0:1382f081365b 177 {
yihui 0:1382f081365b 178 clear_finalizer_array(&zone->finalizer_array);
yihui 0:1382f081365b 179 clear_chunk_list(&zone->chunk_list, zone->chunk_size);
yihui 0:1382f081365b 180 }
yihui 0:1382f081365b 181
yihui 0:1382f081365b 182 bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
yihui 0:1382f081365b 183 {
yihui 0:1382f081365b 184 zone->chunk_size = chunk_size;
yihui 0:1382f081365b 185
yihui 0:1382f081365b 186 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
yihui 0:1382f081365b 187 return false;
yihui 0:1382f081365b 188 }
yihui 0:1382f081365b 189
yihui 0:1382f081365b 190 init_finalizer_array(&zone->finalizer_array);
yihui 0:1382f081365b 191
yihui 0:1382f081365b 192 return true;
yihui 0:1382f081365b 193 }
yihui 0:1382f081365b 194
yihui 0:1382f081365b 195 msgpack_zone* msgpack_zone_new(size_t chunk_size)
yihui 0:1382f081365b 196 {
yihui 0:1382f081365b 197 msgpack_zone* zone = (msgpack_zone*)malloc(
yihui 0:1382f081365b 198 sizeof(msgpack_zone) + chunk_size);
yihui 0:1382f081365b 199 if(zone == NULL) {
yihui 0:1382f081365b 200 return NULL;
yihui 0:1382f081365b 201 }
yihui 0:1382f081365b 202
yihui 0:1382f081365b 203 zone->chunk_size = chunk_size;
yihui 0:1382f081365b 204
yihui 0:1382f081365b 205 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
yihui 0:1382f081365b 206 free(zone);
yihui 0:1382f081365b 207 return NULL;
yihui 0:1382f081365b 208 }
yihui 0:1382f081365b 209
yihui 0:1382f081365b 210 init_finalizer_array(&zone->finalizer_array);
yihui 0:1382f081365b 211
yihui 0:1382f081365b 212 return zone;
yihui 0:1382f081365b 213 }
yihui 0:1382f081365b 214
yihui 0:1382f081365b 215 void msgpack_zone_free(msgpack_zone* zone)
yihui 0:1382f081365b 216 {
yihui 0:1382f081365b 217 if(zone == NULL) { return; }
yihui 0:1382f081365b 218 msgpack_zone_destroy(zone);
yihui 0:1382f081365b 219 free(zone);
yihui 0:1382f081365b 220 }
yihui 0:1382f081365b 221