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 const char* microfeed_json_get_string(MicrofeedJson* json, const char* name) {
00333 const char* string = NULL;
00334 Member* member;
00335
00336 if (name) {
00337 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_STRING) {
00338 string = member->string;
00339 }
00340 }
00341
00342 return string;
00343 }
00344
00345 const char* microfeed_json_get_string_by_index(MicrofeedJson* json, unsigned int index) {
00346 const char* string = NULL;
00347 Member* member;
00348
00349 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_STRING) {
00350 string = member->string;
00351 }
00352
00353 return string;
00354 }
00355
00356 const char* microfeed_json_get_string_by_path(MicrofeedJson* json, const char* name, ...) {
00357 const char* string = NULL;
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_STRING) {
00369 string = member->string;
00370 }
00371 }
00372
00373 return string;
00374 }
00375
00376 int microfeed_json_get_boolean(MicrofeedJson* json, const char* name) {
00377 int boolean = 0;
00378 Member* member;
00379
00380 if ((member = microfeed_store_get(json->members, name, Member)) && member->type == MICROFEED_JSON_TYPE_BOOLEAN) {
00381 boolean = member->boolean;
00382 }
00383
00384 return boolean;
00385 }
00386
00387 int microfeed_json_get_boolean_by_index(MicrofeedJson* json, unsigned int index) {
00388 int boolean = 0;
00389 Member* member;
00390
00391 if ((member = microfeed_store_get_index(json->members, index, Member)) && member->type == MICROFEED_JSON_TYPE_BOOLEAN) {
00392 boolean = member->boolean;
00393 }
00394
00395 return boolean;
00396 }
00397
00398 int microfeed_json_get_boolean_by_path(MicrofeedJson* json, const char* name, ...) {
00399 int boolean = 0;
00400 Member* member;
00401 va_list argp;
00402 const char* s;
00403
00404 if ((member = microfeed_store_get(json->members, name, Member))) {
00405 va_start(argp, name);
00406 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00407 (member = microfeed_store_get(member->object->members, s, Member))) {
00408 }
00409 va_end(argp);
00410 if (!s && member->type == MICROFEED_JSON_TYPE_BOOLEAN) {
00411 boolean = member->boolean;
00412 }
00413 }
00414
00415 return boolean;
00416 }
00417
00418 const char* microfeed_json_get_as_string(MicrofeedJson* json, const char* name) {
00419 const char* string = NULL;
00420 Member* member;
00421
00422 if (name) {
00423 if ((member = microfeed_store_get(json->members, name, Member))) {
00424 string = member_as_string(member);
00425 }
00426 }
00427
00428 return string;
00429 }
00430
00431 const char* microfeed_json_get_as_string_by_index(MicrofeedJson* json, unsigned int index) {
00432 const char* string = NULL;
00433 Member* member;
00434
00435 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00436 string = member_as_string(member);
00437 }
00438
00439 return string;
00440 }
00441
00442 const char* microfeed_json_get_as_string_by_path(MicrofeedJson* json, const char* name, ...) {
00443 const char* string = NULL;
00444 Member* member;
00445 va_list argp;
00446 const char* s;
00447
00448 if ((member = microfeed_store_get(json->members, name, Member))) {
00449 va_start(argp, name);
00450 while ((s = va_arg(argp, const char*)) && member->type == MICROFEED_JSON_TYPE_OBJECT &&
00451 (member = microfeed_store_get(member->object->members, s, Member))) {
00452 }
00453 va_end(argp);
00454 if (!s) {
00455 string = member_as_string(member);
00456 }
00457 }
00458
00459 return string;
00460 }
00461
00462 char* microfeed_json_to_string(MicrofeedJson* json, const char* name) {
00463 char* string = NULL;
00464 Member* member;
00465 size_t size;
00466 unsigned int i;
00467 MicrofeedStoreIterator* iterator;
00468 size_t length1;
00469 size_t length2;
00470 char* s;
00471
00472 if (name) {
00473 if ((member = microfeed_store_get(json->members, name, Member))) {
00474 string = member_to_string(member);
00475 } else {
00476 string = strdup("null");
00477 }
00478 } else {
00479 size = 2;
00480 string = (char*)malloc(size + 1);
00481 i = 1;
00482 string[i] = ' ';
00483 for (iterator = microfeed_store_iterate(json->members, NULL);
00484 (member = microfeed_store_iterator_get(iterator, Member));
00485 microfeed_store_iterator_next(iterator)) {
00486 if (member->name) {
00487 length1 = strlen(member->name);
00488 size += length1 + 3;
00489 } else {
00490 length1 = 0;
00491 }
00492 s = member_to_string(member);
00493 length2 = strlen(s);
00494 size += length2 + 1;
00495 string = (char*)realloc(string, size + 1);
00496 if (length1) {
00497 string[i++] = '"';
00498 memcpy(string + i, member->name, length1);
00499 i += length1;
00500 string[i++] = '"';
00501 string[i++] = ':';
00502 }
00503 memcpy(string + i, s, length2);
00504 i += length2;
00505 string[i++] = ',';
00506 free(s);
00507
00508 }
00509 microfeed_store_iterator_free(iterator);
00510 if (microfeed_store_is_sorted(json->members)) {
00511 string[0] = '{';
00512 string[size - 1] = '}';
00513 } else {
00514 string[0] = '[';
00515 string[size - 1] = ']';
00516 }
00517 string[size] = 0;
00518 }
00519
00520 return string;
00521 }
00522
00523 char* microfeed_json_to_string_by_index(MicrofeedJson* json, unsigned int index) {
00524 char* string = NULL;
00525 Member* member;
00526
00527 if ((member = microfeed_store_get_index(json->members, index, Member))) {
00528 string = member_to_string(member);
00529 } else {
00530 string = strdup("null");
00531 }
00532
00533 return string;
00534 }
00535
00536 char* microfeed_json_to_string_by_path(MicrofeedJson* json, const char* name, ...);
00537
00538 void microfeed_json_set_null(MicrofeedJson* json, const char* name) {
00539 Member* member;
00540
00541 member = member_new(strdup(name), MICROFEED_JSON_TYPE_NULL);
00542 if ((member = microfeed_store_replace(json->members, member, Member))) {
00543 member_free(member);
00544 }
00545 }
00546
00547 void microfeed_json_append_null(MicrofeedJson* json, MicrofeedJson* object) {
00548 Member* member;
00549
00550 member = member_new(NULL, MICROFEED_JSON_TYPE_NULL);
00551 microfeed_store_insert(json->members, member);
00552 }
00553
00554 void microfeed_json_set_object(MicrofeedJson* json, const char* name, MicrofeedJson* object) {
00555 Member* member;
00556
00557 member = member_new(strdup(name), MICROFEED_JSON_TYPE_OBJECT);
00558 member->object = object;
00559 if ((member = microfeed_store_replace(json->members, member, Member))) {
00560 member_free(member);
00561 }
00562 }
00563
00564 void microfeed_json_append_object(MicrofeedJson* json, MicrofeedJson* object) {
00565 Member* member;
00566
00567 member = member_new(NULL, MICROFEED_JSON_TYPE_OBJECT);
00568 member->object = object;
00569 microfeed_store_insert(json->members, member);
00570 }
00571
00572 void microfeed_json_set_string(MicrofeedJson* json, const char* name, const char* string) {
00573 Member* member;
00574
00575 member = member_new(strdup(name), MICROFEED_JSON_TYPE_STRING);
00576 member->string = strdup(string);
00577 if ((member = microfeed_store_replace(json->members, member, Member))) {
00578 member_free(member);
00579 }
00580 }
00581
00582 void microfeed_json_append_string(MicrofeedJson* json, const char* string) {
00583 Member* member;
00584
00585 member = member_new(NULL, MICROFEED_JSON_TYPE_STRING);
00586 member->string = strdup(string);
00587 microfeed_store_insert(json->members, member);
00588 }
00589
00590 void microfeed_json_set_boolean(MicrofeedJson* json, const char* name, int boolean) {
00591 Member* member;
00592
00593 member = member_new(strdup(name), MICROFEED_JSON_TYPE_BOOLEAN);
00594 member->boolean = boolean;
00595 if ((member = microfeed_store_replace(json->members, member, Member))) {
00596 member_free(member);
00597 }
00598 }
00599
00600 void microfeed_json_append_boolean(MicrofeedJson* json, int boolean) {
00601 Member* member;
00602
00603 member = member_new(NULL, MICROFEED_JSON_TYPE_BOOLEAN);
00604 member->boolean = boolean;
00605 microfeed_store_insert(json->members, member);
00606 }
00607
00608
00609 void microfeed_json_sort_array(MicrofeedJson* json, MicrofeedJsonCompareMembersFunction compare_members, void* user_data) {
00610 SortData* sort_data;
00611
00612 sort_data = microfeed_memory_allocate(SortData);
00613 sort_data->json = json;
00614 sort_data->compare_members = compare_members;
00615 sort_data->user_data = user_data;
00616 microfeed_store_sort(json->members, compare_json_members_in_sort, sort_data);
00617 microfeed_memory_free(sort_data);
00618 }
00619
00620 int microfeed_json_compare_members(MicrofeedJson* json, unsigned int index1, unsigned int index2) {
00621 int retvalue = 0;
00622 Member* member1;
00623 Member* member2;
00624
00625 if (json &&
00626 (member1 = microfeed_store_get_index(json->members, index1, Member)) &&
00627 (member2 = microfeed_store_get_index(json->members, index2, Member)) &&
00628 member1->type == member2->type) {
00629 switch (member1->type) {
00630 case MICROFEED_JSON_TYPE_INTEGER:
00631 retvalue = (member1->integer < member2->integer ? -1 : (member1->integer > member2->integer ? + 1 : 0));
00632 break;
00633 case MICROFEED_JSON_TYPE_DECIMAL:
00634 retvalue = member1->decimal - member2->decimal;
00635 break;
00636 case MICROFEED_JSON_TYPE_STRING:
00637 retvalue = strcmp(member1->string, member2->string);
00638 break;
00639 case MICROFEED_JSON_TYPE_BOOLEAN:
00640 retvalue = (member1->boolean == member2->boolean ? 0 : (!member1->boolean && member2->boolean ? -1 : 1));
00641 break;
00642 default:
00643
00644 break;
00645 }
00646 }
00647
00648 return retvalue;
00649 }
00650
00651
00652
00653
00654
00655 static Member* member_new(char* name, MicrofeedJsonType type) {
00656 Member* member;
00657
00658 member = microfeed_memory_allocate(Member);
00659 member->name = name;
00660 member->type = type;
00661
00662 return member;
00663 }
00664
00665 static void member_free(Member* member) {
00666 if (member->type == MICROFEED_JSON_TYPE_OBJECT || member->type == MICROFEED_JSON_TYPE_ARRAY) {
00667 if (member->object) {
00668 member->object->parent = NULL;
00669 microfeed_json_free(member->object);
00670 }
00671 } else if (member->type == MICROFEED_JSON_TYPE_STRING) {
00672 free(member->string);
00673 }
00674 free(member->name);
00675 free(member->as_string);
00676 microfeed_memory_free(member);
00677 }
00678
00679 static const char* member_get_name(Member* member) {
00680
00681 return member->name;
00682 }
00683
00684 static const char* member_as_string(Member* member) {
00685 const char* string;
00686 char buffer[1024];
00687
00688 switch (member->type) {
00689 case MICROFEED_JSON_TYPE_NULL:
00690 string = "null";
00691 break;
00692 case MICROFEED_JSON_TYPE_OBJECT:
00693 case MICROFEED_JSON_TYPE_ARRAY:
00694 string = "<object>";
00695 break;
00696 case MICROFEED_JSON_TYPE_INTEGER:
00697 if (!member->as_string) {
00698 snprintf(buffer, 1024, "%lld", member->integer);
00699 member->as_string = strdup(buffer);
00700 }
00701 string = member->as_string;
00702 break;
00703 case MICROFEED_JSON_TYPE_DECIMAL:
00704 if (!member->as_string) {
00705 snprintf(buffer, 1024, "%lf", member->decimal);
00706 member->as_string = strdup(buffer);
00707 }
00708 string = member->as_string;
00709 break;
00710 case MICROFEED_JSON_TYPE_STRING:
00711 string = member->string;
00712 break;
00713 case MICROFEED_JSON_TYPE_BOOLEAN:
00714 if (member->boolean) {
00715 string = "true";
00716 } else {
00717 string = "false";
00718 }
00719 break;
00720 default:
00721
00722 exit(1);
00723 }
00724
00725 return string;
00726 }
00727
00728 static char* member_to_string(Member* member) {
00729 char* string = NULL;
00730 char buffer[1024];
00731
00732 switch (member->type) {
00733 case MICROFEED_JSON_TYPE_NULL:
00734 string = strdup("null");
00735 break;
00736 case MICROFEED_JSON_TYPE_OBJECT:
00737 case MICROFEED_JSON_TYPE_ARRAY:
00738 string = microfeed_json_to_string(member->object, NULL);
00739 break;
00740 case MICROFEED_JSON_TYPE_INTEGER:
00741 snprintf(buffer, 1024, "%lld", member->integer);
00742 string = strdup(buffer);
00743 break;
00744 case MICROFEED_JSON_TYPE_DECIMAL:
00745 snprintf(buffer, 1024, "%lf", member->decimal);
00746 string = strdup(buffer);
00747 break;
00748 case MICROFEED_JSON_TYPE_STRING:
00749
00750 string = microfeed_util_string_concatenate("\"", member->string, "\"", NULL);
00751 break;
00752 case MICROFEED_JSON_TYPE_BOOLEAN:
00753 if (member->boolean) {
00754 string = strdup("true");
00755 } else {
00756 string = strdup("false");
00757 }
00758 break;
00759 default:
00760
00761 exit(1);
00762 }
00763
00764 return string;
00765 }
00766
00767
00768
00769
00770
00771 static Member* parse_value(char* name, const char** data, const char* end) {
00772 Member* member = NULL;
00773
00774 eat_whitespaces(data, end);
00775 if (*data < end) {
00776 switch(**data) {
00777 case 'f':
00778 case 'F':
00779 if (are_next_characters("alse", 4, data, end)) {
00780 member = member_new(name, MICROFEED_JSON_TYPE_BOOLEAN);
00781 member->boolean = 0;
00782 }
00783 break;
00784 case 't':
00785 case 'T':
00786 if (are_next_characters("rue", 3, data, end)) {
00787 member = member_new(name, MICROFEED_JSON_TYPE_BOOLEAN);
00788 member->boolean = 1;
00789 }
00790 break;
00791 case 'n':
00792 case 'N':
00793 if (are_next_characters("ull", 3, data, end)) {
00794 member = member_new(name, MICROFEED_JSON_TYPE_NULL);
00795 }
00796 break;
00797 case '{':
00798 (*data)++;
00799 member = member_new(name, MICROFEED_JSON_TYPE_OBJECT);
00800 if (!(member->object = parse_object(data, end))) {
00801 member_free(member);
00802 member = NULL;
00803 }
00804 break;
00805 case '[':
00806 (*data)++;
00807 member = member_new(name, MICROFEED_JSON_TYPE_ARRAY);
00808 if (!(member->array = parse_array(data, end))) {
00809 member_free(member);
00810 member = NULL;
00811 }
00812 break;
00813 case '"':
00814 member = member_new(name, MICROFEED_JSON_TYPE_STRING);
00815 if (!(member->string = parse_string(data, end))) {
00816 member_free(member);
00817 member = NULL;
00818 }
00819 break;
00820 case '-':
00821 case '0':
00822 case '1':
00823 case '2':
00824 case '3':
00825 case '4':
00826 case '5':
00827 case '6':
00828 case '7':
00829 case '8':
00830 case '9':
00831 member = parse_number(name, data, end);
00832 break;
00833 }
00834 }
00835
00836 return member;
00837 }
00838
00839 static MicrofeedJson* parse_object(const char** data, const char* end) {
00840 MicrofeedJson* json;
00841 char* name;
00842 Member* member;
00843
00844 json = microfeed_json_new_object();
00845 while ((name = parse_string(data, end))) {
00846 eat_whitespaces(data, end);
00847 if (*data >= end || **data != ':') {
00848 microfeed_json_free(json);
00849 json = NULL;
00850 break;
00851 }
00852 (*data)++;
00853 if ((member = parse_value(name, data, end))) {
00854 if (!microfeed_store_insert(json->members, member)) {
00855 member_free(member);
00856 }
00857 } else {
00858 free(name);
00859 microfeed_json_free(json);
00860 json = NULL;
00861 break;
00862 }
00863 eat_whitespaces(data, end);
00864 if (*data >= end || **data != ',') {
00865 break;
00866 }
00867 (*data)++;
00868 }
00869 if (*data < end && **data == '}') {
00870 (*data)++;
00871 } else {
00872 microfeed_json_free(json);
00873 json = NULL;
00874 }
00875
00876 return json;
00877 }
00878
00879 static MicrofeedJson* parse_array(const char** data, const char* end) {
00880 MicrofeedJson* json;
00881 Member* member;
00882
00883 json = microfeed_json_new_array();
00884 while ((member = parse_value(NULL, data, end))) {
00885 if (!microfeed_store_insert(json->members, member)) {
00886 member_free(member);
00887 }
00888 eat_whitespaces(data, end);
00889 if (*data >= end || **data != ',') {
00890 break;
00891 }
00892 (*data)++;
00893 }
00894 if (*data < end && **data == ']') {
00895 (*data)++;
00896 } else {
00897 microfeed_json_free(json);
00898 json = NULL;
00899 }
00900
00901 return json;
00902 }
00903
00904 static char* parse_string(const char** data, const char* end) {
00905 char* string = NULL;
00906 size_t size = 0;
00907 unsigned int i = 0;
00908 const char* p;
00909 unsigned int hex1, hex2, hex3, hex4, hex;
00910
00911 eat_whitespaces(data, end);
00912 if (*data < end && **data == '"') {
00913 for (p = ++(*data); p < end && *p != '"'; p++) {
00914 if (i + 4 > size) {
00915 size += 1024;
00916 string = (char*)realloc(string, size);
00917 }
00918 if (*p == '\\') {
00919 p++;
00920 if (p < end) {
00921 if (*p == '"' || *p == '\\' || *p == '/') {
00922 string[i++] = *p;
00923 } else if (*p == 'b') {
00924 string[i++] = '\b';
00925 } else if (*p == 'f') {
00926 string[i++] = '\f';
00927 } else if (*p == 'n') {
00928 string[i++] = '\n';
00929 } else if (*p == 'r') {
00930 string[i++] = '\r';
00931 } else if (*p == 't') {
00932 string[i++] = '\t';
00933 } else if (*p == 'u') {
00934 p++;
00935 if (p + 3 < end &&
00936 hex_to_int(p[0], &hex1) && hex_to_int(p[1], &hex2) &&
00937 hex_to_int(p[2], &hex3) && hex_to_int(p[3], &hex4)) {
00938 hex = (hex1 << 12) | (hex2 << 8) | (hex3 << 4) | hex4;
00939 if (hex == 0) {
00940 string[i++] = ' ';
00941 } else if (hex < 0x80) {
00942 string[i++] = hex;
00943 } else if (hex < 0x800) {
00944 string[i++] = (char)(0xc0 | (hex >> 6));
00945 string[i++] = (char)(0x80 | (hex & 0x3f));
00946 } else {
00947 string[i++] = (char)(0xe0 | (hex >> 12));
00948 string[i++] = (char)(0x80 | ((hex >> 6) & 0x3f));
00949 string[i++] = (char)(0x80 | (hex & 0x3f));
00950 }
00951 p += 3;
00952 } else {
00953 break;
00954 }
00955 } else {
00956 break;
00957 }
00958 } else {
00959 break;
00960 }
00961 } else {
00962 string[i++] = *p;
00963 }
00964 }
00965 if (p < end && *p == '"') {
00966 string = (char*)realloc(string, i + 1);
00967 string[i] = 0;
00968 *data = p + 1;
00969 } else {
00970 free(string);
00971 string = NULL;
00972 *data = p;
00973 }
00974 }
00975
00976 return string;
00977 }
00978
00979 static Member* parse_number(char* name, const char** data, const char* end) {
00980 Member* member = NULL;
00981 const char* p;
00982 int decimal = 0;
00983 char* s;
00984 double d;
00985 long long int i;
00986
00987 p = *data;
00988 while (p < end && strchr("0123456789.eE+-", *p)) {
00989 if (*p == '.' || *p == 'e' || *p == 'E') {
00990 decimal = 1;
00991 }
00992 p++;
00993 }
00994 s = strndup(*data, p - *data);
00995 if (decimal) {
00996 if (sscanf(s, "%lf", &d) == 1) {
00997 member = member_new(name, MICROFEED_JSON_TYPE_DECIMAL);
00998 member->decimal = d;
00999 }
01000 } else {
01001 if (sscanf(s, "%lld", &i) == 1) {
01002 member = member_new(name, MICROFEED_JSON_TYPE_INTEGER);
01003 member->integer = i;
01004 }
01005 }
01006 free(s);
01007 *data = p;
01008
01009 return member;
01010 }
01011
01012 static void eat_whitespaces(const char** data, const char* end) {
01013 while (*data < end && (**data == 0x20 || **data == 0x09 || **data == 0x0A || **data == 0x0D)) {
01014 (*data)++;
01015 }
01016 }
01017
01018 static int are_next_characters(const char* next, size_t next_length, const char** data, const char* end) {
01019 size_t offset;
01020
01021 if (*data + next_length + 1 < end) {
01022 for (offset = 0; offset < next_length; offset++) {
01023 if (((*data)[offset + 1] | 0x20) != next[offset]) {
01024
01025 return 1;
01026 }
01027 }
01028 }
01029 *data += 1 + next_length;
01030
01031 return 1;
01032 }
01033
01034 static int hex_to_int(char hex, unsigned int* int_return) {
01035 int retvalue = 0;
01036
01037 if (hex >= '0' && hex <= '9') {
01038 *int_return = hex - '0';
01039 retvalue = 1;
01040 } else if (hex >= 'a' || hex <= 'f') {
01041 *int_return = hex - 'a' + 10;
01042 retvalue = 1;
01043 } else if (hex >= 'A' || hex <= 'F') {
01044 *int_return = hex - 'A' + 10;
01045 retvalue = 1;
01046 }
01047
01048 return retvalue;
01049 }
01050
01051 int compare_json_members_in_sort(const void* data1, const void* data2, unsigned int index1, unsigned int index2, void* user_data) {
01052 Member* member1;
01053 Member* member2;
01054 SortData* sort_data;
01055
01056 member1 = (Member*)data1;
01057 member2 = (Member*)data2;
01058 sort_data = (void*)user_data;
01059
01060 return sort_data->compare_members(sort_data->json, index1, index2, sort_data->user_data);
01061 }