Changes in / [6ae1056:820a2a7]
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
configure
r6ae1056 r820a2a7 140 140 DESTDIR= 141 141 LFLAGS= 142 EFLAGS= -lm142 EFLAGS= 143 143 EOF 144 144 -
lib/json.c
r6ae1056 r820a2a7 1 /* vim: set et ts=3 sw=3 sts=3 ft=c: 1 2 /* vim: set et ts=3 sw=3 ft=c: 2 3 * 3 * Copyright (C) 2012 , 2013, 2014James McLaughlin et al. All rights reserved.4 * Copyright (C) 2012 James McLaughlin et al. All rights reserved. 4 5 * https://github.com/udp/json-parser 5 6 * … … 28 29 */ 29 30 30 #include <glib.h>31 32 31 #include "json.h" 33 32 … … 44 43 #endif 45 44 45 #include <glib.h> 46 #include <stdlib.h> 46 47 #include <stdio.h> 47 48 #include <string.h> 48 49 #include <ctype.h> 49 #include <math.h>50 50 51 51 typedef unsigned short json_uchar; … … 53 53 static unsigned char hex_value (json_char c) 54 54 { 55 if (isdigit(c)) 55 if (c >= 'A' && c <= 'F') 56 return (c - 'A') + 10; 57 58 if (c >= 'a' && c <= 'f') 59 return (c - 'a') + 10; 60 61 if (c >= '0' && c <= '9') 56 62 return c - '0'; 57 63 58 switch (c) { 59 case 'a': case 'A': return 0x0A; 60 case 'b': case 'B': return 0x0B; 61 case 'c': case 'C': return 0x0C; 62 case 'd': case 'D': return 0x0D; 63 case 'e': case 'E': return 0x0E; 64 case 'f': case 'F': return 0x0F; 65 default: return 0xFF; 66 } 64 return 0xFF; 67 65 } 68 66 69 67 typedef struct 70 68 { 69 json_settings settings; 70 int first_pass; 71 71 72 unsigned long used_memory; 72 73 … … 74 75 unsigned long ulong_max; 75 76 76 json_settings settings;77 int first_pass;78 79 77 } json_state; 80 81 static void * default_alloc (size_t size, int zero, void * user_data)82 {83 return zero ? calloc (1, size) : malloc (size);84 }85 86 static void default_free (void * ptr, void * user_data)87 {88 free (ptr);89 }90 78 91 79 static void * json_alloc (json_state * state, unsigned long size, int zero) 92 80 { 81 void * mem; 82 93 83 if ((state->ulong_max - state->used_memory) < size) 94 84 return 0; … … 100 90 } 101 91 102 return state->settings.mem_alloc (size, zero, state->settings.user_data); 92 if (! (mem = zero ? calloc (size, 1) : malloc (size))) 93 return 0; 94 95 return mem; 103 96 } 104 97 … … 127 120 } 128 121 129 value->u.array.length = 0;130 122 break; 131 123 … … 142 134 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; 143 135 144 value->u.object.length = 0;145 136 break; 146 137 … … 153 144 } 154 145 155 value->u.string.length = 0;156 146 break; 157 147 … … 160 150 }; 161 151 152 value->u.array.length = 0; 153 162 154 return 1; 163 155 } … … 192 184 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0); 193 185 194 static const long 195 flag_next = 1 << 0, 196 flag_reproc = 1 << 1, 197 flag_need_comma = 1 << 2, 198 flag_seek_value = 1 << 3, 199 flag_escaped = 1 << 4, 200 flag_string = 1 << 5, 201 flag_need_colon = 1 << 6, 202 flag_done = 1 << 7, 203 flag_num_negative = 1 << 8, 204 flag_num_zero = 1 << 9, 205 flag_num_e = 1 << 10, 206 flag_num_e_got_sign = 1 << 11, 207 flag_num_e_negative = 1 << 12, 208 flag_line_comment = 1 << 13, 209 flag_block_comment = 1 << 14; 210 211 json_value * json_parse_ex (json_settings * settings, 212 const json_char * json, 213 size_t length, 214 char * error_buf) 186 const static int 187 flag_next = 1, flag_reproc = 2, flag_need_comma = 4, flag_seek_value = 8, flag_exponent = 16, 188 flag_got_exponent_sign = 32, flag_escaped = 64, flag_string = 128, flag_need_colon = 256, 189 flag_done = 512; 190 191 json_value * json_parse_ex (json_settings * settings, const json_char * json, char * error_buf) 215 192 { 216 json_char error [ json_error_max];193 json_char error [128]; 217 194 unsigned int cur_line; 218 const json_char * cur_line_begin, * i , * end;195 const json_char * cur_line_begin, * i; 219 196 json_value * top, * root, * alloc = 0; 220 json_state state = { 0 }; 221 long flags; 222 long num_digits = 0, num_e = 0; 223 json_int_t num_fraction = 0; 224 225 /* Skip UTF-8 BOM 226 */ 227 if (length >= 3 && ((unsigned char) json [0]) == 0xEF 228 && ((unsigned char) json [1]) == 0xBB 229 && ((unsigned char) json [2]) == 0xBF) 230 { 231 json += 3; 232 length -= 3; 233 } 197 json_state state; 198 int flags; 234 199 235 200 error[0] = '\0'; 236 end = (json + length); 237 201 202 memset (&state, 0, sizeof (json_state)); 238 203 memcpy (&state.settings, settings, sizeof (json_settings)); 239 240 if (!state.settings.mem_alloc)241 state.settings.mem_alloc = default_alloc;242 243 if (!state.settings.mem_free)244 state.settings.mem_free = default_free;245 204 246 205 memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); … … 265 224 for (i = json ;; ++ i) 266 225 { 267 json_char b = (i == end ? 0 : *i); 268 226 json_char b = *i; 227 228 if (flags & flag_done) 229 { 230 if (!b) 231 break; 232 233 switch (b) 234 { 235 whitespace: 236 continue; 237 238 default: 239 sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b); 240 goto e_failed; 241 }; 242 } 243 269 244 if (flags & flag_string) 270 245 { … … 290 265 case 'u': 291 266 292 if (end - i < 4 || 293 (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF 267 if ((uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF 294 268 || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF) 295 269 { … … 370 344 = (json_char *) top->_reserved.object_mem; 371 345 372 top->u.object.values [top->u.object.length].name_length373 = string_length;374 375 346 (*(json_char **) &top->_reserved.object_mem) += string_length + 1; 376 347 } … … 390 361 } 391 362 392 if (state.settings.settings & json_enable_comments)393 {394 if (flags & (flag_line_comment | flag_block_comment))395 {396 if (flags & flag_line_comment)397 {398 if (b == '\r' || b == '\n' || !b)399 {400 flags &= ~ flag_line_comment;401 -- i; /* so null can be reproc'd */402 }403 404 continue;405 }406 407 if (flags & flag_block_comment)408 {409 if (!b)410 { sprintf (error, "%d:%d: Unexpected EOF in block comment", cur_line, e_off);411 goto e_failed;412 }413 414 if (b == '*' && i < (end - 1) && i [1] == '/')415 {416 flags &= ~ flag_block_comment;417 ++ i; /* skip closing sequence */418 }419 420 continue;421 }422 }423 else if (b == '/')424 {425 if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)426 {427 sprintf (error, "%d:%d: Comment not allowed here", cur_line, e_off);428 goto e_failed;429 }430 431 if (++ i == end)432 { sprintf (error, "%d:%d: EOF unexpected", cur_line, e_off);433 goto e_failed;434 }435 436 switch (b = *i)437 {438 case '/':439 flags |= flag_line_comment;440 continue;441 442 case '*':443 flags |= flag_block_comment;444 continue;445 446 default:447 sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, b);448 goto e_failed;449 };450 }451 }452 453 if (flags & flag_done)454 {455 if (!b)456 break;457 458 switch (b)459 {460 whitespace:461 continue;462 463 default:464 sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);465 goto e_failed;466 };467 }468 469 363 if (flags & flag_seek_value) 470 364 { … … 478 372 if (top->type == json_array) 479 373 flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; 480 else 374 else if (!state.settings.settings & json_relaxed_commas) 481 375 { sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off); 482 376 goto e_failed; … … 544 438 case 't': 545 439 546 if ( (end - i) < 3 ||*(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')440 if (*(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e') 547 441 goto e_unknown_value; 548 442 … … 557 451 case 'f': 558 452 559 if ( (end - i) < 4 ||*(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')453 if (*(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e') 560 454 goto e_unknown_value; 561 455 … … 568 462 case 'n': 569 463 570 if ( (end - i) < 3 ||*(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')464 if (*(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l') 571 465 goto e_unknown_value; 572 466 … … 584 478 goto e_alloc_failure; 585 479 586 if (!state.first_pass) 587 { 588 while (isdigit (b) || b == '+' || b == '-' 589 || b == 'e' || b == 'E' || b == '.') 590 { 591 if ( (++ i) == end) 592 { 593 b = 0; 594 break; 595 } 596 597 b = *i; 598 } 599 600 flags |= flag_next | flag_reproc; 601 break; 602 } 603 604 flags &= ~ (flag_num_negative | flag_num_e | 605 flag_num_e_got_sign | flag_num_e_negative | 606 flag_num_zero); 607 608 num_digits = 0; 609 num_fraction = 0; 610 num_e = 0; 611 612 if (b != '-') 613 { 614 flags |= flag_reproc; 615 break; 616 } 617 618 flags |= flag_num_negative; 619 continue; 480 flags &= ~ (flag_exponent | flag_got_exponent_sign); 481 482 if (state.first_pass) 483 continue; 484 485 if (top->type == json_double) 486 top->u.dbl = g_ascii_strtod (i, (json_char **) &i); 487 else 488 top->u.integer = g_ascii_strtoll (i, (json_char **) &i, 10); 489 490 flags |= flag_next | flag_reproc; 620 491 } 621 492 else … … 639 510 case '"': 640 511 641 if (flags & flag_need_comma )512 if (flags & flag_need_comma && (!state.settings.settings & json_relaxed_commas)) 642 513 { 643 514 sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off); … … 677 548 678 549 if (isdigit (b)) 550 continue; 551 552 if (b == 'e' || b == 'E') 679 553 { 680 ++ num_digits; 681 682 if (top->type == json_integer || flags & flag_num_e) 554 if (!(flags & flag_exponent)) 683 555 { 684 if (! (flags & flag_num_e)) 685 { 686 if (flags & flag_num_zero) 687 { sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b); 688 goto e_failed; 689 } 690 691 if (num_digits == 1 && b == '0') 692 flags |= flag_num_zero; 693 } 694 else 695 { 696 flags |= flag_num_e_got_sign; 697 num_e = (num_e * 10) + (b - '0'); 698 continue; 699 } 700 701 top->u.integer = (top->u.integer * 10) + (b - '0'); 556 flags |= flag_exponent; 557 top->type = json_double; 558 702 559 continue; 703 560 } 704 705 num_fraction = (num_fraction * 10) + (b - '0');706 continue;707 561 } 708 709 if (b == '+' || b == '-') 562 else if (b == '+' || b == '-') 710 563 { 711 if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))564 if (flags & flag_exponent && !(flags & flag_got_exponent_sign)) 712 565 { 713 flags |= flag_num_e_got_sign; 714 715 if (b == '-') 716 flags |= flag_num_e_negative; 717 566 flags |= flag_got_exponent_sign; 718 567 continue; 719 568 } … … 721 570 else if (b == '.' && top->type == json_integer) 722 571 { 723 if (!num_digits)724 { sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);725 goto e_failed;726 }727 728 572 top->type = json_double; 729 top->u.dbl = (double) top->u.integer;730 731 num_digits = 0;732 573 continue; 733 }734 735 if (! (flags & flag_num_e))736 {737 if (top->type == json_double)738 {739 if (!num_digits)740 { sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);741 goto e_failed;742 }743 744 top->u.dbl += ((double) num_fraction) / (pow (10, (double) num_digits));745 }746 747 if (b == 'e' || b == 'E')748 {749 flags |= flag_num_e;750 751 if (top->type == json_integer)752 {753 top->type = json_double;754 top->u.dbl = (double) top->u.integer;755 }756 757 num_digits = 0;758 flags &= ~ flag_num_zero;759 760 continue;761 }762 }763 else764 {765 if (!num_digits)766 { sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);767 goto e_failed;768 }769 770 top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));771 }772 773 if (flags & flag_num_negative)774 {775 if (top->type == json_integer)776 top->u.integer = - top->u.integer;777 else778 top->u.dbl = - top->u.dbl;779 574 } 780 575 … … 878 673 { 879 674 top = alloc->_reserved.next_alloc; 880 state.settings.mem_free (alloc, state.settings.user_data);675 free (alloc); 881 676 alloc = top; 882 677 } 883 678 884 679 if (!state.first_pass) 885 json_value_free _ex (&state.settings,root);680 json_value_free (root); 886 681 887 682 return 0; 888 683 } 889 684 890 json_value * json_parse (const json_char * json , size_t length)685 json_value * json_parse (const json_char * json) 891 686 { 892 json_settings settings = { 0 }; 893 return json_parse_ex (&settings, json, length, 0); 687 json_settings settings; 688 memset (&settings, 0, sizeof (json_settings)); 689 690 return json_parse_ex (&settings, json, 0); 894 691 } 895 692 896 void json_value_free _ex (json_settings * settings,json_value * value)693 void json_value_free (json_value * value) 897 694 { 898 695 json_value * cur_value; … … 911 708 if (!value->u.array.length) 912 709 { 913 settings->mem_free (value->u.array.values, settings->user_data);710 free (value->u.array.values); 914 711 break; 915 712 } … … 922 719 if (!value->u.object.length) 923 720 { 924 settings->mem_free (value->u.object.values, settings->user_data);721 free (value->u.object.values); 925 722 break; 926 723 } … … 931 728 case json_string: 932 729 933 settings->mem_free (value->u.string.ptr, settings->user_data);730 free (value->u.string.ptr); 934 731 break; 935 732 … … 940 737 cur_value = value; 941 738 value = value->parent; 942 settings->mem_free (cur_value, settings->user_data);739 free (cur_value); 943 740 } 944 741 } 945 742 946 void json_value_free (json_value * value) 947 { 948 json_settings settings = { 0 }; 949 settings.mem_free = default_free; 950 json_value_free_ex (&settings, value); 951 } 952 743 -
lib/json.h
r6ae1056 r820a2a7 1 1 2 /* vim: set et ts=3 sw=3 sts=3ft=c:2 /* vim: set et ts=3 sw=3 ft=c: 3 3 * 4 * Copyright (C) 2012 , 2013, 2014James McLaughlin et al. All rights reserved.4 * Copyright (C) 2012 James McLaughlin et al. All rights reserved. 5 5 * https://github.com/udp/json-parser 6 6 * … … 36 36 #endif 37 37 38 #ifndef json_int_t39 #ifndef _MSC_VER40 #include <inttypes.h>41 #define json_int_t int64_t42 #else43 #define json_int_t __int6444 #endif45 #endif46 47 #include <stdlib.h>48 49 38 #ifdef __cplusplus 50 39 … … 61 50 int settings; 62 51 63 /* Custom allocator support (leave null to use malloc/free)64 */65 66 void * (* mem_alloc) (size_t, int zero, void * user_data);67 void (* mem_free) (void *, void * user_data);68 69 void * user_data; /* will be passed to mem_alloc and mem_free */70 71 52 } json_settings; 72 53 73 #define json_ enable_comments 0x0154 #define json_relaxed_commas 1 74 55 75 56 typedef enum … … 97 78 { 98 79 int boolean; 99 json_int_tinteger;80 long long integer; 100 81 double dbl; 101 82 … … 114 95 { 115 96 json_char * name; 116 unsigned int name_length;117 118 97 struct _json_value * value; 119 98 120 99 } * values; 121 122 #if defined(__cplusplus) && __cplusplus >= 201103L123 decltype(values) begin () const124 { return values;125 }126 decltype(values) end () const127 { return values + length;128 }129 #endif130 100 131 101 } object; … … 135 105 unsigned int length; 136 106 struct _json_value ** values; 137 138 #if defined(__cplusplus) && __cplusplus >= 201103L139 decltype(values) begin () const140 { return values;141 }142 decltype(values) end () const143 { return values + length;144 }145 #endif146 107 147 108 } array; … … 202 163 } 203 164 204 inline operator json_int_t () const 205 { 206 switch (type) 207 { 208 case json_integer: 209 return u.integer; 210 211 case json_double: 212 return (json_int_t) u.dbl; 213 214 default: 215 return 0; 216 }; 165 inline operator long () const 166 { return u.integer; 217 167 } 218 168 219 169 inline operator bool () const 220 { 221 if (type != json_boolean) 222 return false; 223 224 return u.boolean != 0; 225 } 226 227 inline operator double () const 228 { 229 switch (type) 230 { 231 case json_integer: 232 return (double) u.integer; 233 234 case json_double: 235 return u.dbl; 236 237 default: 238 return 0; 239 }; 170 { return u.boolean != 0; 240 171 } 241 172 … … 244 175 } json_value; 245 176 246 json_value * json_parse (const json_char * json,247 size_t length);177 json_value * json_parse 178 (const json_char * json); 248 179 249 #define json_error_max 128 250 json_value * json_parse_ex (json_settings * settings, 251 const json_char * json, 252 size_t length, 253 char * error); 180 json_value * json_parse_ex 181 (json_settings * settings, const json_char * json, char * error); 254 182 255 183 void json_value_free (json_value *); 256 257 258 /* Not usually necessary, unless you used a custom mem_alloc and now want to259 * use a custom mem_free.260 */261 void json_value_free_ex (json_settings * settings,262 json_value *);263 184 264 185 -
lib/oauth2.c
r6ae1056 r820a2a7 154 154 strstr( content_type, "text/javascript" ) ) ) 155 155 { 156 json_value *js = json_parse( req->reply_body , req->body_size);156 json_value *js = json_parse( req->reply_body ); 157 157 if( js && js->type == json_object ) 158 158 { -
protocols/twitter/twitter_lib.c
r6ae1056 r820a2a7 164 164 165 165 if (req->body_size > 0) { 166 root = json_parse(req->reply_body , req->body_size);166 root = json_parse(req->reply_body); 167 167 err = json_o_get(root, "errors"); 168 168 if (err && err->type == json_array && (err = err->u.array.values[0]) && … … 220 220 } 221 221 222 if ((ret = json_parse(req->reply_body , req->body_size)) == NULL) {222 if ((ret = json_parse(req->reply_body)) == NULL) { 223 223 imcb_error(ic, "Could not retrieve %s: %s", 224 224 path, "XML parse error"); … … 263 263 264 264 txl->list = g_slist_prepend(txl->list, 265 g_strdup_printf("% " PRIu64, c->u.array.values[i]->u.integer));265 g_strdup_printf("%lld", c->u.array.values[i]->u.integer)); 266 266 } 267 267 … … 773 773 req->reply_body[len] = '\0'; 774 774 775 if ((parsed = json_parse(req->reply_body , req->body_size))) {775 if ((parsed = json_parse(req->reply_body))) { 776 776 twitter_stream_handle_object(ic, parsed); 777 777 }
Note: See TracChangeset
for help on using the changeset viewer.