Changeset 7a80925
- Timestamp:
- 2014-02-13T08:48:37Z (11 years ago)
- Branches:
- master
- Children:
- 6ae1056
- Parents:
- e76cf26
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
configure
re76cf26 r7a80925 140 140 DESTDIR= 141 141 LFLAGS= 142 EFLAGS= 142 EFLAGS=-lm 143 143 EOF 144 144 -
lib/json.c
re76cf26 r7a80925 1 2 /* vim: set et ts=3 sw=3 ft=c: 1 /* vim: set et ts=3 sw=3 sts=3 ft=c: 3 2 * 4 * Copyright (C) 2012 James McLaughlin et al. All rights reserved.3 * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. 5 4 * https://github.com/udp/json-parser 6 5 * … … 29 28 */ 30 29 30 #include <glib.h> 31 31 32 #include "json.h" 32 33 … … 43 44 #endif 44 45 45 #include <glib.h>46 #include <stdlib.h>47 46 #include <stdio.h> 48 47 #include <string.h> 49 48 #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 (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') 55 if (isdigit(c)) 62 56 return c - '0'; 63 57 64 return 0xFF; 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 } 65 67 } 66 68 67 69 typedef struct 68 70 { 71 unsigned long used_memory; 72 73 unsigned int uint_max; 74 unsigned long ulong_max; 75 69 76 json_settings settings; 70 77 int first_pass; 71 78 72 unsigned long used_memory;73 74 unsigned int uint_max;75 unsigned long ulong_max;76 77 79 } 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 } 78 90 79 91 static void * json_alloc (json_state * state, unsigned long size, int zero) 80 92 { 81 void * mem;82 83 93 if ((state->ulong_max - state->used_memory) < size) 84 94 return 0; … … 90 100 } 91 101 92 if (! (mem = zero ? calloc (size, 1) : malloc (size))) 93 return 0; 94 95 return mem; 102 return state->settings.mem_alloc (size, zero, state->settings.user_data); 96 103 } 97 104 … … 120 127 } 121 128 129 value->u.array.length = 0; 122 130 break; 123 131 … … 134 142 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; 135 143 144 value->u.object.length = 0; 136 145 break; 137 146 … … 144 153 } 145 154 155 value->u.string.length = 0; 146 156 break; 147 157 … … 150 160 }; 151 161 152 value->u.array.length = 0;153 154 162 return 1; 155 163 } … … 184 192 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0); 185 193 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) 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) 192 215 { 193 json_char error [ 128];216 json_char error [json_error_max]; 194 217 unsigned int cur_line; 195 const json_char * cur_line_begin, * i ;218 const json_char * cur_line_begin, * i, * end; 196 219 json_value * top, * root, * alloc = 0; 197 json_state state; 198 int flags; 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 } 199 234 200 235 error[0] = '\0'; 201 202 memset (&state, 0, sizeof (json_state)); 236 end = (json + length); 237 203 238 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; 204 245 205 246 memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); … … 224 265 for (i = json ;; ++ i) 225 266 { 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 267 json_char b = (i == end ? 0 : *i); 268 244 269 if (flags & flag_string) 245 270 { … … 265 290 case 'u': 266 291 267 if ((uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF 292 if (end - i < 4 || 293 (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF 268 294 || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF) 269 295 { … … 344 370 = (json_char *) top->_reserved.object_mem; 345 371 372 top->u.object.values [top->u.object.length].name_length 373 = string_length; 374 346 375 (*(json_char **) &top->_reserved.object_mem) += string_length + 1; 347 376 } … … 361 390 } 362 391 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 363 469 if (flags & flag_seek_value) 364 470 { … … 372 478 if (top->type == json_array) 373 479 flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; 374 else if (!state.settings.settings & json_relaxed_commas)480 else 375 481 { sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off); 376 482 goto e_failed; … … 438 544 case 't': 439 545 440 if ( *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')546 if ((end - i) < 3 || *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e') 441 547 goto e_unknown_value; 442 548 … … 451 557 case 'f': 452 558 453 if ( *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')559 if ((end - i) < 4 || *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e') 454 560 goto e_unknown_value; 455 561 … … 462 568 case 'n': 463 569 464 if ( *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')570 if ((end - i) < 3 || *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l') 465 571 goto e_unknown_value; 466 572 … … 478 584 goto e_alloc_failure; 479 585 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; 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; 491 620 } 492 621 else … … 510 639 case '"': 511 640 512 if (flags & flag_need_comma && (!state.settings.settings & json_relaxed_commas))641 if (flags & flag_need_comma) 513 642 { 514 643 sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off); … … 548 677 549 678 if (isdigit (b)) 679 { 680 ++ num_digits; 681 682 if (top->type == json_integer || flags & flag_num_e) 683 { 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'); 702 continue; 703 } 704 705 num_fraction = (num_fraction * 10) + (b - '0'); 550 706 continue; 551 552 if (b == 'e' || b == 'E') 553 { 554 if (!(flags & flag_exponent)) 707 } 708 709 if (b == '+' || b == '-') 710 { 711 if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) 555 712 { 556 flags |= flag_exponent; 557 top->type = json_double; 558 559 continue; 560 } 561 } 562 else if (b == '+' || b == '-') 563 { 564 if (flags & flag_exponent && !(flags & flag_got_exponent_sign)) 565 { 566 flags |= flag_got_exponent_sign; 713 flags |= flag_num_e_got_sign; 714 715 if (b == '-') 716 flags |= flag_num_e_negative; 717 567 718 continue; 568 719 } … … 570 721 else if (b == '.' && top->type == json_integer) 571 722 { 723 if (!num_digits) 724 { sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off); 725 goto e_failed; 726 } 727 572 728 top->type = json_double; 729 top->u.dbl = (double) top->u.integer; 730 731 num_digits = 0; 573 732 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 else 764 { 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 else 778 top->u.dbl = - top->u.dbl; 574 779 } 575 780 … … 673 878 { 674 879 top = alloc->_reserved.next_alloc; 675 free (alloc);880 state.settings.mem_free (alloc, state.settings.user_data); 676 881 alloc = top; 677 882 } 678 883 679 884 if (!state.first_pass) 680 json_value_free (root);885 json_value_free_ex (&state.settings, root); 681 886 682 887 return 0; 683 888 } 684 889 685 json_value * json_parse (const json_char * json )890 json_value * json_parse (const json_char * json, size_t length) 686 891 { 687 json_settings settings; 688 memset (&settings, 0, sizeof (json_settings)); 689 690 return json_parse_ex (&settings, json, 0); 892 json_settings settings = { 0 }; 893 return json_parse_ex (&settings, json, length, 0); 691 894 } 692 895 693 void json_value_free (json_value * value)896 void json_value_free_ex (json_settings * settings, json_value * value) 694 897 { 695 898 json_value * cur_value; … … 708 911 if (!value->u.array.length) 709 912 { 710 free (value->u.array.values);913 settings->mem_free (value->u.array.values, settings->user_data); 711 914 break; 712 915 } … … 719 922 if (!value->u.object.length) 720 923 { 721 free (value->u.object.values);924 settings->mem_free (value->u.object.values, settings->user_data); 722 925 break; 723 926 } … … 728 931 case json_string: 729 932 730 free (value->u.string.ptr);933 settings->mem_free (value->u.string.ptr, settings->user_data); 731 934 break; 732 935 … … 737 940 cur_value = value; 738 941 value = value->parent; 739 free (cur_value);942 settings->mem_free (cur_value, settings->user_data); 740 943 } 741 944 } 742 945 743 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 -
lib/json.h
re76cf26 r7a80925 1 1 2 /* vim: set et ts=3 sw=3 ft=c:3 * 4 * Copyright (C) 2012 James McLaughlin et al. All rights reserved.2 /* vim: set et ts=3 sw=3 sts=3 ft=c: 3 * 4 * Copyright (C) 2012, 2013, 2014 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_t 39 #ifndef _MSC_VER 40 #include <inttypes.h> 41 #define json_int_t int64_t 42 #else 43 #define json_int_t __int64 44 #endif 45 #endif 46 47 #include <stdlib.h> 48 38 49 #ifdef __cplusplus 39 50 … … 50 61 int settings; 51 62 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 52 71 } json_settings; 53 72 54 #define json_ relaxed_commas173 #define json_enable_comments 0x01 55 74 56 75 typedef enum … … 78 97 { 79 98 int boolean; 80 long longinteger;99 json_int_t integer; 81 100 double dbl; 82 101 … … 95 114 { 96 115 json_char * name; 116 unsigned int name_length; 117 97 118 struct _json_value * value; 98 119 99 120 } * values; 121 122 #if defined(__cplusplus) && __cplusplus >= 201103L 123 decltype(values) begin () const 124 { return values; 125 } 126 decltype(values) end () const 127 { return values + length; 128 } 129 #endif 100 130 101 131 } object; … … 106 136 struct _json_value ** values; 107 137 138 #if defined(__cplusplus) && __cplusplus >= 201103L 139 decltype(values) begin () const 140 { return values; 141 } 142 decltype(values) end () const 143 { return values + length; 144 } 145 #endif 146 108 147 } array; 109 148 … … 163 202 } 164 203 165 inline operator long () const 166 { return u.integer; 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 }; 167 217 } 168 218 169 219 inline operator bool () const 170 { return u.boolean != 0; 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 }; 171 240 } 172 241 … … 175 244 } json_value; 176 245 177 json_value * json_parse 178 (const json_char * json); 179 180 json_value * json_parse_ex 181 (json_settings * settings, const json_char * json, char * error); 246 json_value * json_parse (const json_char * json, 247 size_t length); 248 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); 182 254 183 255 void json_value_free (json_value *); 256 257 258 /* Not usually necessary, unless you used a custom mem_alloc and now want to 259 * use a custom mem_free. 260 */ 261 void json_value_free_ex (json_settings * settings, 262 json_value *); 184 263 185 264 -
lib/oauth2.c
re76cf26 r7a80925 154 154 strstr( content_type, "text/javascript" ) ) ) 155 155 { 156 json_value *js = json_parse( req->reply_body );156 json_value *js = json_parse( req->reply_body, req->body_size ); 157 157 if( js && js->type == json_object ) 158 158 { -
protocols/twitter/twitter_lib.c
re76cf26 r7a80925 164 164 165 165 if (req->body_size > 0) { 166 root = json_parse(req->reply_body );166 root = json_parse(req->reply_body, req->body_size); 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 )) == NULL) {222 if ((ret = json_parse(req->reply_body, req->body_size)) == 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("% lld", c->u.array.values[i]->u.integer));265 g_strdup_printf("%" PRIu64, 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 ))) {775 if ((parsed = json_parse(req->reply_body, req->body_size))) { 776 776 twitter_stream_handle_object(ic, parsed); 777 777 }
Note: See TracChangeset
for help on using the changeset viewer.