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:54:29 2011 +0000
Revision:
2:e39bfa3e917d
Parent:
0:0cf0e27feaad
Child:
3:f2ffae08b963

        

Who changed what in which revision?

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