Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
JsonParser.h
00001 /* 00002 * 00003 * Compact JSON format parsing lib (native cross-platform c++) 00004 * 00005 * Copyright (C) 2013 Victor Laskin (victor.laskin@gmail.com) 00006 * Details: http://vitiy.info/?p=102 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 3. The names of the authors may not be used to endorse or promote 00018 * products derived from this software without specific prior 00019 * written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS 00022 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00023 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00024 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 00025 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00026 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00027 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00029 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00030 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00031 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 * 00033 */ 00034 00035 00036 #include <string> 00037 #include <vector> 00038 #include <stdlib.h> 00039 00040 #ifndef MVJSON_H_ 00041 #define MVJSON_H_ 00042 00043 using namespace std; 00044 00045 namespace JSON { 00046 00047 /// JSON node types 00048 enum MVJSON_TYPE 00049 { 00050 MVJSON_TYPE_NULL, 00051 MVJSON_TYPE_OBJECT, 00052 MVJSON_TYPE_ARRAY, 00053 MVJSON_TYPE_STRING, 00054 MVJSON_TYPE_INT, 00055 MVJSON_TYPE_DOUBLE, 00056 MVJSON_TYPE_BOOL 00057 }; 00058 00059 class MVJSONUtils { 00060 protected: 00061 00062 // string parsing functions 00063 inline static int stringToInt(const string & s); ///< convert string to int 00064 inline static double stringToDouble(const string & s); ///< convert string to float 00065 inline static bool symbolToBeTrimmed(const char& c); ///< check if symbol is space, tab or new line break 00066 inline static string trim(const string & text); ///< trim spaces, tabs and line break 00067 inline static void replace(string & target, const string & oldStr, const string & newStr); ///< replace all occurrences of substring 00068 inline static void splitInHalf(const string & s, const string & separator, string & begin, string & end); ///< second half (output) 00069 inline static void splitList(const string & s, vector<string> & parts); 00070 }; 00071 00072 00073 class MVJSONNode; 00074 00075 /// JSON Value 00076 class MVJSONValue : public MVJSONUtils { 00077 public: 00078 MVJSONValue(string name, MVJSON_TYPE valueType); 00079 MVJSONValue(string name, bool value); 00080 MVJSONValue(string name, string value); 00081 MVJSONValue(string name, int value); 00082 MVJSONValue(string name, double value); 00083 MVJSONValue(string name, MVJSONNode* value); 00084 virtual ~MVJSONValue(); 00085 00086 string name; ///< value name [optional] 00087 MVJSON_TYPE valueType; ///< type of node 00088 00089 string stringValue; ///< value if data has string type 00090 bool boolValue; ///< value if data has bool type 00091 int intValue; ///< value if data has int type 00092 double doubleValue; ///< value if data has double type 00093 MVJSONNode* objValue; ///< value if data has object type 00094 00095 vector<MVJSONValue*> arrayValue; ///< array of values 00096 00097 double getFieldDouble(string name); ///< get value of double field of VALUE OBJECT (objValue) 00098 int getFieldInt(string name); ///< get value of int field of VALUE OBJECT (objValue) 00099 string getFieldString(string name); ///< get value of string field of VALUE OBJECT (objValue) 00100 bool getFieldBool(string name); ///< get value of bool field of VALUE OBJECT (objValue) 00101 00102 inline MVJSONValue* at(unsigned int i){ return arrayValue.at(i); } 00103 inline int size() { if (valueType == MVJSON_TYPE_ARRAY) return arrayValue.size(); else return 1; } 00104 private: 00105 void init(MVJSON_TYPE valueType); 00106 }; 00107 00108 /// JSON Node (Object) 00109 class MVJSONNode { 00110 public: 00111 00112 virtual ~MVJSONNode(); 00113 00114 vector<MVJSONValue*> values; ///< values (props) 00115 00116 bool hasField(string name); ///< check that object has field 00117 MVJSONValue* getField(string name); ///< get field by name 00118 00119 double getFieldDouble(string name); ///< get value of double field 00120 int getFieldInt(string name); ///< get value of int field 00121 string getFieldString(string name); ///< get value of string field 00122 bool getFieldBool(string name); ///< get value of bool field 00123 }; 00124 00125 /// Compact JSON parser (based on specification: http://www.json.org/) 00126 class MVJSONReader : public MVJSONUtils { 00127 public: 00128 MVJSONReader(const string & source); ///< constructor from json source 00129 virtual ~MVJSONReader(); 00130 00131 MVJSONNode* root; ///< root object (if its null - parsing was failed) 00132 00133 private: 00134 MVJSONValue* parseValue(string text, bool hasNoName); ///< parse value 00135 MVJSONNode* parse(string text); ///< parse node 00136 00137 00138 }; 00139 00140 00141 00142 // ------------------- inlined string processing functions -------------> 00143 00144 00145 inline int MVJSONUtils::stringToInt(const string & s) 00146 { 00147 return atoi(s.c_str()); 00148 } 00149 00150 00151 inline double MVJSONUtils::stringToDouble(const string & s) 00152 { 00153 return atof(s.c_str()); 00154 } 00155 00156 00157 inline bool MVJSONUtils::symbolToBeTrimmed(const char& c ///< the char to test 00158 ) 00159 { 00160 if (c == ' ') return true; 00161 if (c == '\n') return true; 00162 if (c == '\r') return true; 00163 if (c == '\t') return true; 00164 return false; 00165 } 00166 00167 00168 inline string MVJSONUtils::trim(const string & text ///< the text to trim 00169 ) 00170 { 00171 if (text.length() == 0) return ""; 00172 int start = 0; 00173 while ((start < text.length()) && (symbolToBeTrimmed(text[start]))) start++; 00174 int end = text.length() - 1; 00175 while ((end > 0) && (symbolToBeTrimmed(text[end]))) end--; 00176 if (start > end) return ""; 00177 00178 return text.substr(start, end - start + 1); 00179 } 00180 00181 inline void MVJSONUtils::splitInHalf(const string & s, ///< source string to split up 00182 const string & separator, ///< separator string) 00183 string & begin, ///< first part (output) 00184 string & end ///< second half (output) 00185 ) 00186 { 00187 int pos = s.find(separator); 00188 if (pos == string::npos) { begin = s; end = ""; return; } 00189 00190 begin = s.substr(0, pos); 00191 end = s.substr(pos + separator.length(), s.length() - pos - separator.length()); 00192 } 00193 00194 /// split string by "," - ignore content inside of "{", "}", "[", "]" and quotations "...." 00195 /// also take \" into account 00196 /// (Code should be cleared of comments beforehand) 00197 inline void MVJSONUtils::splitList(const string & s, ///< string to be splitted 00198 vector<string> & parts ///< result parts 00199 ) 00200 { 00201 00202 bool isNotInQuotes = true; 00203 int b1 = 0; 00204 int b2 = 0; 00205 int lastPos = 0; 00206 00207 const char* start = s.c_str(); 00208 const char* ps = start; 00209 00210 while (*ps) // *ps != 0 00211 { 00212 if ((*ps == ',') && (isNotInQuotes) && (b1 == 0) && (b2 == 0)) 00213 { 00214 parts.push_back(s.substr(lastPos, ps - start - lastPos)); 00215 lastPos = ps - start + 1; 00216 } 00217 00218 if (isNotInQuotes) 00219 { 00220 if (*ps == '{') b1++; 00221 if (*ps == '}') b1--; 00222 if (*ps == '[') b2++; 00223 if (*ps == ']') b2--; 00224 } 00225 00226 if (*ps == '"') 00227 { 00228 isNotInQuotes = !isNotInQuotes; 00229 if (ps != start) 00230 if (*(ps-1) == '\\') 00231 isNotInQuotes = !isNotInQuotes; 00232 } 00233 00234 ps++; 00235 } 00236 00237 parts.push_back(s.substr(lastPos, s.length() - lastPos)); 00238 } 00239 00240 inline void MVJSONUtils::replace(string & target, ///< text to be modified 00241 const string & oldStr, ///< old string 00242 const string & newStr ///< new string 00243 ) 00244 { 00245 unsigned int pos = 0; 00246 unsigned int oldLen = oldStr.length(); 00247 unsigned int newLen = newStr.length(); 00248 00249 for (;;) 00250 { 00251 pos = target.find(oldStr, pos); 00252 if (pos == string::npos) break; 00253 target.replace(pos, oldLen, newStr); 00254 pos += newLen; 00255 } 00256 } 00257 00258 00259 } /* namespace F2 */ 00260 #endif /* MVJSON_H_ */ 00261
Generated on Tue Jul 12 2022 18:55:01 by
1.7.2