1 /* 2 * 3 * Copyright (C) 2012-2018 by C.H. Huang 4 * plushuang.tw@gmail.com 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 * 20 * --- 21 * 22 * In addition, as a special exception, the copyright holders give 23 * permission to link the code of portions of this program with the 24 * OpenSSL library under certain conditions as described in each 25 * individual source file, and distribute linked combinations 26 * including the two. 27 * You must obey the GNU Lesser General Public License in all respects 28 * for all of the code used other than OpenSSL. If you modify 29 * file(s) with this exception, you may extend this exception to your 30 * version of the file(s), but you are not obligated to do so. If you 31 * do not wish to do so, delete this exception statement from your 32 * version. If you delete this exception statement from all source 33 * files in the program, then also delete it here. 34 * 35 */ 36 37 #ifndef UG_JSON_H 38 #define UG_JSON_H 39 40 #include <stdint.h> // int64_t 41 #include <UgBuffer.h> 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 // ---------------------------------------------------------------------------- 48 // UgJsonType & UgJsonError 49 50 typedef enum { 51 UG_JSON_NULL, // null 52 UG_JSON_TRUE, // true 53 UG_JSON_FALSE, // false 54 UG_JSON_NUMBER, // 1234, 0.567 55 UG_JSON_STRING, // "string" 56 UG_JSON_OBJECT, // { 57 UG_JSON_ARRAY, // [ 58 59 UG_JSON_N_TYPE, // numbers of UgJsonType 60 } UgJsonType; 61 62 typedef enum { 63 UG_JSON_ERROR_NONE = 0, 64 65 // error code < 0, JSON format error 66 UG_JSON_ERROR_UNKNOWN = -1, 67 UG_JSON_ERROR_INVALID_NAME = -2, 68 UG_JSON_ERROR_EXCESS_NAME = -3, // get 2 names in 1 element 69 UG_JSON_ERROR_BEFORE_COLON = -4, // no name before colon in object 70 UG_JSON_ERROR_EXCESS_COLON = -5, // get 2 colons in 1 element 71 // UG_JSON_ERROR_NO_VALUE = -6, 72 UG_JSON_ERROR_INVALID_VALUE = -7, // not true, false, null, string, and number. 73 UG_JSON_ERROR_EXCESS_VALUE = -8, // get 2 values in 1 element 74 UG_JSON_ERROR_INVALID_CONTROL = -9, // unknown control character after '\' 75 UG_JSON_ERROR_INVALID_UNICODE = -10, 76 UG_JSON_ERROR_INVALID_NUMBER = -11, 77 78 UG_JSON_ERROR_IN_OBJECT = -12, 79 UG_JSON_ERROR_IN_ARRAY = -13, 80 UG_JSON_ERROR_IN_SEPARATOR = -14, // ',' 81 82 UG_JSON_ERROR_UNCOMPLETED = -15, 83 84 // -------------------------------- 85 // JSON-RPC error code 86 UG_JSON_ERROR_RPC_INVALID = -32, 87 88 // -------------------------------- 89 // error code > 0, user (application) error 90 // used by user parser (e.g. UgArray, UgList, UgEntry) 91 UG_JSON_ERROR_TYPE_NOT_MATCH = 1, 92 UG_JSON_ERROR_NO_DESTINATION = 2, 93 UG_JSON_ERROR_OUT_OF_MEMORY = 3, 94 UG_JSON_ERROR_CUSTOM = 4, 95 } UgJsonError; 96 97 // ---------------------------------------------------------------------------- 98 // UgJson: a simple JSON parser & writer 99 100 typedef struct UgJson UgJson; 101 102 // UgJsonParseFunc : a callback function to parse data 103 typedef UgJsonError (*UgJsonParseFunc) (UgJson* json, 104 const char* name, const char* value, 105 void* dest, void* data); 106 typedef void (*UgJsonWriteFunc) (UgJson* json, void* src, void* data); 107 108 // ---------------------------------------------------------------------------- 109 // JSON initialize & finalize functions 110 111 void ug_json_init (UgJson* json); 112 void ug_json_final (UgJson* json); 113 114 // ---------------------------------------------------------------------------- 115 // JSON Parser functions 116 117 void ug_json_begin_parse (UgJson* json); 118 UgJsonError ug_json_end_parse (UgJson* json); 119 120 UgJsonError ug_json_parse (UgJson* json, const char* string, int len); 121 122 // Don't call ug_json_pop() directly. 123 void ug_json_set (UgJson* json, UgJsonParseFunc func, void* dest, void* data); 124 void ug_json_push (UgJson* json, UgJsonParseFunc func, void* dest, void* data); 125 void ug_json_pop (UgJson* json); 126 127 // UgJsonParseFunc for JSON that starting with array. 128 // This parser will be popped if JSON start with array, otherwise it pop parser twice. 129 // User must push it after UserParseFunc. Below is sample code. 130 // ug_json_push (json, UserParseFunc, UserData1, UserData2); 131 // ug_json_push (json, ug_json_parse_array, NULL, NULL); 132 UgJsonError ug_json_parse_array (UgJson* json, 133 const char* name, const char* value, 134 void* dest, void* data); 135 // UgJsonParseFunc for JSON that starting with object. 136 // This parser will be popped if JSON start with object, otherwise it pop parser twice. 137 // User must push it after UserParseFunc. Below is sample code. 138 // ug_json_push (json, UserParseFunc, UserData1, UserData2); 139 // ug_json_push (json, ug_json_parse_object, NULL, NULL); 140 UgJsonError ug_json_parse_object (UgJson* json, 141 const char* name, const char* value, 142 void* dest, void* data); 143 // UgJsonParseFunc for unknown object or array. 144 // User must push this function in UserParseFunc if you get unknown object or array. 145 // ug_json_push (json, ug_json_parse_unknown, NULL, NULL); 146 UgJsonError ug_json_parse_unknown (UgJson* json, 147 const char* name, const char* value, 148 void* dest, void* data); 149 150 // ---------------------------------------------------------------------------- 151 // JSON Writer functions 152 153 // UgJson.state = UgJsonFormat 154 // UgJson.index[0] = level 155 // UgJson.stack.at[0] = UgBuffer 156 157 typedef enum 158 { 159 UG_JSON_FORMAT_INDENT = 1, 160 UG_JSON_FORMAT_UTF8 = 2, 161 UG_JSON_FORMAT_ALL = UG_JSON_FORMAT_INDENT | UG_JSON_FORMAT_UTF8 162 } UgJsonFormat; 163 164 // UgJson Writer functions 165 void ug_json_begin_write (UgJson* json, UgJsonFormat format, UgBuffer* buffer); 166 void ug_json_end_write (UgJson* json); 167 168 void ug_json_write_head (UgJson* json, char ch); 169 void ug_json_write_tail (UgJson* json, char ch); 170 171 // void ug_json_write_object_head (UgJson* json) 172 // void ug_json_write_object_tail (UgJson* json) 173 // void ug_json_write_array_head (UgJson* json) 174 // void ug_json_write_array_tail (UgJson* json) 175 #define ug_json_write_object_head(json) ug_json_write_head (json, '{') 176 #define ug_json_write_object_tail(json) ug_json_write_tail (json, '}') 177 #define ug_json_write_array_head(json) ug_json_write_head (json, '[') 178 #define ug_json_write_array_tail(json) ug_json_write_tail (json, ']') 179 180 void ug_json_write_null (UgJson* json); 181 void ug_json_write_bool (UgJson* json, int value); 182 183 void ug_json_write_number (UgJson* json, const char* format, ...); 184 void ug_json_write_string (UgJson* json, const char* Cstring); 185 186 // void ug_json_write_int (UgJson* json, int value); 187 // void ug_json_write_uint (UgJson* json, unsigned int value); 188 // void ug_json_write_int64 (UgJson* json, int64_t value); 189 // void ug_json_write_uint64 (UgJson* json, uint64_t value); 190 // void ug_json_write_double (UgJson* json, double value); 191 #define ug_json_write_int(json, value) ug_json_write_number (json, "%d", value) 192 #define ug_json_write_uint(json, value) ug_json_write_number (json, "%u", value) 193 #define ug_json_write_double(json, value) ug_json_write_number (json, "%f", value) 194 #if defined (_MSC_VER) || defined (__MINGW32__) 195 #define ug_json_write_int64(json, value) ug_json_write_number (json, "%I64d", value) 196 #define ug_json_write_uint64(json, value) ug_json_write_number (json, "%I64u", value) 197 #else 198 #define ug_json_write_int64(json, value) ug_json_write_number (json, "%lld", (long long) (value)) 199 #define ug_json_write_uint64(json, value) ug_json_write_number (json, "%llu", (unsigned long long) (value)) 200 #endif 201 202 #ifdef __cplusplus 203 } 204 #endif 205 206 struct UgJson 207 { 208 // buffer is used by parser & writer 209 struct { 210 char* at; 211 int length; 212 int allocated; 213 } buf; 214 215 // stack can store state, function, and data. 216 struct { 217 void** at; 218 int length; 219 int allocated; 220 } stack; 221 222 // User's parser can read type and scope only. 223 // used by parser & writer 224 uint8_t scope; // UG_JSON_OBJECT or UG_JSON_ARRAY 225 uint8_t state; // Parser state, Writer UgJsonFormat 226 int8_t error; 227 // temporary state 228 uint8_t type; // UgJsonType 229 uint8_t count; // count value (true, false, null, unicode) length 230 uint8_t colon:1; // boolean, has ':' in object. 231 uint8_t numberPoint:1; // boolean, has '.' in number. 232 uint8_t numberEe:1; // boolean, has 'E' or 'e' in number. 233 uint8_t numberPm:1; // boolean, has '+' or '-' in number. 234 235 // parser index[0] = index of name 236 // index[1] = index of value 237 // writer index[0] = level 238 int index[2]; 239 240 #ifdef __cplusplus 241 // C++11 standard-layout UgJsonUgJson242 inline UgJson (void) 243 { ug_json_init (this); } ~UgJsonUgJson244 inline ~UgJson (void) 245 { ug_json_final (this); } 246 initUgJson247 inline void init (void) 248 { ug_json_init (this); } finalUgJson249 inline void final (void) 250 { ug_json_final (this); } 251 252 // parser beginParseUgJson253 inline void beginParse(void) 254 { ug_json_begin_parse (this); } endParseUgJson255 inline void endParse (void) 256 { ug_json_end_parse (this); } parseUgJson257 inline void parse (const char* string, int length) 258 { ug_json_parse (this, string, length); } pushUgJson259 inline void push (UgJsonParseFunc func, void* dest, void* data) 260 { ug_json_push (this, func, dest, data); } popUgJson261 inline void pop (void) 262 { ug_json_pop (this); } 263 264 // writer beginWriteUgJson265 inline void beginWrite (UgJsonFormat format, UgBuffer* buffer) 266 { ug_json_begin_write (this, format, buffer); } endWriteUgJson267 inline void endWrite (void) 268 { ug_json_end_write (this); } 269 270 // inline void writeHead (char ch) 271 // { ug_json_write_head (this, ch); } 272 // inline void writeTail (char ch) 273 // { ug_json_write_tail (this, ch); } writeObjectHeadUgJson274 inline void writeObjectHead (void) 275 { ug_json_write_object_head (this); } writeObjectTailUgJson276 inline void writeObjectTail (void) 277 { ug_json_write_object_tail (this); } writeArrayHeadUgJson278 inline void writeArrayHead (void) 279 { ug_json_write_array_head (this); } writeArrayTailUgJson280 inline void writeArrayTail (void) 281 { ug_json_write_array_tail (this); } 282 writeNullUgJson283 inline void writeNull (void) 284 { ug_json_write_null (this); } writeBoolUgJson285 inline void writeBool (int value) 286 { ug_json_write_bool (this, value); } 287 // void writeNumber (const char* format, ...) writeStringUgJson288 inline void writeString (const char* Cstring) 289 { ug_json_write_string (this, Cstring); } 290 writeIntUgJson291 inline void writeInt (int value) 292 { ug_json_write_int (this, value); } writeUintUgJson293 inline void writeUint (unsigned int value) 294 { ug_json_write_uint (this, value); } writeInt64UgJson295 inline void writeInt64 (int64_t value) 296 { ug_json_write_int64 (this, value); } writeDoubleUgJson297 inline void writeDouble (double value) 298 { ug_json_write_double (this, value); } 299 #endif // __cplusplus 300 }; 301 302 303 // ---------------------------------------------------------------------------- 304 // C++11 standard-layout 305 306 #ifdef __cplusplus 307 308 namespace Ug 309 { 310 // This one is for directly use only. You can NOT derived it. 311 typedef struct UgJson Json; 312 }; // namespace Ug 313 314 #endif // __cplusplus 315 316 317 #endif // UG_JSON_H 318 319