Minimalist JSON parser and serializer (inspired by picojson). Used by MbedJSONRpc.
Dependents: RPC_mbed_client WebSocket_test pseudo_comet RPC_Wifly_HelloWorld ... more
MbedJSONValue.cpp
00001 #include "MbedJSONValue.h" 00002 00003 # include <stdlib.h> 00004 # include <stdio.h> 00005 00006 // Clean up 00007 void MbedJSONValue::clean() { 00008 switch (_type) { 00009 case TypeString : 00010 delete _value.asString; 00011 break; 00012 case TypeArray : 00013 for (int i = 0; i < index_array; i++) 00014 delete array[i]; 00015 index_array = 0; 00016 break; 00017 case TypeObject : 00018 for (int i = 0; i < index_token; i++) { 00019 delete token[i]; 00020 delete token_name[i]; 00021 } 00022 index_token = 0; 00023 break; 00024 default: 00025 break; 00026 } 00027 _type = TypeNull ; 00028 _type = TypeNull ; 00029 } 00030 00031 bool MbedJSONValue::hasMember(char * name) 00032 { 00033 for(int i = 0; i < index_token; i++) 00034 if( !strcmp(name, (*(token_name[i])).c_str() )) 00035 return true; 00036 return false; 00037 } 00038 00039 00040 void copy(const std::string& s, std::back_insert_iterator<std::string> oi) { 00041 std::copy(s.begin(), s.end(), oi); 00042 } 00043 00044 void serialize_str(const std::string& s, std::back_insert_iterator<std::string> oi) { 00045 *oi++ = '"'; 00046 for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) { 00047 switch (*i) { 00048 #define MAP(val, sym) case val: copy(sym, oi); break 00049 MAP('"', "\\\""); 00050 MAP('\\', "\\\\"); 00051 MAP('/', "\\/"); 00052 MAP('\b', "\\b"); 00053 MAP('\f', "\\f"); 00054 MAP('\n', "\\n"); 00055 MAP('\r', "\\r"); 00056 MAP('\t', "\\t"); 00057 #undef MAP 00058 default: 00059 if ((unsigned char)*i < 0x20 || *i == 0x7f) { 00060 char buf[7]; 00061 sprintf(buf, "\\u%04x", *i & 0xff); 00062 copy(buf, buf + 6, oi); 00063 } else { 00064 *oi++ = *i; 00065 } 00066 break; 00067 } 00068 } 00069 *oi++ = '"'; 00070 } 00071 00072 std::string MbedJSONValue::serialize(){ 00073 std::string s; 00074 serialize(std::back_inserter(s)); 00075 return s; 00076 } 00077 00078 std::string MbedJSONValue::to_str(){ 00079 switch (_type) { 00080 case TypeNull : 00081 return "null"; 00082 case TypeBoolean : 00083 return _value.asBool ? "true" : "false"; 00084 case TypeInt : { 00085 char buf[10]; 00086 sprintf(buf, "%d", _value.asInt); 00087 return buf; 00088 } 00089 case TypeDouble : { 00090 char buf[10]; 00091 sprintf(buf, "%f", _value.asDouble); 00092 return buf; 00093 } 00094 default: 00095 break; 00096 } 00097 return NULL; 00098 } 00099 00100 00101 00102 void MbedJSONValue::serialize(std::back_insert_iterator<std::string> oi) { 00103 switch (_type) { 00104 case TypeString : 00105 serialize_str(*_value.asString, oi); 00106 break; 00107 case TypeArray : { 00108 *oi++ = '['; 00109 for (int i = 0; i < index_array; i++) { 00110 if (i) 00111 *oi++ = ','; 00112 (*this)[i].serialize(oi); 00113 } 00114 *oi++ = ']'; 00115 break; 00116 } 00117 case TypeObject : { 00118 *oi++ = '{'; 00119 for (int i = 0; i < index_token; i++) { 00120 if (i) 00121 *oi++ = ','; 00122 serialize_str(*(token_name[i]), oi); 00123 *oi++ = ':'; 00124 (*(token[i])).serialize(oi); 00125 } 00126 *oi++ = '}'; 00127 break; 00128 } 00129 default: 00130 copy(to_str(), oi); 00131 break; 00132 } 00133 } 00134 00135 00136 00137 MbedJSONValue& MbedJSONValue::operator[](int i) { 00138 _type = TypeArray ; 00139 if (i < NB_TOKEN && index_array == i ) { 00140 #ifdef DEBUG 00141 printf("will add an element to the array\r\n"); 00142 #endif 00143 array[i] = new MbedJSONValue(); 00144 index_array++; 00145 return *(array[i]); 00146 } 00147 if (i < NB_TOKEN && index_array > i) 00148 return *(array[i]); 00149 00150 //if the user is not doing something wrong, this code is never executed!! 00151 return *(new MbedJSONValue()); 00152 } 00153 00154 MbedJSONValue& MbedJSONValue::operator[](std::string k) { 00155 _type = TypeObject ; 00156 for (int i = 0; i < index_token; i++) { 00157 #ifdef DEBUG 00158 printf("k: %s\r\n", k.c_str()); 00159 printf("str: %s\r\n", token_name[i]->c_str()); 00160 #endif 00161 //existing token 00162 if (!strcmp(k.c_str(), token_name[i]->c_str())) { 00163 #ifdef DEBUG 00164 printf("token found: %d\r\n", i); 00165 #endif 00166 return *(token[i]); 00167 } 00168 } 00169 00170 if(index_token >= NB_TOKEN) 00171 index_token = NB_TOKEN - 1; 00172 //non existing token 00173 token_name[index_token] = new std::string(k); 00174 token[index_token] = new MbedJSONValue(); 00175 index_token++; 00176 return *(token[index_token - 1]); 00177 } 00178 00179 MbedJSONValue& MbedJSONValue::operator[](std::string k) const 00180 { 00181 for (int i = 0; i < index_token; i++) { 00182 #ifdef DEBUG 00183 printf("k: %s\r\n", k.c_str()); 00184 printf("str: %s\r\n", token_name[i]->c_str()); 00185 #endif 00186 if (!strcmp(k.c_str(), token_name[i]->c_str())) { 00187 #ifdef DEBUG 00188 printf("token found: %d\r\n", i); 00189 #endif 00190 return *(token[i]); 00191 } 00192 } 00193 00194 //if the user is not doing something wrong, this code is never executed!! 00195 return *(new MbedJSONValue()); 00196 } 00197 00198 00199 // Operators 00200 MbedJSONValue& MbedJSONValue::operator=(MbedJSONValue const& rhs) { 00201 if (this != &rhs) { 00202 clean(); 00203 _type = rhs._type; 00204 switch (_type) { 00205 case TypeBoolean : 00206 _value.asBool = rhs._value.asBool; 00207 break; 00208 case TypeInt : 00209 _value.asInt = rhs._value.asInt; 00210 break; 00211 case TypeDouble : 00212 _value.asDouble = rhs._value.asDouble; 00213 break; 00214 case TypeString : 00215 _value.asString = new std::string(*rhs._value.asString); 00216 break; 00217 case TypeArray : 00218 for (int i = 0; i < rhs.index_array; i++) 00219 (*this)[i] = rhs[i]; 00220 case TypeObject : 00221 for (int i = 0; i < rhs.index_token; i++) 00222 (*this)[*(rhs.token_name[i])] = rhs[*(rhs.token_name[i])]; 00223 default: 00224 break; 00225 } 00226 } 00227 return *this; 00228 } 00229 00230 00231 // Works for strings, arrays, and structs. 00232 int MbedJSONValue::size() const { 00233 switch (_type) { 00234 case TypeString : 00235 return int(_value.asString->size()); 00236 case TypeArray : 00237 return index_array; 00238 case TypeObject : 00239 return index_token; 00240 default: 00241 break; 00242 } 00243 return -1; 00244 } 00245
Generated on Tue Jul 12 2022 18:09:13 by 1.7.2