00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define _GNU_SOURCE
00020
00021 #include <microfeed-provider/microfeedjson.h>
00022 #include <microfeed-common/microfeedstore.h>
00023 #include <microfeed-common/microfeedmisc.h>
00024 #include <unistd.h>
00025 #include <string.h>
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028
00029 struct _MicrofeedJson {
00030 MicrofeedJson* parent;
00031 MicrofeedStore* members;
00032 };
00033
00034 typedef struct {
00035 char* name;
00036 MicrofeedJsonType type;
00037 union {
00038 MicrofeedJson* object;
00039 MicrofeedJson* array;
00040 char* string;
00041 long long int integer;
00042 double decimal;
00043 int boolean;
00044 };
00045 char* as_string;
00046 } Member;
00047
00048 typedef struct {
00049 MicrofeedJson* json;
00050 MicrofeedJsonCompareMembersFunction compare_members;
00051 void* user_data;
00052 } SortData;
00053
00054 static Member* member_new(char* name, MicrofeedJsonType type);
00055 static void member_free(Member* member);
00056 static const char* member_get_name(Member* member);
00057 static const char* member_as_string(Member* member);
00058 static char* member_to_string(Member* member);
00059 static Member* parse_value(char* name, const char** data, const char* end);
00060 static MicrofeedJson* parse_object(const char** data, const char* end);
00061 static MicrofeedJson* parse_array(const char** data, const char* end);
00062 static char* parse_string(const char** data, const char* end);
00063 static Member* parse_number(char* name, const char** data, const char* end);
00064 static void eat_whitespaces(const char** data, const char* end);
00065 static int are_next_characters(const char* next, size_t next_length, const char** data, const char* end);
00066 static int hex_to_int(char hex, unsigned int* int_return);
00067 int compare_json_members_in_sort(const void* data1, const void* data2, unsigned int index1, unsigned int index2, void* user_data);
00068
00069 MicrofeedJson* microfeed_json_new_object(void) {
00070 MicrofeedJson* json;
00071
00072 json = microfeed_memory_allocate(MicrofeedJson);
00073 json->members = microfeed_store_new_sorted((MicrofeedStoreCompareKeysFunction)strcmp, (MicrofeedStoreGetKeyFunction)member_get_name);
00074
00075 return json;
00076 }
00077
00078 MicrofeedJson* microfeed_json_new_array(void) {
00079 MicrofeedJson* json;
00080
00081 json = microfeed_memory_allocate(MicrofeedJson);
00082 json->members = microfeed_store_new_unsorted((MicrofeedStoreCompareKeysFunction)strcmp, (MicrofeedStoreGetKeyFunction)member_get_name);
00083
00084 return json;
00085 }
00086
00087 MicrofeedJson* microfeed_json_new_from_data(const char* data, size_t length) {
00088 MicrofeedJson* json = NULL;
00089 Member* member;
00090
00091 if ((member = parse_value(NULL, &data, data + length))) {
00092 if (member->type == MICROFEED_JSON_TYPE_OBJECT) {
00093 json = member->object;
00094 member->object = NULL;
00095 } else if (member->type == MICROFEED_JSON_TYPE_ARRAY) {
00096 json = member->array;
00097 member->array = NULL;
00098 }
00099 member_free(member);
00100 } else {
00101 printf("JSON parsing failed: %s\n", data);
00102 }
00103
00104 return json;
00105 }
00106
00107 void microfeed_json_free(MicrofeedJson* json) {
00108 if (json) {
00109 if (json->parent) {
00110
00111 }
00112 microfeed_store_foreach(json->members, (MicrofeedStoreForeachFunction)member_free, NULL);
00113 microfeed_store_free(json->members);
00114 microfeed_memory_free(json);
00115 }
00116 }
00117
00118 int microfeed_json_is_array(MicrofeedJson* json) {
00119
00120 return !microfeed_store_is_sorted(json->members);
00121 }
00122
00123 MicrofeedJson* microfeed_json_get_parent(MicrofeedJson* json) {
00124
00125 return json->parent;
00126 }
00127
00128 unsigned int microfeed_json_get_size(MicrofeedJson* json) {
00129
00130 return microfeed_store_get_size(json->members);
00131 }
00132
00133 MicrofeedJsonType microfeed_json_get_type(MicrofeedJson* json, const char* name) {
00134 MicrofeedJsonType type = MICROFEED_JSON_TYPE_NULL;
00135 Member* member;
00136
00137 if (name) {
00138 if ((member = microfeed_store_get(json->members, name, Member))) {
00139 type = member->type;
00140 }
00141 } else {
00142 type = (microfeed_store_is_sorted(json->members) ? MICROFEED_JSON_TYPE_OBJECT : MICROFEED_JSON_TYPE_ARRAY);
00143 }
00144
00145 return type;
00146 }
00147
00148 MicrofeedJsonType microfeed_json_get_type_by_index(MicrofeedJson* json, unsigned int index) {
00149 MicrofeedJsonType type = MICROFEED_JSON_TYPE_NULL;
00150 Member* member;
00151
00152 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00153 type = member->type;
00154 }
00155
00156 return type;
00157 }
00158
00159 MicrofeedJsonType microfeed_json_get_type_by_path(MicrofeedJson* json, const char* name, ...) {
00160 MicrofeedJsonType type = MICROFEED_JSON_TYPE_NULL;
00161 Member* member;
00162 va_list argp;
00163 const char* s;
00164
00165 if ((member = microfeed_store_get(json->members, name, Member))) {
00166 va_start(argp, name);
00167 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00168 (member = microfeed_store_get(member->object->members, s, Member))) {
00169 }
00170 va_end(argp);
00171 if (!s) {
00172 type = member->type;
00173 }
00174 }
00175
00176 return type;
00177 }
00178
00179 int microfeed_json_is_null(MicrofeedJson* json, const char* name) {
00180 int retvalue = 1;
00181 Member* member;
00182
00183 if (name) {
00184 if ((member = microfeed_store_get(json->members, name, Member))) {
00185 retvalue = (member->type == MICROFEED_JSON_TYPE_NULL);
00186 }
00187 } else {
00188 retvalue = 0;
00189 }
00190
00191 return retvalue;
00192 }
00193
00194 const char* microfeed_json_get_name_by_index(MicrofeedJson* json, unsigned int index) {
00195 const char* name = NULL;
00196 Member* member;
00197
00198 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00199 name = member->name;
00200 }
00201
00202 return name;
00203 }
00204
00205 int microfeed_json_is_null_by_index(MicrofeedJson* json, unsigned int index) {
00206 int retvalue = 1;
00207 Member* member;
00208
00209 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00210 retvalue = (member->type == MICROFEED_JSON_TYPE_NULL);
00211 }
00212
00213 return retvalue;
00214 }
00215
00216 int microfeed_json_is_null_by_path(MicrofeedJson* json,const char* name, ...) {
00217 int retvalue = 1;
00218 Member* member;
00219 va_list argp;
00220 const char* s;
00221
00222 if ((member = microfeed_store_get(json->members, name, Member))) {
00223 va_start(argp, name);
00224 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00225 (member = microfeed_store_get(member->object->members, s, Member))) {
00226 }
00227 va_end(argp);
00228 if (!s) {
00229 retvalue = (member->type == MICROFEED_JSON_TYPE_NULL);
00230 }
00231 }
00232
00233 return retvalue;
00234 }
00235
00236 MicrofeedJson* microfeed_json_get_object(MicrofeedJson* json, const char* name) {
00237 MicrofeedJson* object = NULL;
00238 Member* member;
00239
00240 if (name) {
00241 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_OBJECT) {
00242 object = member->object;
00243 }
00244 } else {
00245 if (microfeed_store_is_sorted(json->members)) {
00246 object = json;
00247 }
00248 }
00249
00250 return object;
00251 }
00252
00253 MicrofeedJson* microfeed_json_get_object_by_index(MicrofeedJson* json, unsigned int index) {
00254 MicrofeedJson* object = NULL;
00255 Member* member;
00256
00257 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_OBJECT) {
00258 object = member->object;
00259 }
00260
00261 return object;
00262 }
00263
00264 MicrofeedJson* microfeed_json_get_object_by_path(MicrofeedJson* json, const char* name, ...) {
00265 MicrofeedJson* object = NULL;
00266 Member* member;
00267 va_list argp;
00268 const char* s;
00269
00270 if ((member = microfeed_store_get(json->members, name, Member))) {
00271 va_start(argp, name);
00272 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00273 (member = microfeed_store_get(member->object->members, s, Member))) {
00274 }
00275 va_end(argp);
00276 if (!s && member->type == MICROFEED_JSON_TYPE_OBJECT) {
00277 object = member->object;
00278 }
00279 }
00280
00281 return object;
00282 }
00283
00284 MicrofeedJson* microfeed_json_get_array(MicrofeedJson* json, const char* name) {
00285 MicrofeedJson* array = NULL;
00286 Member* member;
00287
00288 if (name) {
00289 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_ARRAY) {
00290 array = member->array;
00291 }
00292 } else {
00293 if (!microfeed_store_is_sorted(json->members)) {
00294 array = json;
00295 }
00296 }
00297
00298 return array;
00299 }
00300
00301 MicrofeedJson* microfeed_json_get_array_by_index(MicrofeedJson* json, unsigned int index) {
00302 MicrofeedJson* array = NULL;
00303 Member* member;
00304
00305 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_ARRAY) {
00306 array = member->array;
00307 }
00308
00309 return array;
00310 }
00311
00312 MicrofeedJson* microfeed_json_get_array_by_path(MicrofeedJson* json, const char* name, ...) {
00313 MicrofeedJson* array = NULL;
00314 Member* member;
00315 va_list argp;
00316 const char* s;
00317
00318 if ((member = microfeed_store_get(json->members, name, Member))) {
00319 va_start(argp, name);
00320 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00321 (member = microfeed_store_get(member->object->members, s, Member))) {
00322 }
00323 va_end(argp);
00324 if (!s && member->type == MICROFEED_JSON_TYPE_ARRAY) {
00325 array = member->array;
00326 }
00327 }
00328
00329 return array;
00330 }
00331
00332 long long int microfeed_json_get_integer(MicrofeedJson* json, const char* name) {
00333 long long int integer = 0;
00334 Member* member;
00335
00336 if (name) {
00337 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_INTEGER) {
00338 integer = member->integer;
00339 }
00340 }
00341
00342 return integer;
00343 }
00344
00345 long long int microfeed_json_get_integer_by_index(MicrofeedJson* json, unsigned int index) {
00346 long long int integer = 0;;
00347 Member* member;
00348
00349 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_INTEGER) {
00350 integer = member->integer;
00351 }
00352
00353 return integer;
00354 }
00355
00356 long long int microfeed_json_get_integer_by_path(MicrofeedJson* json, const char* name, ...) {
00357 long long int integer = 0;
00358 Member* member;
00359 va_list argp;
00360 const char* s;
00361
00362 if ((member = microfeed_store_get(json->members, name, Member))) {
00363 va_start(argp, name);
00364 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00365 (member = microfeed_store_get(member->object->members, s, Member))) {
00366 }
00367 va_end(argp);
00368 if (!s && member->type == MICROFEED_JSON_TYPE_INTEGER) {
00369 integer = member->integer;
00370 }
00371 }
00372
00373 return integer;
00374 }
00375
00376 double microfeed_json_get_decimal(MicrofeedJson* json, const char* name) {
00377 double decimal = 0;
00378 Member* member;
00379
00380 if (name) {
00381 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_DECIMAL) {
00382 decimal = member->decimal;
00383 }
00384 }
00385
00386 return decimal;
00387 }
00388
00389 double microfeed_json_get_decimal_by_index(MicrofeedJson* json, unsigned int index) {
00390 double decimal = 0;;
00391 Member* member;
00392
00393 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_DECIMAL) {
00394 decimal = member->decimal;
00395 }
00396
00397 return decimal;
00398
00399 }
00400
00401 double microfeed_json_get_decimal_by_path(MicrofeedJson* json, const char* name, ...) {
00402 double decimal = 0;
00403 Member* member;
00404 va_list argp;
00405 const char* s;
00406
00407 if ((member = microfeed_store_get(json->members, name, Member))) {
00408 va_start(argp, name);
00409 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00410 (member = microfeed_store_get(member->object->members, s, Member))) {
00411 }
00412 va_end(argp);
00413 if (!s && member->type == MICROFEED_JSON_TYPE_DECIMAL) {
00414 decimal = member->decimal;
00415 }
00416 }
00417
00418 return decimal;
00419 }
00420
00421 const char* microfeed_json_get_string(MicrofeedJson* json, const char* name) {
00422 const char* string = NULL;
00423 Member* member;
00424
00425 if (name) {
00426 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_STRING) {
00427 string = member->string;
00428 }
00429 }
00430
00431 return string;
00432 }
00433
00434 const char* microfeed_json_get_string_by_index(MicrofeedJson* json, unsigned int index) {
00435 const char* string = NULL;
00436 Member* member;
00437
00438 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_STRING) {
00439 string = member->string;
00440 }
00441
00442 return string;
00443 }
00444
00445 const char* microfeed_json_get_string_by_path(MicrofeedJson* json, const char* name, ...) {
00446 const char* string = NULL;
00447 Member* member;
00448 va_list argp;
00449 const char* s;
00450
00451 if ((member = microfeed_store_get(json->members, name, Member))) {
00452 va_start(argp, name);
00453 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00454 (member = microfeed_store_get(member->object->members, s, Member))) {
00455 }
00456 va_end(argp);
00457 if (!s && member->type == MICROFEED_JSON_TYPE_STRING) {
00458 string = member->string;
00459 }
00460 }
00461
00462 return string;
00463 }
00464
00465 int microfeed_json_get_boolean(MicrofeedJson* json, const char* name) {
00466 int boolean = 0;
00467 Member* member;
00468
00469 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_BOOLEAN) {
00470 boolean = member->boolean;
00471 }
00472
00473 return boolean;
00474 }
00475
00476 int microfeed_json_get_boolean_by_index(MicrofeedJson* json, unsigned int index) {
00477 int boolean = 0;
00478 Member* member;
00479
00480 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_BOOLEAN) {
00481 boolean = member->boolean;
00482 }
00483
00484 return boolean;
00485 }
00486
00487 int microfeed_json_get_boolean_by_path(MicrofeedJson* json, const char* name, ...) {
00488 int boolean = 0;
00489 Member* member;
00490 va_list argp;
00491 const char* s;
00492
00493 if ((member = microfeed_store_get(json->members, name, Member))) {
00494 va_start(argp, name);
00495 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00496 (member = microfeed_store_get(member->object->members, s, Member))) {
00497 }
00498 va_end(argp);
00499 if (!s && member->type == MICROFEED_JSON_TYPE_BOOLEAN) {
00500 boolean = member->boolean;
00501 }
00502 }
00503
00504 return boolean;
00505 }
00506
00507 const char* microfeed_json_get_as_string(MicrofeedJson* json, const char* name) {
00508 const char* string = NULL;
00509 Member* member;
00510
00511 if (name) {
00512 if ((member = microfeed_store_get(json->members, name, Member))) {
00513 string = member_as_string(member);
00514 }
00515 }
00516
00517 return string;
00518 }
00519
00520 const char* microfeed_json_get_as_string_by_index(MicrofeedJson* json, unsigned int index) {
00521 const char* string = NULL;
00522 Member* member;
00523
00524 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00525 string = member_as_string(member);
00526 }
00527
00528 return string;
00529 }
00530
00531 const char* microfeed_json_get_as_string_by_path(MicrofeedJson* json, const char* name, ...) {
00532 const char* string = NULL;
00533 Member* member;
00534 va_list argp;
00535 const char* s;
00536
00537 if ((member = microfeed_store_get(json->members, name, Member))) {
00538 va_start(argp, name);
00539 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00540 (member = microfeed_store_get(member->object->members, s, Member))) {
00541 }
00542 va_end(argp);
00543 if (!s) {
00544 string = member_as_string(member);
00545 }
00546 }
00547
00548 return string;
00549 }
00550
00551 char* microfeed_json_to_string(MicrofeedJson* json, const char* name) {
00552 char* string = NULL;
00553 Member* member;
00554 size_t size;
00555 unsigned int i;
00556 MicrofeedStoreIterator* iterator;
00557 size_t length1;
00558 size_t length2;
00559 char* s;
00560
00561 if (name) {
00562 if ((member = microfeed_store_get(json->members, name, Member))) {
00563 string = member_to_string(member);
00564 } else {
00565 string = strdup("null");
00566 }
00567 } else {
00568 size = 2;
00569 string = (char*)malloc(size + 1);
00570 i = 1;
00571 string[i] = ' ';
00572 for (iterator = microfeed_store_iterate(json->members, NULL);
00573 (member = microfeed_store_iterator_get(iterator, Member));
00574 microfeed_store_iterator_next(iterator)) {
00575 if (member->name) {
00576 length1 = strlen(member->name);
00577 size += length1 + 3;
00578 } else {
00579 length1 = 0;
00580 }
00581 s = member_to_string(member);
00582 length2 = strlen(s);
00583 size += length2 + 1;
00584 string = (char*)realloc(string, size + 1);
00585 if (length1) {
00586 string[i++] = '"';
00587 memcpy(string + i, member->name, length1);
00588 i += length1;
00589 string[i++] = '"';
00590 string[i++] = ':';
00591 }
00592 memcpy(string + i, s, length2);
00593 i += length2;
00594 string[i++] = ',';
00595 free(s);
00596
00597 }
00598 microfeed_store_iterator_free(iterator);
00599 if (microfeed_store_is_sorted(json->members)) {
00600 string[0] = '{';
00601 string[size - 1] = '}';
00602 } else {
00603 string[0] = '[';
00604 string[size - 1] = ']';
00605 }
00606 string[size] = 0;
00607 }
00608
00609 return string;
00610 }
00611
00612 char* microfeed_json_to_string_by_index(MicrofeedJson* json, unsigned int index) {
00613 char* string = NULL;
00614 Member* member;
00615
00616 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00617 string = member_to_string(member);
00618 } else {
00619 string = strdup("null");
00620 }
00621
00622 return string;
00623 }
00624
00625 char* microfeed_json_to_string_by_path(MicrofeedJson* json, const char* name, ...);
00626
00627 void microfeed_json_set_null(MicrofeedJson* json, const char* name) {
00628 Member* member;
00629
00630 member = member_new(strdup(name), MICROFEED_JSON_TYPE_NULL);
00631 if ((member = microfeed_store_replace(json->members, member, Member))) {
00632 member_free(member);
00633 }
00634 }
00635
00636 void microfeed_json_append_null(MicrofeedJson* json, MicrofeedJson* object) {
00637 Member* member;
00638
00639 member = member_new(NULL, MICROFEED_JSON_TYPE_NULL);
00640 microfeed_store_insert(json->members, member);
00641 }
00642
00643 void microfeed_json_set_object(MicrofeedJson* json, const char* name, MicrofeedJson* object) {
00644 Member* member;
00645
00646 member = member_new(strdup(name), MICROFEED_JSON_TYPE_OBJECT);
00647 member->object = object;
00648 if ((member = microfeed_store_replace(json->members, member, Member))) {
00649 member_free(member);
00650 }
00651 }
00652
00653 void microfeed_json_append_object(MicrofeedJson* json, MicrofeedJson* object) {
00654 Member* member;
00655
00656 member = member_new(NULL, MICROFEED_JSON_TYPE_OBJECT);
00657 member->object = object;
00658 microfeed_store_insert(json->members, member);
00659 }
00660
00661 void microfeed_json_set_integer(MicrofeedJson* json, const char* name, long long int integer) {
00662 Member* member;
00663
00664 member = member_new(strdup(name), MICROFEED_JSON_TYPE_INTEGER);
00665 member->integer = integer;
00666 if ((member = microfeed_store_replace(json->members, member, Member))) {
00667 member_free(member);
00668 }
00669 }
00670
00671 void microfeed_json_append_integer(MicrofeedJson* json, long long int integer) {
00672 Member* member;
00673
00674 member = member_new(NULL, MICROFEED_JSON_TYPE_INTEGER);
00675 member->integer = integer;
00676 microfeed_store_insert(json->members, member);
00677 }
00678
00679 void microfeed_json_set_decimal(MicrofeedJson* json, const char* name, double decimal) {
00680 Member* member;
00681
00682 member = member_new(strdup(name), MICROFEED_JSON_TYPE_DECIMAL);
00683 member->decimal = decimal;
00684 if ((member = microfeed_store_replace(json->members, member, Member))) {
00685 member_free(member);
00686 }
00687 }
00688
00689 void microfeed_json_append_decimal(MicrofeedJson* json, double decimal) {
00690 Member* member;
00691
00692 member = member_new(NULL, MICROFEED_JSON_TYPE_DECIMAL);
00693 member->decimal = decimal;
00694 microfeed_store_insert(json->members, member);
00695 }
00696
00697 void microfeed_json_set_string(MicrofeedJson* json, const char* name, const char* string) {
00698 Member* member;
00699
00700 member = member_new(strdup(name), MICROFEED_JSON_TYPE_STRING);
00701 member->string = strdup(string);
00702 if ((member = microfeed_store_replace(json->members, member, Member))) {
00703 member_free(member);
00704 }
00705 }
00706
00707 void microfeed_json_append_string(MicrofeedJson* json, const char* string) {
00708 Member* member;
00709
00710 member = member_new(NULL, MICROFEED_JSON_TYPE_STRING);
00711 member->string = strdup(string);
00712 microfeed_store_insert(json->members, member);
00713 }
00714
00715 void microfeed_json_set_boolean(MicrofeedJson* json, const char* name, int boolean) {
00716 Member* member;
00717
00718 member = member_new(strdup(name), MICROFEED_JSON_TYPE_BOOLEAN);
00719 member->boolean = boolean;
00720 if ((member = microfeed_store_replace(json->members, member, Member))) {
00721 member_free(member);
00722 }
00723 }
00724
00725 void microfeed_json_append_boolean(MicrofeedJson* json, int boolean) {
00726 Member* member;
00727
00728 member = member_new(NULL, MICROFEED_JSON_TYPE_BOOLEAN);
00729 member->boolean = boolean;
00730 microfeed_store_insert(json->members, member);
00731 }
00732
00733
00734 void microfeed_json_sort_array(MicrofeedJson* json, MicrofeedJsonCompareMembersFunction compare_members, void* user_data) {
00735 SortData* sort_data;
00736
00737 sort_data = microfeed_memory_allocate(SortData);
00738 sort_data->json = json;
00739 sort_data->compare_members = compare_members;
00740 sort_data->user_data = user_data;
00741 microfeed_store_sort(json->members, compare_json_members_in_sort, sort_data);
00742 microfeed_memory_free(sort_data);
00743 }
00744
00745 int microfeed_json_compare_members(MicrofeedJson* json, unsigned int index1, unsigned int index2) {
00746 int retvalue = 0;
00747 Member* member1;
00748 Member* member2;
00749
00750 if (json &&
00751 (member1 = microfeed_store_get_index(json->members, index1, Member)) &&
00752 (member2 = microfeed_store_get_index(json->members, index2, Member)) &&
00753 member1->type == member2->type) {
00754 switch (member1->type) {
00755 case MICROFEED_JSON_TYPE_INTEGER:
00756 retvalue = (member1->integer < member2->integer ? -1 : (member1->integer > member2->integer ? + 1 : 0));
00757 break;
00758 case MICROFEED_JSON_TYPE_DECIMAL:
00759 retvalue = member1->decimal - member2->decimal;
00760 break;
00761 case MICROFEED_JSON_TYPE_STRING:
00762 retvalue = strcmp(member1->string, member2->string);
00763 break;
00764 case MICROFEED_JSON_TYPE_BOOLEAN:
00765 retvalue = (member1->boolean == member2->boolean ? 0 : (!member1->boolean && member2->boolean ? -1 : 1));
00766 break;
00767 default:
00768
00769 break;
00770 }
00771 }
00772
00773 return retvalue;
00774 }
00775
00776
00777
00778
00779
00780 static Member* member_new(char* name, MicrofeedJsonType type) {
00781 Member* member;
00782
00783 member = microfeed_memory_allocate(Member);
00784 member->name = name;
00785 member->type = type;
00786
00787 return member;
00788 }
00789
00790 static void member_free(Member* member) {
00791 if (member->type == MICROFEED_JSON_TYPE_OBJECT || member->type == MICROFEED_JSON_TYPE_ARRAY) {
00792 if (member->object) {
00793 member->object->parent = NULL;
00794 microfeed_json_free(member->object);
00795 }
00796 } else if (member->type == MICROFEED_JSON_TYPE_STRING) {
00797 free(member->string);
00798 }
00799 free(member->name);
00800 free(member->as_string);
00801 microfeed_memory_free(member);
00802 }
00803
00804 static const char* member_get_name(Member* member) {
00805
00806 return member->name;
00807 }
00808
00809 static const char* member_as_string(Member* member) {
00810 const char* string;
00811 char buffer[1024];
00812
00813 switch (member->type) {
00814 case MICROFEED_JSON_TYPE_NULL:
00815 string = "null";
00816 break;
00817 case MICROFEED_JSON_TYPE_OBJECT:
00818 case MICROFEED_JSON_TYPE_ARRAY:
00819 string = "<object>";
00820 break;
00821 case MICROFEED_JSON_TYPE_INTEGER:
00822 if (!member->as_string) {
00823 snprintf(buffer, 1024, "%lld", member->integer);
00824 member->as_string = strdup(buffer);
00825 }
00826 string = member->as_string;
00827 break;
00828 case MICROFEED_JSON_TYPE_DECIMAL:
00829 if (!member->as_string) {
00830 snprintf(buffer, 1024, "%lf", member->decimal);
00831 member->as_string = strdup(buffer);
00832 }
00833 string = member->as_string;
00834 break;
00835 case MICROFEED_JSON_TYPE_STRING:
00836 string = member->string;
00837 break;
00838 case MICROFEED_JSON_TYPE_BOOLEAN:
00839 if (member->boolean) {
00840 string = "true";
00841 } else {
00842 string = "false";
00843 }
00844 break;
00845 default:
00846
00847 exit(1);
00848 }
00849
00850 return string;
00851 }
00852
00853 static char* member_to_string(Member* member) {
00854 char* string = NULL;
00855 char buffer[1024];
00856
00857 switch (member->type) {
00858 case MICROFEED_JSON_TYPE_NULL:
00859 string = strdup("null");
00860 break;
00861 case MICROFEED_JSON_TYPE_OBJECT:
00862 case MICROFEED_JSON_TYPE_ARRAY:
00863 string = microfeed_json_to_string(member->object, NULL);
00864 break;
00865 case MICROFEED_JSON_TYPE_INTEGER:
00866 snprintf(buffer, 1024, "%lld", member->integer);
00867 string = strdup(buffer);
00868 break;
00869 case MICROFEED_JSON_TYPE_DECIMAL:
00870 snprintf(buffer, 1024, "%lf", member->decimal);
00871 string = strdup(buffer);
00872 break;
00873 case MICROFEED_JSON_TYPE_STRING:
00874
00875 string = microfeed_util_string_concatenate("\"", member->string, "\"", NULL);
00876 break;
00877 case MICROFEED_JSON_TYPE_BOOLEAN:
00878 if (member->boolean) {
00879 string = strdup("true");
00880 } else {
00881 string = strdup("false");
00882 }
00883 break;
00884 default:
00885
00886 exit(1);
00887 }
00888
00889 return string;
00890 }
00891
00892
00893
00894
00895
00896 static Member* parse_value(char* name, const char** data, const char* end) {
00897 Member* member = NULL;
00898
00899 eat_whitespaces(data, end);
00900 if (*data < end) {
00901 switch(**data) {
00902 case 'f':
00903 case 'F':
00904 if (are_next_characters("alse", 4, data, end)) {
00905 member = member_new(name, MICROFEED_JSON_TYPE_BOOLEAN);
00906 member->boolean = 0;
00907 }
00908 break;
00909 case 't':
00910 case 'T':
00911 if (are_next_characters("rue", 3, data, end)) {
00912 member = member_new(name, MICROFEED_JSON_TYPE_BOOLEAN);
00913 member->boolean = 1;
00914 }
00915 break;
00916 case 'n':
00917 case 'N':
00918 if (are_next_characters("ull", 3, data, end)) {
00919 member = member_new(name, MICROFEED_JSON_TYPE_NULL);
00920 }
00921 break;
00922 case '{':
00923 (*data)++;
00924 member = member_new(name, MICROFEED_JSON_TYPE_OBJECT);
00925 if (!(member->object = parse_object(data, end))) {
00926 member_free(member);
00927 member = NULL;
00928 }
00929 break;
00930 case '[':
00931 (*data)++;
00932 member = member_new(name, MICROFEED_JSON_TYPE_ARRAY);
00933 if (!(member->array = parse_array(data, end))) {
00934 member_free(member);
00935 member = NULL;
00936 }
00937 break;
00938 case '"':
00939 member = member_new(name, MICROFEED_JSON_TYPE_STRING);
00940 if (!(member->string = parse_string(data, end))) {
00941 member_free(member);
00942 member = NULL;
00943 }
00944 break;
00945 case '-':
00946 case '0':
00947 case '1':
00948 case '2':
00949 case '3':
00950 case '4':
00951 case '5':
00952 case '6':
00953 case '7':
00954 case '8':
00955 case '9':
00956 member = parse_number(name, data, end);
00957 break;
00958 }
00959 }
00960
00961 return member;
00962 }
00963
00964 static MicrofeedJson* parse_object(const char** data, const char* end) {
00965 MicrofeedJson* json;
00966 char* name;
00967 Member* member;
00968
00969 json = microfeed_json_new_object();
00970 while ((name = parse_string(data, end))) {
00971 eat_whitespaces(data, end);
00972 if (*data >= end || **data != ':') {
00973 microfeed_json_free(json);
00974 json = NULL;
00975 break;
00976 }
00977 (*data)++;
00978 if ((member = parse_value(name, data, end))) {
00979 if (!microfeed_store_insert(json->members, member)) {
00980 member_free(member);
00981 }
00982 } else {
00983 free(name);
00984 microfeed_json_free(json);
00985 json = NULL;
00986 break;
00987 }
00988 eat_whitespaces(data, end);
00989 if (*data >= end || **data != ',') {
00990 break;
00991 }
00992 (*data)++;
00993 }
00994 if (*data < end && **data == '}') {
00995 (*data)++;
00996 } else {
00997 microfeed_json_free(json);
00998 json = NULL;
00999 }
01000
01001 return json;
01002 }
01003
01004 static MicrofeedJson* parse_array(const char** data, const char* end) {
01005 MicrofeedJson* json;
01006 Member* member;
01007
01008 json = microfeed_json_new_array();
01009 while ((member = parse_value(NULL, data, end))) {
01010 if (!microfeed_store_insert(json->members, member)) {
01011 member_free(member);
01012 }
01013 eat_whitespaces(data, end);
01014 if (*data >= end || **data != ',') {
01015 break;
01016 }
01017 (*data)++;
01018 }
01019 if (*data < end && **data == ']') {
01020 (*data)++;
01021 } else {
01022 microfeed_json_free(json);
01023 json = NULL;
01024 }
01025
01026 return json;
01027 }
01028
01029 static char* parse_string(const char** data, const char* end) {
01030 char* string = NULL;
01031 size_t size = 0;
01032 unsigned int i = 0;
01033 const char* p;
01034 unsigned int hex1, hex2, hex3, hex4, hex;
01035
01036 eat_whitespaces(data, end);
01037 if (*data < end && **data == '"') {
01038 for (p = ++(*data); p < end && *p != '"'; p++) {
01039 if (i + 4 > size) {
01040 size += 1024;
01041 string = (char*)realloc(string, size);
01042 }
01043 if (*p == '\\') {
01044 p++;
01045 if (p < end) {
01046 if (*p == '"' || *p == '\\' || *p == '/') {
01047 string[i++] = *p;
01048 } else if (*p == 'b') {
01049 string[i++] = '\b';
01050 } else if (*p == 'f') {
01051 string[i++] = '\f';
01052 } else if (*p == 'n') {
01053 string[i++] = '\n';
01054 } else if (*p == 'r') {
01055 string[i++] = '\r';
01056 } else if (*p == 't') {
01057 string[i++] = '\t';
01058 } else if (*p == 'u') {
01059 p++;
01060 if (p + 3 < end &&
01061 hex_to_int(p[0], &hex1) && hex_to_int(p[1], &hex2) &&
01062 hex_to_int(p[2], &hex3) && hex_to_int(p[3], &hex4)) {
01063 hex = (hex1 << 12) | (hex2 << 8) | (hex3 << 4) | hex4;
01064 if (hex == 0) {
01065 string[i++] = ' ';
01066 } else if (hex < 0x80) {
01067 string[i++] = hex;
01068 } else if (hex < 0x800) {
01069 string[i++] = (char)(0xc0 | (hex >> 6));
01070 string[i++] = (char)(0x80 | (hex & 0x3f));
01071 } else {
01072 string[i++] = (char)(0xe0 | (hex >> 12));
01073 string[i++] = (char)(0x80 | ((hex >> 6) & 0x3f));
01074 string[i++] = (char)(0x80 | (hex & 0x3f));
01075 }
01076 p += 3;
01077 } else {
01078 break;
01079 }
01080 } else {
01081 break;
01082 }
01083 } else {
01084 break;
01085 }
01086 } else {
01087 string[i++] = *p;
01088 }
01089 }
01090 if (p < end && *p == '"') {
01091 string = (char*)realloc(string, i + 1);
01092 string[i] = 0;
01093 *data = p + 1;
01094 } else {
01095 free(string);
01096 string = NULL;
01097 *data = p;
01098 }
01099 }
01100
01101 return string;
01102 }
01103
01104 static Member* parse_number(char* name, const char** data, const char* end) {
01105 Member* member = NULL;
01106 const char* p;
01107 int decimal = 0;
01108 char* s;
01109 double d;
01110 long long int i;
01111
01112 p = *data;
01113 while (p < end && strchr("0123456789.eE+-", *p)) {
01114 if (*p == '.' || *p == 'e' || *p == 'E') {
01115 decimal = 1;
01116 }
01117 p++;
01118 }
01119 s = strndup(*data, p - *data);
01120 if (decimal) {
01121 if (sscanf(s, "%lf", &d) == 1) {
01122 member = member_new(name, MICROFEED_JSON_TYPE_DECIMAL);
01123 member->decimal = d;
01124 }
01125 } else {
01126 if (sscanf(s, "%lld", &i) == 1) {
01127 member = member_new(name, MICROFEED_JSON_TYPE_INTEGER);
01128 member->integer = i;
01129 }
01130 }
01131 free(s);
01132 *data = p;
01133
01134 return member;
01135 }
01136
01137 static void eat_whitespaces(const char** data, const char* end) {
01138 while (*data < end && (**data == 0x20 || **data == 0x09 || **data == 0x0A || **data == 0x0D)) {
01139 (*data)++;
01140 }
01141 }
01142
01143 static int are_next_characters(const char* next, size_t next_length, const char** data, const char* end) {
01144 size_t offset;
01145
01146 if (*data + next_length + 1 < end) {
01147 for (offset = 0; offset < next_length; offset++) {
01148 if (((*data)[offset + 1] | 0x20) != next[offset]) {
01149
01150 return 1;
01151 }
01152 }
01153 }
01154 *data += 1 + next_length;
01155
01156 return 1;
01157 }
01158
01159 static int hex_to_int(char hex, unsigned int* int_return) {
01160 int retvalue = 0;
01161
01162 if (hex >= '0' && hex <= '9') {
01163 *int_return = hex - '0';
01164 retvalue = 1;
01165 } else if (hex >= 'a' || hex <= 'f') {
01166 *int_return = hex - 'a' + 10;
01167 retvalue = 1;
01168 } else if (hex >= 'A' || hex <= 'F') {
01169 *int_return = hex - 'A' + 10;
01170 retvalue = 1;
01171 }
01172
01173 return retvalue;
01174 }
01175
01176 int compare_json_members_in_sort(const void* data1, const void* data2, unsigned int index1, unsigned int index2, void* user_data) {
01177 Member* member1;
01178 Member* member2;
01179 SortData* sort_data;
01180
01181 member1 = (Member*)data1;
01182 member2 = (Member*)data2;
01183 sort_data = (void*)user_data;
01184
01185 return sort_data->compare_members(sort_data->json, index1, index2, sort_data->user_data);
01186 }