aboutsummaryrefslogtreecommitdiff
path: root/src/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/json.c')
-rw-r--r--src/json.c120
1 files changed, 88 insertions, 32 deletions
diff --git a/src/json.c b/src/json.c
index 58f89b1aa..63feff948 100644
--- a/src/json.c
+++ b/src/json.c
@@ -912,10 +912,9 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
int x;
JsonNode *pNode;
const char *z = pParse->zJson;
- while( fast_isspace(z[i]) ){ i++; }
json_parse_restart:
- c = z[i];
- if( c=='{' ){
+ switch( (u8)z[i] ){
+ case '{': {
/* Parse object */
iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
if( iThis<0 ) return -1;
@@ -951,7 +950,8 @@ json_parse_restart:
}
pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
return j+1;
- }else if( c=='[' ){
+ }
+ case '[': {
/* Parse array */
iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
if( iThis<0 ) return -1;
@@ -977,7 +977,8 @@ json_parse_restart:
}
pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
return j+1;
- }else if( c=='"' ){
+ }
+ case '"': {
/* Parse string */
u8 jnFlags = 0;
j = i+1;
@@ -1004,32 +1005,61 @@ json_parse_restart:
jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
return j+1;
- }else if( c=='n'
- && strncmp(z+i,"null",4)==0
- && !sqlite3Isalnum(z[i+4]) ){
- jsonParseAddNode(pParse, JSON_NULL, 0, 0);
- return i+4;
- }else if( c=='t'
- && strncmp(z+i,"true",4)==0
- && !sqlite3Isalnum(z[i+4]) ){
- jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
- return i+4;
- }else if( c=='f'
- && strncmp(z+i,"false",5)==0
- && !sqlite3Isalnum(z[i+5]) ){
- jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
- return i+5;
- }else if( c=='-' || (c>='0' && c<='9') ){
+ }
+ case 'n': {
+ if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
+ jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+ return i+4;
+ }
+ return -1;
+ }
+ case 't': {
+ if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){
+ jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+ return i+4;
+ }
+ return -1;
+ }
+ case 'f': {
+ if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){
+ jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
+ return i+5;
+ }
+ return -1;
+ }
+ case '+':
+ pParse->has5 = 1;
+ /* fall through */
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
/* Parse number */
u8 seenDP = 0;
u8 seenE = 0;
assert( '-' < '0' );
+ assert( '+' < '0' );
+ assert( '.' < '0' );
+ c = z[i];
+
if( c<='0' ){
- j = c=='-' ? i+1 : i;
- if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
+ if( c=='0' ){
+ if( sqlite3Isdigit(z[i+1]) ){
+ pParse->has5 = 1;
+ }
+ }else{
+ if( !sqlite3Isdigit(z[i+1]) ) return -1;
+ if( z[i+1]=='0' && sqlite3Isdigit(z[i+2]) ) pParse->has5 = 1;
+ }
}
- j = i+1;
- for(;; j++){
+ for(j=i+1;; j++){
c = z[j];
if( c>='0' && c<='9' ) continue;
if( c=='.' ){
@@ -1074,19 +1104,44 @@ json_parse_restart:
jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
j - i, &z[i]);
return j;
- }else if( c=='}' ){
+ }
+ case '}': {
return -2; /* End of {...} */
- }else if( c==']' ){
+ }
+ case ']': {
return -3; /* End of [...] */
- }else if( c==0 ){
+ }
+ case 0: {
return 0; /* End of file */
- }else if( (j = json5Whitespace(&z[i]))>0 ){
- i += j;
- pParse->has5 = 1;
+ }
+ case 0x09:
+ case 0x0a:
+ case 0x0d:
+ case 0x20: {
+ do{
+ i++;
+ }while( fast_isspace(z[i]) );
goto json_parse_restart;
- }else{
+ }
+ case 0x0b:
+ case 0x0c:
+ case '/':
+ case 0xc2:
+ case 0xe1:
+ case 0xe2:
+ case 0xe3: {
+ j = json5Whitespace(&z[i]);
+ if( j>0 ){
+ i += j;
+ pParse->has5 = 1;
+ goto json_parse_restart;
+ }
+ return -1;
+ }
+ default: {
#ifdef SQLITE_ENABLE_JSON_NAN_INF
int k, nn;
+ c = z[i];
for(k=0; k<sizeof(aNanInfName)/sizeof(aNanInfName[0]); k++){
if( c!=aNanInfName[k].c1 && c!=aNanInfName[k].c2 ) continue;
nn = aNanInfName[k].n;
@@ -1101,6 +1156,7 @@ json_parse_restart:
#endif
return -1; /* Syntax error */
}
+ } /* End switch(z[i]) */
}
/*