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 dynamic typing routine
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/object.h"
yihui 0:1382f081365b 19 #include "msgpack/pack.h"
yihui 0:1382f081365b 20 #include <stdio.h>
yihui 0:1382f081365b 21 #include <string.h>
yihui 0:1382f081365b 22
yihui 0:1382f081365b 23 #ifdef __MBED__
yihui 0:1382f081365b 24 #define PRIu64 "u"
yihui 0:1382f081365b 25 #define PRIi64 "d"
yihui 0:1382f081365b 26 #else
yihui 0:1382f081365b 27 #ifndef _MSC_VER
yihui 0:1382f081365b 28 #include <inttypes.h>
yihui 0:1382f081365b 29 #else
yihui 0:1382f081365b 30 #ifndef PRIu64
yihui 0:1382f081365b 31 #define PRIu64 "I64u"
yihui 0:1382f081365b 32 #endif
yihui 0:1382f081365b 33 #ifndef PRIi64
yihui 0:1382f081365b 34 #define PRIi64 "I64d"
yihui 0:1382f081365b 35 #endif
yihui 0:1382f081365b 36 #endif
yihui 0:1382f081365b 37 #endif
yihui 0:1382f081365b 38
yihui 0:1382f081365b 39
yihui 0:1382f081365b 40 int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
yihui 0:1382f081365b 41 {
yihui 0:1382f081365b 42 switch(d.type) {
yihui 0:1382f081365b 43 case MSGPACK_OBJECT_NIL:
yihui 0:1382f081365b 44 return msgpack_pack_nil(pk);
yihui 0:1382f081365b 45
yihui 0:1382f081365b 46 case MSGPACK_OBJECT_BOOLEAN:
yihui 0:1382f081365b 47 if(d.via.boolean) {
yihui 0:1382f081365b 48 return msgpack_pack_true(pk);
yihui 0:1382f081365b 49 } else {
yihui 0:1382f081365b 50 return msgpack_pack_false(pk);
yihui 0:1382f081365b 51 }
yihui 0:1382f081365b 52
yihui 0:1382f081365b 53 case MSGPACK_OBJECT_POSITIVE_INTEGER:
yihui 0:1382f081365b 54 return msgpack_pack_uint64(pk, d.via.u64);
yihui 0:1382f081365b 55
yihui 0:1382f081365b 56 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
yihui 0:1382f081365b 57 return msgpack_pack_int64(pk, d.via.i64);
yihui 0:1382f081365b 58
yihui 0:1382f081365b 59 case MSGPACK_OBJECT_DOUBLE:
yihui 0:1382f081365b 60 return msgpack_pack_double(pk, d.via.dec);
yihui 0:1382f081365b 61
yihui 0:1382f081365b 62 case MSGPACK_OBJECT_RAW:
yihui 0:1382f081365b 63 {
yihui 0:1382f081365b 64 int ret = msgpack_pack_raw(pk, d.via.raw.size);
yihui 0:1382f081365b 65 if(ret < 0) { return ret; }
yihui 0:1382f081365b 66 return msgpack_pack_raw_body(pk, d.via.raw.ptr, d.via.raw.size);
yihui 0:1382f081365b 67 }
yihui 0:1382f081365b 68
yihui 0:1382f081365b 69 case MSGPACK_OBJECT_ARRAY:
yihui 0:1382f081365b 70 {
yihui 0:1382f081365b 71 int ret = msgpack_pack_array(pk, d.via.array.size);
yihui 0:1382f081365b 72 if(ret < 0) { return ret; }
yihui 0:1382f081365b 73
yihui 0:1382f081365b 74 msgpack_object* o = d.via.array.ptr;
yihui 0:1382f081365b 75 msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
yihui 0:1382f081365b 76 for(; o != oend; ++o) {
yihui 0:1382f081365b 77 ret = msgpack_pack_object(pk, *o);
yihui 0:1382f081365b 78 if(ret < 0) { return ret; }
yihui 0:1382f081365b 79 }
yihui 0:1382f081365b 80
yihui 0:1382f081365b 81 return 0;
yihui 0:1382f081365b 82 }
yihui 0:1382f081365b 83
yihui 0:1382f081365b 84 case MSGPACK_OBJECT_MAP:
yihui 0:1382f081365b 85 {
yihui 0:1382f081365b 86 int ret = msgpack_pack_map(pk, d.via.map.size);
yihui 0:1382f081365b 87 if(ret < 0) { return ret; }
yihui 0:1382f081365b 88
yihui 0:1382f081365b 89 msgpack_object_kv* kv = d.via.map.ptr;
yihui 0:1382f081365b 90 msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
yihui 0:1382f081365b 91 for(; kv != kvend; ++kv) {
yihui 0:1382f081365b 92 ret = msgpack_pack_object(pk, kv->key);
yihui 0:1382f081365b 93 if(ret < 0) { return ret; }
yihui 0:1382f081365b 94 ret = msgpack_pack_object(pk, kv->val);
yihui 0:1382f081365b 95 if(ret < 0) { return ret; }
yihui 0:1382f081365b 96 }
yihui 0:1382f081365b 97
yihui 0:1382f081365b 98 return 0;
yihui 0:1382f081365b 99 }
yihui 0:1382f081365b 100
yihui 0:1382f081365b 101 default:
yihui 0:1382f081365b 102 return -1;
yihui 0:1382f081365b 103 }
yihui 0:1382f081365b 104 }
yihui 0:1382f081365b 105
yihui 0:1382f081365b 106
yihui 0:1382f081365b 107 void msgpack_object_print(FILE* out, msgpack_object o)
yihui 0:1382f081365b 108 {
yihui 0:1382f081365b 109 switch(o.type) {
yihui 0:1382f081365b 110 case MSGPACK_OBJECT_NIL:
yihui 0:1382f081365b 111 fprintf(out, "nil");
yihui 0:1382f081365b 112 break;
yihui 0:1382f081365b 113
yihui 0:1382f081365b 114 case MSGPACK_OBJECT_BOOLEAN:
yihui 0:1382f081365b 115 fprintf(out, (o.via.boolean ? "true" : "false"));
yihui 0:1382f081365b 116 break;
yihui 0:1382f081365b 117
yihui 0:1382f081365b 118 case MSGPACK_OBJECT_POSITIVE_INTEGER:
yihui 0:1382f081365b 119 fprintf(out, "%" PRIu64, o.via.u64);
yihui 0:1382f081365b 120 break;
yihui 0:1382f081365b 121
yihui 0:1382f081365b 122 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
yihui 0:1382f081365b 123 fprintf(out, "%" PRIi64, o.via.i64);
yihui 0:1382f081365b 124 break;
yihui 0:1382f081365b 125
yihui 0:1382f081365b 126 case MSGPACK_OBJECT_DOUBLE:
yihui 0:1382f081365b 127 fprintf(out, "%f", o.via.dec);
yihui 0:1382f081365b 128 break;
yihui 0:1382f081365b 129
yihui 0:1382f081365b 130 case MSGPACK_OBJECT_RAW:
yihui 0:1382f081365b 131 fprintf(out, "\"");
yihui 0:1382f081365b 132 fwrite(o.via.raw.ptr, o.via.raw.size, 1, out);
yihui 0:1382f081365b 133 fprintf(out, "\"");
yihui 0:1382f081365b 134 break;
yihui 0:1382f081365b 135
yihui 0:1382f081365b 136 case MSGPACK_OBJECT_ARRAY:
yihui 0:1382f081365b 137 fprintf(out, "[");
yihui 0:1382f081365b 138 if(o.via.array.size != 0) {
yihui 0:1382f081365b 139 msgpack_object* p = o.via.array.ptr;
yihui 0:1382f081365b 140 msgpack_object_print(out, *p);
yihui 0:1382f081365b 141 ++p;
yihui 0:1382f081365b 142 msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
yihui 0:1382f081365b 143 for(; p < pend; ++p) {
yihui 0:1382f081365b 144 fprintf(out, ", ");
yihui 0:1382f081365b 145 msgpack_object_print(out, *p);
yihui 0:1382f081365b 146 }
yihui 0:1382f081365b 147 }
yihui 0:1382f081365b 148 fprintf(out, "]");
yihui 0:1382f081365b 149 break;
yihui 0:1382f081365b 150
yihui 0:1382f081365b 151 case MSGPACK_OBJECT_MAP:
yihui 0:1382f081365b 152 fprintf(out, "{");
yihui 0:1382f081365b 153 if(o.via.map.size != 0) {
yihui 0:1382f081365b 154 msgpack_object_kv* p = o.via.map.ptr;
yihui 0:1382f081365b 155 msgpack_object_print(out, p->key);
yihui 0:1382f081365b 156 fprintf(out, "=>");
yihui 0:1382f081365b 157 msgpack_object_print(out, p->val);
yihui 0:1382f081365b 158 ++p;
yihui 0:1382f081365b 159 msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
yihui 0:1382f081365b 160 for(; p < pend; ++p) {
yihui 0:1382f081365b 161 fprintf(out, ", ");
yihui 0:1382f081365b 162 msgpack_object_print(out, p->key);
yihui 0:1382f081365b 163 fprintf(out, "=>");
yihui 0:1382f081365b 164 msgpack_object_print(out, p->val);
yihui 0:1382f081365b 165 }
yihui 0:1382f081365b 166 }
yihui 0:1382f081365b 167 fprintf(out, "}");
yihui 0:1382f081365b 168 break;
yihui 0:1382f081365b 169
yihui 0:1382f081365b 170 default:
yihui 0:1382f081365b 171 // FIXME
yihui 0:1382f081365b 172 fprintf(out, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64);
yihui 0:1382f081365b 173 }
yihui 0:1382f081365b 174 }
yihui 0:1382f081365b 175
yihui 0:1382f081365b 176 bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
yihui 0:1382f081365b 177 {
yihui 0:1382f081365b 178 if(x.type != y.type) { return false; }
yihui 0:1382f081365b 179
yihui 0:1382f081365b 180 switch(x.type) {
yihui 0:1382f081365b 181 case MSGPACK_OBJECT_NIL:
yihui 0:1382f081365b 182 return true;
yihui 0:1382f081365b 183
yihui 0:1382f081365b 184 case MSGPACK_OBJECT_BOOLEAN:
yihui 0:1382f081365b 185 return x.via.boolean == y.via.boolean;
yihui 0:1382f081365b 186
yihui 0:1382f081365b 187 case MSGPACK_OBJECT_POSITIVE_INTEGER:
yihui 0:1382f081365b 188 return x.via.u64 == y.via.u64;
yihui 0:1382f081365b 189
yihui 0:1382f081365b 190 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
yihui 0:1382f081365b 191 return x.via.i64 == y.via.i64;
yihui 0:1382f081365b 192
yihui 0:1382f081365b 193 case MSGPACK_OBJECT_DOUBLE:
yihui 0:1382f081365b 194 return x.via.dec == y.via.dec;
yihui 0:1382f081365b 195
yihui 0:1382f081365b 196 case MSGPACK_OBJECT_RAW:
yihui 0:1382f081365b 197 return x.via.raw.size == y.via.raw.size &&
yihui 0:1382f081365b 198 memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0;
yihui 0:1382f081365b 199
yihui 0:1382f081365b 200 case MSGPACK_OBJECT_ARRAY:
yihui 0:1382f081365b 201 if(x.via.array.size != y.via.array.size) {
yihui 0:1382f081365b 202 return false;
yihui 0:1382f081365b 203 } else if(x.via.array.size == 0) {
yihui 0:1382f081365b 204 return true;
yihui 0:1382f081365b 205 } else {
yihui 0:1382f081365b 206 msgpack_object* px = x.via.array.ptr;
yihui 0:1382f081365b 207 msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
yihui 0:1382f081365b 208 msgpack_object* py = y.via.array.ptr;
yihui 0:1382f081365b 209 do {
yihui 0:1382f081365b 210 if(!msgpack_object_equal(*px, *py)) {
yihui 0:1382f081365b 211 return false;
yihui 0:1382f081365b 212 }
yihui 0:1382f081365b 213 ++px;
yihui 0:1382f081365b 214 ++py;
yihui 0:1382f081365b 215 } while(px < pxend);
yihui 0:1382f081365b 216 return true;
yihui 0:1382f081365b 217 }
yihui 0:1382f081365b 218
yihui 0:1382f081365b 219 case MSGPACK_OBJECT_MAP:
yihui 0:1382f081365b 220 if(x.via.map.size != y.via.map.size) {
yihui 0:1382f081365b 221 return false;
yihui 0:1382f081365b 222 } else if(x.via.map.size == 0) {
yihui 0:1382f081365b 223 return true;
yihui 0:1382f081365b 224 } else {
yihui 0:1382f081365b 225 msgpack_object_kv* px = x.via.map.ptr;
yihui 0:1382f081365b 226 msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
yihui 0:1382f081365b 227 msgpack_object_kv* py = y.via.map.ptr;
yihui 0:1382f081365b 228 do {
yihui 0:1382f081365b 229 if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
yihui 0:1382f081365b 230 return false;
yihui 0:1382f081365b 231 }
yihui 0:1382f081365b 232 ++px;
yihui 0:1382f081365b 233 ++py;
yihui 0:1382f081365b 234 } while(px < pxend);
yihui 0:1382f081365b 235 return true;
yihui 0:1382f081365b 236 }
yihui 0:1382f081365b 237
yihui 0:1382f081365b 238 default:
yihui 0:1382f081365b 239 return false;
yihui 0:1382f081365b 240 }
yihui 0:1382f081365b 241 }