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

Dependents:   RPC_mbed_client WebSocket_test pseudo_comet RPC_Wifly_HelloWorld ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MbedJSONValue.cpp Source File

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