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

Fork of MbedJSONValue by Samuel Mokrani

Committer:
AlexVC97
Date:
Wed Mar 15 07:54:44 2017 +0000
Revision:
5:8730f0b6605e
Parent:
3:f2ffae08b963
JSON in mbed

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