Samuel Mokrani / MbedJSONValue

Minimalist JSON parser and serializer (inspired by picojson). Used by MbedJSONRpc.

Dependents:   RPC_mbed_client WebSocket_test pseudo_comet RPC_Wifly_HelloWorld ... more

Committer:
samux
Date:
Thu Sep 22 10:57:37 2011 +0000
Revision:
4:10a99cdf7846
Parent:
2:e39bfa3e917d

    

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux0:0cf0e27feaad 1#include "MbedJSONValue.h"
samux0:0cf0e27feaad 2
samux0:0cf0e27feaad 3# include <stdlib.h>
samux0:0cf0e27feaad 4# include <stdio.h>
samux0:0cf0e27feaad 5
samux0:0cf0e27feaad 6// Clean up
samux0:0cf0e27feaad 7void MbedJSONValue::clean() {
samux0:0cf0e27feaad 8 switch (_type) {
samux0:0cf0e27feaad 9 case TypeString:
samux0:0cf0e27feaad 10 delete _value.asString;
samux0:0cf0e27feaad 11 break;
samux0:0cf0e27feaad 12 case TypeArray:
samux0:0cf0e27feaad 13 for (int i = 0; i < index_array; i++)
samux0:0cf0e27feaad 14 delete array[i];
samux0:0cf0e27feaad 15 index_array = 0;
samux0:0cf0e27feaad 16 break;
samux0:0cf0e27feaad 17 case TypeObject:
samux0:0cf0e27feaad 18 for (int i = 0; i < index_token; i++) {
samux0:0cf0e27feaad 19 delete token[i];
samux0:0cf0e27feaad 20 delete token_name[i];
samux0:0cf0e27feaad 21 }
samux0:0cf0e27feaad 22 index_token = 0;
samux0:0cf0e27feaad 23 break;
samux0:0cf0e27feaad 24 default:
samux0:0cf0e27feaad 25 break;
samux0:0cf0e27feaad 26 }
samux0:0cf0e27feaad 27 _type = TypeNull;
samux0:0cf0e27feaad 28 _type = TypeNull;
samux0:0cf0e27feaad 29}
samux0:0cf0e27feaad 30
samux0:0cf0e27feaad 31bool MbedJSONValue::hasMember(char * name)
samux0:0cf0e27feaad 32{
samux0:0cf0e27feaad 33 for(int i = 0; i < index_token; i++)
samux0:0cf0e27feaad 34 if( !strcmp(name, (*(token_name[i])).c_str() ))
samux0:0cf0e27feaad 35 return true;
samux0:0cf0e27feaad 36 return false;
samux0:0cf0e27feaad 37}
samux0:0cf0e27feaad 38
samux0:0cf0e27feaad 39
samux0:0cf0e27feaad 40void copy(const std::string& s, std::back_insert_iterator<std::string> oi) {
samux0:0cf0e27feaad 41 std::copy(s.begin(), s.end(), oi);
samux0:0cf0e27feaad 42}
samux0:0cf0e27feaad 43
samux0:0cf0e27feaad 44void serialize_str(const std::string& s, std::back_insert_iterator<std::string> oi) {
samux0:0cf0e27feaad 45 *oi++ = '"';
samux0:0cf0e27feaad 46 for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
samux0:0cf0e27feaad 47 switch (*i) {
samux0:0cf0e27feaad 48#define MAP(val, sym) case val: copy(sym, oi); break
samux0:0cf0e27feaad 49 MAP('"', "\\\"");
samux0:0cf0e27feaad 50 MAP('\\', "\\\\");
samux0:0cf0e27feaad 51 MAP('/', "\\/");
samux0:0cf0e27feaad 52 MAP('\b', "\\b");
samux0:0cf0e27feaad 53 MAP('\f', "\\f");
samux0:0cf0e27feaad 54 MAP('\n', "\\n");
samux0:0cf0e27feaad 55 MAP('\r', "\\r");
samux0:0cf0e27feaad 56 MAP('\t', "\\t");
samux0:0cf0e27feaad 57#undef MAP
samux0:0cf0e27feaad 58 default:
samux0:0cf0e27feaad 59 if ((unsigned char)*i < 0x20 || *i == 0x7f) {
samux0:0cf0e27feaad 60 char buf[7];
samux0:0cf0e27feaad 61 sprintf(buf, "\\u%04x", *i & 0xff);
samux0:0cf0e27feaad 62 copy(buf, buf + 6, oi);
samux0:0cf0e27feaad 63 } else {
samux0:0cf0e27feaad 64 *oi++ = *i;
samux0:0cf0e27feaad 65 }
samux0:0cf0e27feaad 66 break;
samux0:0cf0e27feaad 67 }
samux0:0cf0e27feaad 68 }
samux0:0cf0e27feaad 69 *oi++ = '"';
samux0:0cf0e27feaad 70}
samux0:0cf0e27feaad 71
samux0:0cf0e27feaad 72std::string MbedJSONValue::serialize(){
samux0:0cf0e27feaad 73 std::string s;
samux0:0cf0e27feaad 74 serialize(std::back_inserter(s));
samux0:0cf0e27feaad 75 return s;
samux0:0cf0e27feaad 76}
samux0:0cf0e27feaad 77
samux0:0cf0e27feaad 78std::string MbedJSONValue::to_str(){
samux0:0cf0e27feaad 79 switch (_type) {
samux0:0cf0e27feaad 80 case TypeNull:
samux0:0cf0e27feaad 81 return "null";
samux0:0cf0e27feaad 82 case TypeBoolean:
samux0:0cf0e27feaad 83 return _value.asBool ? "true" : "false";
samux0:0cf0e27feaad 84 case TypeInt: {
samux0:0cf0e27feaad 85 char buf[10];
samux0:0cf0e27feaad 86 sprintf(buf, "%d", _value.asInt);
samux0:0cf0e27feaad 87 return buf;
samux0:0cf0e27feaad 88 }
samux0:0cf0e27feaad 89 case TypeDouble: {
samux0:0cf0e27feaad 90 char buf[10];
samux0:0cf0e27feaad 91 sprintf(buf, "%f", _value.asDouble);
samux0:0cf0e27feaad 92 return buf;
samux0:0cf0e27feaad 93 }
samux0:0cf0e27feaad 94 default:
samux0:0cf0e27feaad 95 break;
samux0:0cf0e27feaad 96 }
samux0:0cf0e27feaad 97 return NULL;
samux0:0cf0e27feaad 98}
samux0:0cf0e27feaad 99
samux0:0cf0e27feaad 100
samux0:0cf0e27feaad 101
samux0:0cf0e27feaad 102void MbedJSONValue::serialize(std::back_insert_iterator<std::string> oi) {
samux0:0cf0e27feaad 103 switch (_type) {
samux0:0cf0e27feaad 104 case TypeString:
samux0:0cf0e27feaad 105 serialize_str(*_value.asString, oi);
samux0:0cf0e27feaad 106 break;
samux0:0cf0e27feaad 107 case TypeArray: {
samux0:0cf0e27feaad 108 *oi++ = '[';
samux0:0cf0e27feaad 109 for (int i = 0; i < index_array; i++) {
samux0:0cf0e27feaad 110 if (i)
samux0:0cf0e27feaad 111 *oi++ = ',';
samux0:0cf0e27feaad 112 (*this)[i].serialize(oi);
samux0:0cf0e27feaad 113 }
samux0:0cf0e27feaad 114 *oi++ = ']';
samux0:0cf0e27feaad 115 break;
samux0:0cf0e27feaad 116 }
samux0:0cf0e27feaad 117 case TypeObject: {
samux0:0cf0e27feaad 118 *oi++ = '{';
samux0:0cf0e27feaad 119 for (int i = 0; i < index_token; i++) {
samux0:0cf0e27feaad 120 if (i)
samux0:0cf0e27feaad 121 *oi++ = ',';
samux0:0cf0e27feaad 122 serialize_str(*(token_name[i]), oi);
samux0:0cf0e27feaad 123 *oi++ = ':';
samux0:0cf0e27feaad 124 (*(token[i])).serialize(oi);
samux0:0cf0e27feaad 125 }
samux0:0cf0e27feaad 126 *oi++ = '}';
samux0:0cf0e27feaad 127 break;
samux0:0cf0e27feaad 128 }
samux0:0cf0e27feaad 129 default:
samux0:0cf0e27feaad 130 copy(to_str(), oi);
samux0:0cf0e27feaad 131 break;
samux0:0cf0e27feaad 132 }
samux0:0cf0e27feaad 133}
samux0:0cf0e27feaad 134
samux0:0cf0e27feaad 135
samux0:0cf0e27feaad 136
samux0:0cf0e27feaad 137MbedJSONValue& MbedJSONValue::operator[](int i) {
samux0:0cf0e27feaad 138 _type = TypeArray;
samux0:0cf0e27feaad 139 if (i < NB_TOKEN && index_array == i ) {
samux0:0cf0e27feaad 140#ifdef DEBUG
samux0:0cf0e27feaad 141 printf("will add an element to the array\r\n");
samux0:0cf0e27feaad 142#endif
samux0:0cf0e27feaad 143 array[i] = new MbedJSONValue();
samux0:0cf0e27feaad 144 index_array++;
samux0:0cf0e27feaad 145 return *(array[i]);
samux0:0cf0e27feaad 146 }
samux0:0cf0e27feaad 147 if (i < NB_TOKEN && index_array > i)
samux0:0cf0e27feaad 148 return *(array[i]);
samux0:0cf0e27feaad 149
samux0:0cf0e27feaad 150 //if the user is not doing something wrong, this code is never executed!!
samux0:0cf0e27feaad 151 return *(new MbedJSONValue());
samux0:0cf0e27feaad 152}
samux0:0cf0e27feaad 153
samux0:0cf0e27feaad 154MbedJSONValue& MbedJSONValue::operator[](std::string k) {
samux0:0cf0e27feaad 155 _type = TypeObject;
samux0:0cf0e27feaad 156 for (int i = 0; i < index_token; i++) {
samux0:0cf0e27feaad 157#ifdef DEBUG
samux0:0cf0e27feaad 158 printf("k: %s\r\n", k.c_str());
samux0:0cf0e27feaad 159 printf("str: %s\r\n", token_name[i]->c_str());
samux0:0cf0e27feaad 160#endif
samux0:0cf0e27feaad 161 //existing token
samux0:0cf0e27feaad 162 if (!strcmp(k.c_str(), token_name[i]->c_str())) {
samux0:0cf0e27feaad 163#ifdef DEBUG
samux0:0cf0e27feaad 164 printf("token found: %d\r\n", i);
samux0:0cf0e27feaad 165#endif
samux0:0cf0e27feaad 166 return *(token[i]);
samux0:0cf0e27feaad 167 }
samux0:0cf0e27feaad 168 }
samux0:0cf0e27feaad 169
samux0:0cf0e27feaad 170 if(index_token >= NB_TOKEN)
samux0:0cf0e27feaad 171 index_token = NB_TOKEN - 1;
samux0:0cf0e27feaad 172 //non existing token
samux0:0cf0e27feaad 173 token_name[index_token] = new std::string(k);
samux0:0cf0e27feaad 174 token[index_token] = new MbedJSONValue();
samux0:0cf0e27feaad 175 index_token++;
samux0:0cf0e27feaad 176 return *(token[index_token - 1]);
samux0:0cf0e27feaad 177}
samux0:0cf0e27feaad 178
samux0:0cf0e27feaad 179MbedJSONValue& MbedJSONValue::operator[](std::string k) const
samux0:0cf0e27feaad 180{
samux0:0cf0e27feaad 181 for (int i = 0; i < index_token; i++) {
samux0:0cf0e27feaad 182#ifdef DEBUG
samux0:0cf0e27feaad 183 printf("k: %s\r\n", k.c_str());
samux0:0cf0e27feaad 184 printf("str: %s\r\n", token_name[i]->c_str());
samux0:0cf0e27feaad 185#endif
samux0:0cf0e27feaad 186 if (!strcmp(k.c_str(), token_name[i]->c_str())) {
samux0:0cf0e27feaad 187#ifdef DEBUG
samux0:0cf0e27feaad 188 printf("token found: %d\r\n", i);
samux0:0cf0e27feaad 189#endif
samux0:0cf0e27feaad 190 return *(token[i]);
samux0:0cf0e27feaad 191 }
samux0:0cf0e27feaad 192 }
samux0:0cf0e27feaad 193
samux0:0cf0e27feaad 194 //if the user is not doing something wrong, this code is never executed!!
samux0:0cf0e27feaad 195 return *(new MbedJSONValue());
samux0:0cf0e27feaad 196}
samux0:0cf0e27feaad 197
samux0:0cf0e27feaad 198
samux0:0cf0e27feaad 199// Operators
samux0:0cf0e27feaad 200MbedJSONValue& MbedJSONValue::operator=(MbedJSONValue const& rhs) {
samux0:0cf0e27feaad 201 if (this != &rhs) {
samux0:0cf0e27feaad 202 clean();
samux0:0cf0e27feaad 203 _type = rhs._type;
samux0:0cf0e27feaad 204 switch (_type) {
samux0:0cf0e27feaad 205 case TypeBoolean:
samux0:0cf0e27feaad 206 _value.asBool = rhs._value.asBool;
samux0:0cf0e27feaad 207 break;
samux0:0cf0e27feaad 208 case TypeInt:
samux0:0cf0e27feaad 209 _value.asInt = rhs._value.asInt;
samux0:0cf0e27feaad 210 break;
samux0:0cf0e27feaad 211 case TypeDouble:
samux0:0cf0e27feaad 212 _value.asDouble = rhs._value.asDouble;
samux0:0cf0e27feaad 213 break;
samux0:0cf0e27feaad 214 case TypeString:
samux0:0cf0e27feaad 215 _value.asString = new std::string(*rhs._value.asString);
samux0:0cf0e27feaad 216 break;
samux0:0cf0e27feaad 217 case TypeArray:
samux0:0cf0e27feaad 218 for (int i = 0; i < rhs.index_array; i++)
samux0:0cf0e27feaad 219 (*this)[i] = rhs[i];
samux0:0cf0e27feaad 220 case TypeObject:
samux0:0cf0e27feaad 221 for (int i = 0; i < rhs.index_token; i++)
samux0:0cf0e27feaad 222 (*this)[*(rhs.token_name[i])] = rhs[*(rhs.token_name[i])];
samux0:0cf0e27feaad 223 default:
samux0:0cf0e27feaad 224 break;
samux0:0cf0e27feaad 225 }
samux0:0cf0e27feaad 226 }
samux0:0cf0e27feaad 227 return *this;
samux0:0cf0e27feaad 228}
samux0:0cf0e27feaad 229
samux0:0cf0e27feaad 230
samux0:0cf0e27feaad 231// Works for strings, arrays, and structs.
samux0:0cf0e27feaad 232int MbedJSONValue::size() const {
samux0:0cf0e27feaad 233 switch (_type) {
samux0:0cf0e27feaad 234 case TypeString:
samux0:0cf0e27feaad 235 return int(_value.asString->size());
samux0:0cf0e27feaad 236 case TypeArray:
samux0:0cf0e27feaad 237 return index_array;
samux0:0cf0e27feaad 238 case TypeObject:
samux0:0cf0e27feaad 239 return index_token;
samux0:0cf0e27feaad 240 default:
samux0:0cf0e27feaad 241 break;
samux0:0cf0e27feaad 242 }
samux0:0cf0e27feaad 243 return -1;
samux0:0cf0e27feaad 244}
samux0:0cf0e27feaad 245