messagepack implementation for embedded systems (mbed / arduino)
Dependents: hello_message_pack
objectc.c
00001 /* 00002 * MessagePack for C dynamic typing routine 00003 * 00004 * Copyright (C) 2008-2009 FURUHASHI Sadayuki 00005 * 00006 * Distributed under the Boost Software License, Version 1.0. 00007 * (See accompanying file LICENSE_1_0.txt or copy at 00008 * http://www.boost.org/LICENSE_1_0.txt) 00009 */ 00010 #include "include/object.h" 00011 #include "include/pack.h" 00012 #include <stdio.h> 00013 #include <string.h> 00014 00015 #if defined(_MSC_VER) 00016 #if _MSC_VER >= 1800 00017 #include <inttypes.h> 00018 #else 00019 #define PRIu64 "I64u" 00020 #define PRIi64 "I64i" 00021 #define PRIi8 "i" 00022 #endif 00023 #else 00024 #include <inttypes.h> 00025 #endif 00026 00027 00028 int msgpack_pack_object(msgpack_packer* pk, msgpack_object d) 00029 { 00030 switch(d.type) { 00031 case MSGPACK_OBJECT_NIL: 00032 return msgpack_pack_nil(pk); 00033 00034 case MSGPACK_OBJECT_BOOLEAN: 00035 if(d.via.boolean) { 00036 return msgpack_pack_true(pk); 00037 } else { 00038 return msgpack_pack_false(pk); 00039 } 00040 00041 case MSGPACK_OBJECT_POSITIVE_INTEGER: 00042 return msgpack_pack_uint64(pk, d.via.u64); 00043 00044 case MSGPACK_OBJECT_NEGATIVE_INTEGER: 00045 return msgpack_pack_int64(pk, d.via.i64); 00046 00047 case MSGPACK_OBJECT_FLOAT: 00048 return msgpack_pack_double(pk, d.via.f64); 00049 00050 case MSGPACK_OBJECT_STR: 00051 { 00052 int ret = msgpack_pack_str(pk, d.via.str.size); 00053 if(ret < 0) { return ret; } 00054 return msgpack_pack_str_body(pk, d.via.str.ptr, d.via.str.size); 00055 } 00056 00057 case MSGPACK_OBJECT_BIN: 00058 { 00059 int ret = msgpack_pack_bin(pk, d.via.bin.size); 00060 if(ret < 0) { return ret; } 00061 return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size); 00062 } 00063 00064 case MSGPACK_OBJECT_EXT: 00065 { 00066 int ret = msgpack_pack_ext(pk, d.via.ext.size, d.via.ext.type); 00067 if(ret < 0) { return ret; } 00068 return msgpack_pack_ext_body(pk, d.via.ext.ptr, d.via.ext.size); 00069 } 00070 00071 case MSGPACK_OBJECT_ARRAY: 00072 { 00073 int ret = msgpack_pack_array(pk, d.via.array.size); 00074 if(ret < 0) { 00075 return ret; 00076 } 00077 else { 00078 msgpack_object* o = d.via.array.ptr; 00079 msgpack_object* const oend = d.via.array.ptr + d.via.array.size; 00080 for(; o != oend; ++o) { 00081 ret = msgpack_pack_object(pk, *o); 00082 if(ret < 0) { return ret; } 00083 } 00084 00085 return 0; 00086 } 00087 } 00088 00089 case MSGPACK_OBJECT_MAP: 00090 { 00091 int ret = msgpack_pack_map(pk, d.via.map.size); 00092 if(ret < 0) { 00093 return ret; 00094 } 00095 else { 00096 msgpack_object_kv* kv = d.via.map.ptr; 00097 msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size; 00098 for(; kv != kvend; ++kv) { 00099 ret = msgpack_pack_object(pk, kv->key); 00100 if(ret < 0) { return ret; } 00101 ret = msgpack_pack_object(pk, kv->val); 00102 if(ret < 0) { return ret; } 00103 } 00104 00105 return 0; 00106 } 00107 } 00108 00109 default: 00110 return -1; 00111 } 00112 } 00113 00114 00115 void msgpack_object_print(FILE* out, msgpack_object o) 00116 { 00117 switch(o.type) { 00118 case MSGPACK_OBJECT_NIL: 00119 fprintf(out, "nil"); 00120 break; 00121 00122 case MSGPACK_OBJECT_BOOLEAN: 00123 fprintf(out, (o.via.boolean ? "true" : "false")); 00124 break; 00125 00126 case MSGPACK_OBJECT_POSITIVE_INTEGER: 00127 #if defined(PRIu64) 00128 fprintf(out, "%" PRIu64, o.via.u64); 00129 #else 00130 if (o.via.u64 > ULONG_MAX) 00131 fprintf(out, "over 4294967295"); 00132 else 00133 fprintf(out, "%lu", (unsigned long)o.via.u64); 00134 #endif 00135 break; 00136 00137 case MSGPACK_OBJECT_NEGATIVE_INTEGER: 00138 #if defined(PRIi64) 00139 fprintf(out, "%" PRIi64, o.via.i64); 00140 #else 00141 if (o.via.i64 > LONG_MAX) 00142 fprintf(out, "over +2147483647"); 00143 else if (o.via.i64 < LONG_MIN) 00144 fprintf(out, "under -2147483648"); 00145 else 00146 fprintf(out, "%ld", (signed long)o.via.i64); 00147 #endif 00148 break; 00149 00150 case MSGPACK_OBJECT_FLOAT: 00151 fprintf(out, "%f", o.via.f64); 00152 break; 00153 00154 case MSGPACK_OBJECT_STR: 00155 fprintf(out, "\""); 00156 fwrite(o.via.str.ptr, o.via.str.size, 1, out); 00157 fprintf(out, "\""); 00158 break; 00159 00160 case MSGPACK_OBJECT_BIN: 00161 fprintf(out, "\""); 00162 fwrite(o.via.bin.ptr, o.via.bin.size, 1, out); 00163 fprintf(out, "\""); 00164 break; 00165 00166 case MSGPACK_OBJECT_EXT: 00167 #if defined(PRIi8) 00168 fprintf(out, "(ext: %" PRIi8 ")", o.via.ext.type); 00169 #else 00170 fprintf(out, "(ext: %d)", (int)o.via.ext.type); 00171 #endif 00172 fprintf(out, "\""); 00173 fwrite(o.via.ext.ptr, o.via.ext.size, 1, out); 00174 fprintf(out, "\""); 00175 break; 00176 00177 case MSGPACK_OBJECT_ARRAY: 00178 fprintf(out, "["); 00179 if(o.via.array.size != 0) { 00180 msgpack_object* p = o.via.array.ptr; 00181 msgpack_object* const pend = o.via.array.ptr + o.via.array.size; 00182 msgpack_object_print(out, *p); 00183 ++p; 00184 for(; p < pend; ++p) { 00185 fprintf(out, ", "); 00186 msgpack_object_print(out, *p); 00187 } 00188 } 00189 fprintf(out, "]"); 00190 break; 00191 00192 case MSGPACK_OBJECT_MAP: 00193 fprintf(out, "{"); 00194 if(o.via.map.size != 0) { 00195 msgpack_object_kv* p = o.via.map.ptr; 00196 msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size; 00197 msgpack_object_print(out, p->key); 00198 fprintf(out, "=>"); 00199 msgpack_object_print(out, p->val); 00200 ++p; 00201 for(; p < pend; ++p) { 00202 fprintf(out, ", "); 00203 msgpack_object_print(out, p->key); 00204 fprintf(out, "=>"); 00205 msgpack_object_print(out, p->val); 00206 } 00207 } 00208 fprintf(out, "}"); 00209 break; 00210 00211 default: 00212 // FIXME 00213 #if defined(PRIu64) 00214 fprintf(out, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64); 00215 #else 00216 if (o.via.u64 > ULONG_MAX) 00217 fprintf(out, "#<UNKNOWN %i over 4294967295>", o.type); 00218 else 00219 fprintf(out, "#<UNKNOWN %i %lu>", o.type, (unsigned long)o.via.u64); 00220 #endif 00221 00222 } 00223 } 00224 00225 bool msgpack_object_equal(const msgpack_object x, const msgpack_object y) 00226 { 00227 if(x.type != y.type) { return false; } 00228 00229 switch(x.type) { 00230 case MSGPACK_OBJECT_NIL: 00231 return true; 00232 00233 case MSGPACK_OBJECT_BOOLEAN: 00234 return x.via.boolean == y.via.boolean; 00235 00236 case MSGPACK_OBJECT_POSITIVE_INTEGER: 00237 return x.via.u64 == y.via.u64; 00238 00239 case MSGPACK_OBJECT_NEGATIVE_INTEGER: 00240 return x.via.i64 == y.via.i64; 00241 00242 case MSGPACK_OBJECT_FLOAT: 00243 return x.via.f64 == y.via.f64; 00244 00245 case MSGPACK_OBJECT_STR: 00246 return x.via.str.size == y.via.str.size && 00247 memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0; 00248 00249 case MSGPACK_OBJECT_BIN: 00250 return x.via.bin.size == y.via.bin.size && 00251 memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0; 00252 00253 case MSGPACK_OBJECT_EXT: 00254 return x.via.ext.size == y.via.ext.size && 00255 x.via.ext.type == y.via.ext.type && 00256 memcmp(x.via.ext.ptr, y.via.ext.ptr, x.via.ext.size) == 0; 00257 00258 case MSGPACK_OBJECT_ARRAY: 00259 if(x.via.array.size != y.via.array.size) { 00260 return false; 00261 } else if(x.via.array.size == 0) { 00262 return true; 00263 } else { 00264 msgpack_object* px = x.via.array.ptr; 00265 msgpack_object* const pxend = x.via.array.ptr + x.via.array.size; 00266 msgpack_object* py = y.via.array.ptr; 00267 do { 00268 if(!msgpack_object_equal(*px, *py)) { 00269 return false; 00270 } 00271 ++px; 00272 ++py; 00273 } while(px < pxend); 00274 return true; 00275 } 00276 00277 case MSGPACK_OBJECT_MAP: 00278 if(x.via.map.size != y.via.map.size) { 00279 return false; 00280 } else if(x.via.map.size == 0) { 00281 return true; 00282 } else { 00283 msgpack_object_kv* px = x.via.map.ptr; 00284 msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size; 00285 msgpack_object_kv* py = y.via.map.ptr; 00286 do { 00287 if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) { 00288 return false; 00289 } 00290 ++px; 00291 ++py; 00292 } while(px < pxend); 00293 return true; 00294 } 00295 00296 default: 00297 return false; 00298 } 00299 }
Generated on Tue Jul 12 2022 22:51:46 by 1.7.2