| @@ -202,21 +202,21 @@ char* strndup(const char* str, size_t n) | |||
| * json_tokener_parse_ex() consumed a lot of CPU in its main loop, | |||
| * iterating character-by character. A large performance boost is | |||
| * achieved by using tighter loops to locally handle units such as | |||
| * comments and strings. Loops that handle an entire token within | |||
| * their scope also gather entire strings and pass them to | |||
| * comments and strings. Loops that handle an entire token within | |||
| * their scope also gather entire strings and pass them to | |||
| * printbuf_memappend() in a single call, rather than calling | |||
| * printbuf_memappend() one char at a time. | |||
| * | |||
| * POP_CHAR() and ADVANCE_CHAR() macros are used for code that is | |||
| * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is | |||
| * common to both the main loop and the tighter loops. | |||
| */ | |||
| /* POP_CHAR(dest, tok) macro: | |||
| * Not really a pop()...peeks at the current char and stores it in dest. | |||
| /* PEEK_CHAR(dest, tok) macro: | |||
| * Peeks at the current char and stores it in dest. | |||
| * Returns 1 on success, sets tok->err and returns 0 if no more chars. | |||
| * Implicit inputs: str, len vars | |||
| */ | |||
| #define POP_CHAR(dest, tok) \ | |||
| #define PEEK_CHAR(dest, tok) \ | |||
| (((tok)->char_offset == len) ? \ | |||
| (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \ | |||
| (((tok)->err = json_tokener_success), 0) \ | |||
| @@ -225,7 +225,7 @@ char* strndup(const char* str, size_t n) | |||
| ) : \ | |||
| (((dest) = *str), 1) \ | |||
| ) | |||
| /* ADVANCE_CHAR() macro: | |||
| * Incrementes str & tok->char_offset. | |||
| * For convenience of existing conditionals, returns the old value of c (0 on eof) | |||
| @@ -254,7 +254,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| tok->char_offset = 0; | |||
| tok->err = json_tokener_success; | |||
| while (POP_CHAR(c, tok)) { | |||
| while (PEEK_CHAR(c, tok)) { | |||
| redo_char: | |||
| switch(state) { | |||
| @@ -262,7 +262,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| case json_tokener_state_eatws: | |||
| /* Advance until we change state */ | |||
| while (isspace((int)c)) { | |||
| if ((!ADVANCE_CHAR(str, tok)) || (!POP_CHAR(c, tok))) | |||
| if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok))) | |||
| goto out; | |||
| } | |||
| if(c == '/') { | |||
| @@ -373,10 +373,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| /* Advance until we change state */ | |||
| const char *case_start = str; | |||
| while(c != '*') { | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| printbuf_memappend_fast(tok->pb, case_start, str-case_start); | |||
| goto out; | |||
| } | |||
| } | |||
| } | |||
| printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start); | |||
| state = json_tokener_state_comment_end; | |||
| @@ -388,7 +388,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| /* Advance until we change state */ | |||
| const char *case_start = str; | |||
| while(c != '\n') { | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| printbuf_memappend_fast(tok->pb, case_start, str-case_start); | |||
| goto out; | |||
| } | |||
| @@ -426,7 +426,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| state = json_tokener_state_string_escape; | |||
| break; | |||
| } | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| printbuf_memappend_fast(tok->pb, case_start, str-case_start); | |||
| goto out; | |||
| } | |||
| @@ -507,13 +507,17 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| (str[1] == '\\') && | |||
| (str[2] == 'u')) | |||
| { | |||
| ADVANCE_CHAR(str, tok); | |||
| ADVANCE_CHAR(str, tok); | |||
| /* Advance through the 16 bit surrogate, and move on to the | |||
| * next sequence. The next step is to process the following | |||
| * characters. | |||
| */ | |||
| if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) { | |||
| printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3); | |||
| } | |||
| /* Advance to the first char of the next sequence and | |||
| * continue processing with the next sequence. | |||
| */ | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3); | |||
| goto out; | |||
| } | |||
| @@ -552,7 +556,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| tok->err = json_tokener_error_parse_string; | |||
| goto out; | |||
| } | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| if (got_hi_surrogate) /* Clean up any pending chars */ | |||
| printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3); | |||
| goto out; | |||
| @@ -595,7 +599,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| ++case_len; | |||
| if(c == '.' || c == 'e' || c == 'E') | |||
| tok->is_double = 1; | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| printbuf_memappend_fast(tok->pb, case_start, case_len); | |||
| goto out; | |||
| } | |||
| @@ -686,7 +690,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| state = json_tokener_state_string_escape; | |||
| break; | |||
| } | |||
| if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) { | |||
| if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) { | |||
| printbuf_memappend_fast(tok->pb, case_start, str-case_start); | |||
| goto out; | |||
| } | |||
| @@ -752,7 +756,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| if (oldlocale) free(oldlocale); | |||
| #endif | |||
| if (tok->err == json_tokener_success) | |||
| if (tok->err == json_tokener_success) | |||
| { | |||
| json_object *ret = json_object_get(current); | |||
| int ii; | |||