Annotation of parser3/src/lib/json/pa_json.C, revision 1.1
1.1 ! moko 1: /*
! 2: * Copyright (C) 2009 Vincent Hanquez <vincent@snarc.org>
! 3: *
! 4: * This program is free software; you can redistribute it and/or modify
! 5: * it under the terms of the GNU Lesser General Public License as published
! 6: * by the Free Software Foundation; version 2.1 or version 3.0 only.
! 7: *
! 8: * This program is distributed in the hope that it will be useful,
! 9: * but WITHOUT ANY WARRANTY; without even the implied warranty of
! 10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 11: * GNU General Public License for more details.
! 12: */
! 13:
! 14: /*
! 15: * the class, states and state transition tables has been inspired by the JSON_parser.c
! 16: * available at http://json.org, but are quite different on the way that the
! 17: * parser handles its parse buffer and contains significant differences that affect
! 18: * the JSON compliance.
! 19: */
! 20:
! 21: #include "json.h"
! 22:
! 23: #ifdef TRACING_ENABLE
! 24: #include <stdio.h>
! 25: #define TRACING(fmt, ...) fprintf(stderr, "tracing: " fmt, ##__VA_ARGS__)
! 26: #else
! 27: #define TRACING(fmt, ...) ((void) 0)
! 28: #endif
! 29:
! 30: enum classes {
! 31: C_SPACE, /* space */
! 32: C_NL, /* newline */
! 33: C_WHITE, /* tab, CR */
! 34: C_LCURB, C_RCURB, /* object opening/closing */
! 35: C_LSQRB, C_RSQRB, /* array opening/closing */
! 36: /* syntax symbols */
! 37: C_COLON,
! 38: C_COMMA,
! 39: C_QUOTE, /* " */
! 40: C_BACKS, /* \ */
! 41: C_SLASH, /* / */
! 42: C_PLUS,
! 43: C_MINUS,
! 44: C_DOT,
! 45: C_ZERO, C_DIGIT, /* digits */
! 46: C_a, C_b, C_c, C_d, C_e, C_f, C_l, C_n, C_r, C_s, C_t, C_u, /* nocaps letters */
! 47: C_ABCDF, C_E, /* caps letters */
! 48: C_OTHER, /* all other */
! 49: C_STAR, /* star in C style comment */
! 50: C_HASH, /* # for YAML comment */
! 51: C_ERROR = 0xfe,
! 52: };
! 53:
! 54: /* map from character < 128 to classes. from 128 to 256 all C_OTHER */
! 55: static uint8_t character_class[128] = {
! 56: C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR,
! 57: C_ERROR, C_WHITE, C_NL, C_ERROR, C_ERROR, C_WHITE, C_ERROR, C_ERROR,
! 58: C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR,
! 59: C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR,
! 60:
! 61: C_SPACE, C_OTHER, C_QUOTE, C_HASH, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
! 62: C_OTHER, C_OTHER, C_STAR, C_PLUS, C_COMMA, C_MINUS, C_DOT, C_SLASH,
! 63: C_ZERO, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
! 64: C_DIGIT, C_DIGIT, C_COLON, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
! 65:
! 66: C_OTHER, C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E, C_ABCDF, C_OTHER,
! 67: C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
! 68: C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
! 69: C_OTHER, C_OTHER, C_OTHER, C_LSQRB, C_BACKS, C_RSQRB, C_OTHER, C_OTHER,
! 70:
! 71: C_OTHER, C_a, C_b, C_c, C_d, C_e, C_f, C_OTHER,
! 72: C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_l, C_OTHER, C_n, C_OTHER,
! 73: C_OTHER, C_OTHER, C_r, C_s, C_t, C_u, C_OTHER, C_OTHER,
! 74: C_OTHER, C_OTHER, C_OTHER, C_LCURB, C_OTHER, C_RCURB, C_OTHER, C_OTHER
! 75: };
! 76:
! 77: /* only the first 36 ascii characters need an escape */
! 78: static char *character_escape[36] = {
! 79: "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", /* 0-7 */
! 80: "\\b" , "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", /* 8-f */
! 81: "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", /* 10-17 */
! 82: "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", /* 18-1f */
! 83: " " , "!" , "\\\"" , "#",
! 84: };
! 85:
! 86: /* define all states and actions that will be taken on each transition.
! 87: *
! 88: * states are defined first because of the fact they are use as index in the
! 89: * transitions table. they usually contains either a number or a prefix _
! 90: * for simple state like string, object, value ...
! 91: *
! 92: * actions are defined starting from 0x80. state error is defined as 0xff
! 93: */
! 94:
! 95: enum states {
! 96: STATE_GO, /* start */
! 97: STATE_OK, /* ok */
! 98: STATE__O, /* object */
! 99: STATE__K, /* key */
! 100: STATE_CO, /* colon */
! 101: STATE__V, /* value */
! 102: STATE__A, /* array */
! 103: STATE__S, /* string */
! 104: STATE_E0, /* escape */
! 105: STATE_U1, STATE_U2, STATE_U3, STATE_U4, /* unicode states */
! 106: STATE_M0, STATE_Z0, STATE_I0, /* number states */
! 107: STATE_R1, STATE_R2, /* real states (after-dot digits) */
! 108: STATE_X1, STATE_X2, STATE_X3, /* exponant states */
! 109: STATE_T1, STATE_T2, STATE_T3, /* true constant states */
! 110: STATE_F1, STATE_F2, STATE_F3, STATE_F4, /* false constant states */
! 111: STATE_N1, STATE_N2, STATE_N3, /* null constant states */
! 112: STATE_C1, STATE_C2, STATE_C3, /* C-comment states */
! 113: STATE_Y1, /* YAML-comment state */
! 114: STATE_D1, STATE_D2, /* multi unicode states */
! 115: };
! 116:
! 117: /* the following are actions that need to be taken */
! 118: enum actions {
! 119: STATE_KS = 0x80, /* key separator */
! 120: STATE_SP, /* comma separator */
! 121: STATE_AB, /* array begin */
! 122: STATE_AE, /* array ending */
! 123: STATE_OB, /* object begin */
! 124: STATE_OE, /* object end */
! 125: STATE_CB, /* C-comment begin */
! 126: STATE_YB, /* YAML-comment begin */
! 127: STATE_CE, /* YAML/C comment end */
! 128: STATE_FA, /* false */
! 129: STATE_TR, /* true */
! 130: STATE_NU, /* null */
! 131: STATE_DE, /* double detected by exponent */
! 132: STATE_DF, /* double detected by . */
! 133: STATE_SE, /* string end */
! 134: STATE_MX, /* integer detected by minus */
! 135: STATE_ZX, /* integer detected by zero */
! 136: STATE_IX, /* integer detected by 1-9 */
! 137: STATE_UC, /* Unicode character read */
! 138: };
! 139:
! 140: /* error state */
! 141: #define STATE___ 0xff
! 142:
! 143: #define NR_STATES (STATE_D2 + 1)
! 144: #define NR_CLASSES (C_HASH + 1)
! 145:
! 146: #define IS_STATE_ACTION(s) ((s) & 0x80)
! 147: #define S(x) STATE_##x
! 148: #define PT_(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1) \
! 149: { S(a),S(b),S(c),S(d),S(e),S(f),S(g),S(h),S(i),S(j),S(k),S(l),S(m),S(n), \
! 150: S(o),S(p),S(q),S(r),S(s),S(t),S(u),S(v),S(w),S(x),S(y),S(z),S(a1),S(b1), \
! 151: S(c1),S(d1),S(e1),S(f1),S(g1),S(h1) }
! 152:
! 153: /* map from the (previous state+new character class) to the next parser transition */
! 154: static const uint8_t state_transition_table[NR_STATES][NR_CLASSES] = {
! 155: /* white ABCDF other */
! 156: /* sp nl | { } [ ] : , " \ / + - . 0 19 a b c d e f l n r s t u | E | * # */
! 157: /*GO*/ PT_(GO,GO,GO,OB,__,AB,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
! 158: /*OK*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
! 159: /*_O*/ PT_(_O,_O,_O,__,OE,__,__,__,__,_S,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
! 160: /*_K*/ PT_(_K,_K,_K,__,__,__,__,__,__,_S,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
! 161: /*CO*/ PT_(CO,CO,CO,__,__,__,__,KS,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
! 162: /*_V*/ PT_(_V,_V,_V,OB,__,AB,__,__,__,_S,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__,__,YB),
! 163: /*_A*/ PT_(_A,_A,_A,OB,__,AB,AE,__,__,_S,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__,__,YB),
! 164: /****************************************************************************************************************/
! 165: /*_S*/ PT_(_S,__,__,_S,_S,_S,_S,_S,_S,SE,E0,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S),
! 166: /*E0*/ PT_(__,__,__,__,__,__,__,__,__,_S,_S,_S,__,__,__,__,__,__,_S,__,__,__,_S,__,_S,_S,__,_S,U1,__,__,__,__,__),
! 167: /*U1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__,__),
! 168: /*U2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__,__),
! 169: /*U3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__,__,__),
! 170: /*U4*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,UC,UC,UC,UC,UC,UC,UC,UC,__,__,__,__,__,__,UC,UC,__,__,__),
! 171: /****************************************************************************************************************/
! 172: /*M0*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,Z0,I0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 173: /*Z0*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,DF,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
! 174: /*I0*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,DF,I0,I0,__,__,__,__,DE,__,__,__,__,__,__,__,__,DE,__,__,YB),
! 175: /*R1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,R2,R2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 176: /*R2*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,__,R2,R2,__,__,__,__,X1,__,__,__,__,__,__,__,__,X1,__,__,YB),
! 177: /*X1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,X2,X2,__,X3,X3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 178: /*X2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,X3,X3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 179: /*X3*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,__,__,__,__,X3,X3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 180: /****************************************************************************************************************/
! 181: /*T1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__,__,__),
! 182: /*T2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__,__,__),
! 183: /*T3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,TR,__,__,__,__,__,__,__,__,__,__,__,__),
! 184: /*F1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 185: /*F2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__,__,__),
! 186: /*F3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__,__,__),
! 187: /*F4*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,FA,__,__,__,__,__,__,__,__,__,__,__,__),
! 188: /*N1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__,__,__),
! 189: /*N2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__,__,__),
! 190: /*N3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,NU,__,__,__,__,__,__,__,__,__,__),
! 191: /****************************************************************************************************************/
! 192: /*C1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,C2,__),
! 193: /*C2*/ PT_(C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3,C2),
! 194: /*C3*/ PT_(C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,CE,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3,C2),
! 195: /*Y1*/ PT_(Y1,CE,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1),
! 196: /*D1*/ PT_(__,__,__,__,__,__,__,__,__,__,D2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
! 197: /*D2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U1,__,__,__,__,__),
! 198: };
! 199: #undef S
! 200: #undef PT_
! 201:
! 202: /* map from (previous state+new character class) to the buffer policy. ignore=0/append=1/escape=2 */
! 203: static const uint8_t buffer_policy_table[NR_STATES][NR_CLASSES] = {
! 204: /* white ABCDF other */
! 205: /* sp nl | { } [ ] : , " \ / + - . 0 19 a b c d e f l n r s t u | E | * # */
! 206: /*GO*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 207: /*OK*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 208: /*_O*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 209: /*_K*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 210: /*CO*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 211: /*_V*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 212: /*_A*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 213: /**************************************************************************************************************/
! 214: /*_S*/ { 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
! 215: /*E0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0 },
! 216: /*U1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
! 217: /*U2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
! 218: /*U3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
! 219: /*U4*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
! 220: /**************************************************************************************************************/
! 221: /*M0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 222: /*Z0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 223: /*I0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
! 224: /*R1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 225: /*R2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
! 226: /*X1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 227: /*X2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 228: /*X3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 229: /**************************************************************************************************************/
! 230: /*T1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 231: /*T2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 232: /*T3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 233: /*F1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 234: /*F2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 235: /*F3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 236: /*F4*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 237: /*N1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 238: /*N2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 239: /*N3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 240: /**************************************************************************************************************/
! 241: /*C1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 242: /*C2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 243: /*C3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 244: /*Y1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 245: /*D1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 246: /*D2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
! 247: };
! 248:
! 249: #define MODE_ARRAY 0
! 250: #define MODE_OBJECT 1
! 251:
! 252: #define parser_malloc(parser, s) parser->config.user_malloc(s)
! 253: #define parser_realloc(parser, p, s) parser->config.user_realloc(p, s)
! 254: #define parser_free(parser, p) parser->config.user_free(p)
! 255:
! 256: static int state_grow(json_parser *parser)
! 257: {
! 258: uint32_t newsize = parser->stack_size * 2;
! 259: void *ptr;
! 260:
! 261: if (parser->config.max_nesting != 0)
! 262: return JSON_ERROR_NESTING_LIMIT;
! 263:
! 264: ptr = parser_realloc(parser, parser->stack, newsize * sizeof(uint8_t));
! 265: if (!ptr)
! 266: return JSON_ERROR_NO_MEMORY;
! 267: parser->stack = ptr;
! 268: parser->stack_size = newsize;
! 269: return 0;
! 270: }
! 271:
! 272: static int state_push(json_parser *parser, int mode)
! 273: {
! 274: if (parser->stack_offset >= parser->stack_size) {
! 275: int ret = state_grow(parser);
! 276: if (ret)
! 277: return ret;
! 278: }
! 279: parser->stack[parser->stack_offset++] = mode;
! 280: return 0;
! 281: }
! 282:
! 283: static int state_pop(json_parser *parser, int mode)
! 284: {
! 285: if (parser->stack_offset == 0)
! 286: return JSON_ERROR_POP_EMPTY;
! 287: parser->stack_offset--;
! 288: if (parser->stack[parser->stack_offset] != mode)
! 289: return JSON_ERROR_POP_UNEXPECTED_MODE;
! 290: return 0;
! 291: }
! 292:
! 293: static int buffer_grow(json_parser *parser)
! 294: {
! 295: uint32_t newsize;
! 296: void *ptr;
! 297: int max = parser->config.max_data;
! 298:
! 299: if (max > 0 && parser->buffer_size == max)
! 300: return JSON_ERROR_DATA_LIMIT;
! 301: newsize = parser->buffer_size * 2;
! 302: if (max > 0 && newsize > max)
! 303: newsize = max;
! 304:
! 305: ptr = parser_realloc(parser, parser->buffer, newsize * sizeof(char));
! 306: if (!ptr)
! 307: return JSON_ERROR_NO_MEMORY;
! 308: parser->buffer = ptr;
! 309: parser->buffer_size = newsize;
! 310: return 0;
! 311: }
! 312:
! 313: static int buffer_push(json_parser *parser, unsigned char c)
! 314: {
! 315: int ret;
! 316:
! 317: if (parser->buffer_offset + 1 >= parser->buffer_size) {
! 318: ret = buffer_grow(parser);
! 319: if (ret)
! 320: return ret;
! 321: }
! 322: parser->buffer[parser->buffer_offset++] = c;
! 323: return 0;
! 324: }
! 325:
! 326: static int do_callback_withbuf(json_parser *parser, int type)
! 327: {
! 328: if (!parser->callback)
! 329: return 0;
! 330: parser->buffer[parser->buffer_offset] = '\0';
! 331: return (*parser->callback)(parser->userdata, type, parser->buffer, parser->buffer_offset);
! 332: }
! 333:
! 334: static int do_callback(json_parser *parser, int type)
! 335: {
! 336: if (!parser->callback)
! 337: return 0;
! 338: return (*parser->callback)(parser->userdata, type, NULL, 0);
! 339: }
! 340:
! 341: static int do_buffer(json_parser *parser)
! 342: {
! 343: int ret = 0;
! 344:
! 345: switch (parser->type) {
! 346: case JSON_KEY: case JSON_STRING:
! 347: case JSON_FLOAT: case JSON_INT:
! 348: case JSON_NULL: case JSON_TRUE: case JSON_FALSE:
! 349: ret = do_callback_withbuf(parser, parser->type);
! 350: if (ret)
! 351: return ret;
! 352: break;
! 353: default:
! 354: break;
! 355: }
! 356: parser->buffer_offset = 0;
! 357: return ret;
! 358: }
! 359:
! 360: static const uint8_t hextable[] = {
! 361: -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 362: -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 363: -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 364: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
! 365: -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 366: -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 367: -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 368: -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
! 369: };
! 370:
! 371: #define hex(c) (hextable[(uint8_t) c])
! 372:
! 373: /* high surrogate range from d800 to dbff */
! 374: /* low surrogate range dc00 to dfff */
! 375: #define IS_HIGH_SURROGATE(uc) (((uc) & 0xfc00) == 0xd800)
! 376: #define IS_LOW_SURROGATE(uc) (((uc) & 0xfc00) == 0xdc00)
! 377:
! 378: /* transform an unicode [0-9A-Fa-f]{4} sequence into a proper value */
! 379: static int decode_unicode_char(json_parser *parser)
! 380: {
! 381: uint32_t uval;
! 382: char *b = parser->buffer;
! 383: int offset = parser->buffer_offset;
! 384:
! 385: uval = (hex(b[offset - 4]) << 12) | (hex(b[offset - 3]) << 8)
! 386: | (hex(b[offset - 2]) << 4) | hex(b[offset - 1]);
! 387:
! 388: parser->buffer_offset -= 4;
! 389:
! 390: /* fast case */
! 391: if (!parser->unicode_multi && uval < 0x80) {
! 392: b[parser->buffer_offset++] = (char) uval;
! 393: return 0;
! 394: }
! 395:
! 396: if (parser->unicode_multi) {
! 397: if (!IS_LOW_SURROGATE(uval))
! 398: return JSON_ERROR_UNICODE_MISSING_LOW_SURROGATE;
! 399:
! 400: uval = 0x10000 + ((parser->unicode_multi & 0x3ff) << 10) + (uval & 0x3ff);
! 401: b[parser->buffer_offset++] = (char) ((uval >> 18) | 0xf0);
! 402: b[parser->buffer_offset++] = (char) (((uval >> 12) & 0x3f) | 0x80);
! 403: b[parser->buffer_offset++] = (char) (((uval >> 6) & 0x3f) | 0x80);
! 404: b[parser->buffer_offset++] = (char) ((uval & 0x3f) | 0x80);
! 405: parser->unicode_multi = 0;
! 406: return 0;
! 407: }
! 408:
! 409: if (IS_LOW_SURROGATE(uval))
! 410: return JSON_ERROR_UNICODE_UNEXPECTED_LOW_SURROGATE;
! 411: if (IS_HIGH_SURROGATE(uval)) {
! 412: parser->unicode_multi = uval;
! 413: return 0;
! 414: }
! 415:
! 416: if (uval < 0x800) {
! 417: b[parser->buffer_offset++] = (char) ((uval >> 6) | 0xc0);
! 418: b[parser->buffer_offset++] = (char) ((uval & 0x3f) | 0x80);
! 419: } else {
! 420: b[parser->buffer_offset++] = (char) ((uval >> 12) | 0xe0);
! 421: b[parser->buffer_offset++] = (char) (((uval >> 6) & 0x3f) | 0x80);
! 422: b[parser->buffer_offset++] = (char) (((uval >> 0) & 0x3f) | 0x80);
! 423: }
! 424: return 0;
! 425: }
! 426:
! 427: static int buffer_push_escape(json_parser *parser, unsigned char next)
! 428: {
! 429: char c = '\0';
! 430:
! 431: switch (next) {
! 432: case 'b': c = '\b'; break;
! 433: case 'f': c = '\f'; break;
! 434: case 'n': c = '\n'; break;
! 435: case 'r': c = '\r'; break;
! 436: case 't': c = '\t'; break;
! 437: case '"': c = '"'; break;
! 438: case '/': c = '/'; break;
! 439: case '\\': c = '\\'; break;
! 440: }
! 441: /* push the escaped character */
! 442: return buffer_push(parser, c);
! 443: }
! 444:
! 445: #define CHK(f) ({ ret = f; if (ret) return ret; })
! 446:
! 447: int act_uc(json_parser *parser)
! 448: {
! 449: int ret;
! 450: CHK(decode_unicode_char(parser));
! 451: parser->state = (parser->unicode_multi) ? STATE_D1 : STATE__S;
! 452: return 0;
! 453: }
! 454:
! 455: int act_yb(json_parser *parser)
! 456: {
! 457: if (!parser->config.allow_yaml_comments)
! 458: return JSON_ERROR_COMMENT_NOT_ALLOWED;
! 459: parser->save_state = parser->state;
! 460: return 0;
! 461: }
! 462:
! 463: int act_cb(json_parser *parser)
! 464: {
! 465: if (!parser->config.allow_c_comments)
! 466: return JSON_ERROR_COMMENT_NOT_ALLOWED;
! 467: parser->save_state = parser->state;
! 468: return 0;
! 469: }
! 470:
! 471: int act_ce(json_parser *parser)
! 472: {
! 473: parser->state = (parser->save_state > STATE__A) ? STATE_OK : parser->save_state;
! 474: return 0;
! 475: }
! 476:
! 477: int act_ob(json_parser *parser)
! 478: {
! 479: int ret;
! 480: CHK(do_callback(parser, JSON_OBJECT_BEGIN));
! 481: CHK(state_push(parser, MODE_OBJECT));
! 482: parser->expecting_key = 1;
! 483: return 0;
! 484: }
! 485:
! 486: int act_oe(json_parser *parser)
! 487: {
! 488: int ret;
! 489: CHK(do_callback(parser, JSON_OBJECT_END));
! 490: CHK(state_pop(parser, MODE_OBJECT));
! 491: parser->expecting_key = 0;
! 492: return 0;
! 493: }
! 494:
! 495: int act_ab(json_parser *parser)
! 496: {
! 497: int ret;
! 498: CHK(do_callback(parser, JSON_ARRAY_BEGIN));
! 499: CHK(state_push(parser, MODE_ARRAY));
! 500: return 0;
! 501: }
! 502: int act_ae(json_parser *parser)
! 503: {
! 504: int ret;
! 505: CHK(do_callback(parser, JSON_ARRAY_END));
! 506: CHK(state_pop(parser, MODE_ARRAY));
! 507: return 0;
! 508: }
! 509:
! 510: int act_se(json_parser *parser)
! 511: {
! 512: int ret;
! 513: CHK(do_callback_withbuf(parser, (parser->expecting_key) ? JSON_KEY : JSON_STRING));
! 514: parser->buffer_offset = 0;
! 515: parser->state = (parser->expecting_key) ? STATE_CO : STATE_OK;
! 516: parser->expecting_key = 0;
! 517: return 0;
! 518: }
! 519:
! 520: int act_sp(json_parser *parser)
! 521: {
! 522: if (parser->stack_offset == 0)
! 523: return JSON_ERROR_COMMA_OUT_OF_STRUCTURE;
! 524: if (parser->stack[parser->stack_offset - 1] == MODE_OBJECT) {
! 525: parser->expecting_key = 1;
! 526: parser->state = STATE__K;
! 527: } else
! 528: parser->state = STATE__V;
! 529: return 0;
! 530: }
! 531:
! 532: struct action_descr
! 533: {
! 534: int (*call)(json_parser *parser);
! 535: uint8_t type;
! 536: uint8_t state; /* 0 if we let the callback set the value it want */
! 537: uint8_t dobuffer;
! 538: };
! 539:
! 540: static struct action_descr actions_map[] = {
! 541: [STATE_MX & ~0x80] = { NULL, JSON_INT, STATE_M0, 0 },
! 542: [STATE_ZX & ~0x80] = { NULL, JSON_INT, STATE_Z0, 0 },
! 543: [STATE_IX & ~0x80] = { NULL, JSON_INT, STATE_I0, 0 },
! 544: [STATE_DE & ~0x80] = { NULL, JSON_FLOAT, STATE_X1, 0 },
! 545: [STATE_DF & ~0x80] = { NULL, JSON_FLOAT, STATE_R1, 0 },
! 546: [STATE_NU & ~0x80] = { NULL, JSON_NULL, STATE_OK, 0 },
! 547: [STATE_FA & ~0x80] = { NULL, JSON_FALSE, STATE_OK, 0 },
! 548: [STATE_TR & ~0x80] = { NULL, JSON_TRUE, STATE_OK, 0 },
! 549: [STATE_KS & ~0x80] = { NULL, JSON_NONE, STATE__V, 0 },
! 550: [STATE_UC & ~0x80] = { act_uc, JSON_NONE, 0, 0 },
! 551: [STATE_YB & ~0x80] = { act_yb, JSON_NONE, STATE_Y1, 1 },
! 552: [STATE_CB & ~0x80] = { act_cb, JSON_NONE, STATE_C1, 1 },
! 553: [STATE_CE & ~0x80] = { act_ce, JSON_NONE, 0, 0 },
! 554: [STATE_OB & ~0x80] = { act_ob, JSON_NONE, STATE__O, 0 },
! 555: [STATE_OE & ~0x80] = { act_oe, JSON_NONE, STATE_OK, 1 },
! 556: [STATE_AB & ~0x80] = { act_ab, JSON_NONE, STATE__A, 0 },
! 557: [STATE_AE & ~0x80] = { act_ae, JSON_NONE, STATE_OK, 1 },
! 558: [STATE_SE & ~0x80] = { act_se, JSON_NONE, 0, 0 },
! 559: [STATE_SP & ~0x80] = { act_sp, JSON_NONE, 0, 1 },
! 560: };
! 561:
! 562: static int do_action(json_parser *parser, int next_state)
! 563: {
! 564: struct action_descr *descr = &actions_map[next_state & ~0x80];
! 565:
! 566: if (descr->call) {
! 567: int ret;
! 568: if (descr->dobuffer)
! 569: CHK(do_buffer(parser));
! 570: CHK((descr->call)(parser));
! 571: }
! 572: if (descr->state)
! 573: parser->state = descr->state;
! 574: parser->type = descr->type;
! 575: return 0;
! 576: }
! 577:
! 578: /** json_parser_init initialize a parser structure taking a config,
! 579: * a config and its userdata.
! 580: * return JSON_ERROR_NO_MEMORY if memory allocation failed or SUCCESS.
! 581: */
! 582: int json_parser_init(json_parser *parser, json_config *config,
! 583: json_parser_callback callback, void *userdata)
! 584: {
! 585: memset(parser, 0, sizeof(*parser));
! 586:
! 587: if (config)
! 588: memcpy(&parser->config, config, sizeof(json_config));
! 589: parser->callback = callback;
! 590: parser->userdata = userdata;
! 591:
! 592: /* initialise parsing stack and state */
! 593: parser->stack_offset = 0;
! 594: parser->state = STATE_GO;
! 595:
! 596: /* initialize the parse stack */
! 597: parser->stack_size = (parser->config.max_nesting > 0)
! 598: ? parser->config.max_nesting
! 599: : LIBJSON_DEFAULT_STACK_SIZE;
! 600:
! 601: parser->stack = parser_malloc(parser, parser->stack_size * sizeof(parser->stack[0]));
! 602: if (!parser->stack)
! 603: return JSON_ERROR_NO_MEMORY;
! 604:
! 605: /* initialize the parse buffer */
! 606: parser->buffer_size = (parser->config.buffer_initial_size > 0)
! 607: ? parser->config.buffer_initial_size
! 608: : LIBJSON_DEFAULT_BUFFER_SIZE;
! 609:
! 610: if (parser->config.max_data > 0 && parser->buffer_size > parser->config.max_data)
! 611: parser->buffer_size = parser->config.max_data;
! 612:
! 613: parser->buffer = parser_malloc(parser, parser->buffer_size * sizeof(char));
! 614: if (!parser->buffer) {
! 615: parser_free(parser, parser->stack);
! 616: return JSON_ERROR_NO_MEMORY;
! 617: }
! 618: return 0;
! 619: }
! 620:
! 621: /** json_parser_free freed memory structure allocated by the parser */
! 622: int json_parser_free(json_parser *parser)
! 623: {
! 624: if (!parser)
! 625: return 0;
! 626: parser_free(parser, parser->stack);
! 627: parser_free(parser, parser->buffer);
! 628: parser->stack = NULL;
! 629: parser->buffer = NULL;
! 630: return 0;
! 631: }
! 632:
! 633: /** json_parser_is_done return 0 is the parser isn't in a finish state. !0 if it is */
! 634: int json_parser_is_done(json_parser *parser)
! 635: {
! 636: /* need to compare the state to !GO to not accept empty document */
! 637: return parser->stack_offset == 0 && parser->state != STATE_GO;
! 638: }
! 639:
! 640: /** json_parser_string append a string s with a specific length to the parser
! 641: * return 0 if everything went ok, a JSON_ERROR_* otherwise.
! 642: * the user can supplied a valid processed pointer that will
! 643: * be fill with the number of processed characters before returning */
! 644: int json_parser_string(json_parser *parser, const char *s,
! 645: uint32_t length, uint32_t *processed)
! 646: {
! 647: int ret;
! 648: int next_class, next_state;
! 649: int buffer_policy;
! 650: uint32_t i;
! 651:
! 652: ret = 0;
! 653: for (i = 0; i < length; i++) {
! 654: unsigned char ch = s[i];
! 655:
! 656: ret = 0;
! 657: next_class = (ch >= 128) ? C_OTHER : character_class[ch];
! 658: if (next_class == C_ERROR) {
! 659: ret = JSON_ERROR_BAD_CHAR;
! 660: break;
! 661: }
! 662:
! 663: next_state = state_transition_table[parser->state][next_class];
! 664: buffer_policy = buffer_policy_table[parser->state][next_class];
! 665: TRACING("addchar %d (current-state=%d, next-state=%d, buf-policy=%d)\n",
! 666: ch, parser->state, next_state, buffer_policy);
! 667: if (next_state == STATE___) {
! 668: ret = JSON_ERROR_UNEXPECTED_CHAR;
! 669: break;
! 670: }
! 671:
! 672: /* add char to buffer */
! 673: if (buffer_policy) {
! 674: ret = (buffer_policy == 2)
! 675: ? buffer_push_escape(parser, ch)
! 676: : buffer_push(parser, ch);
! 677: if (ret)
! 678: break;
! 679: }
! 680:
! 681: /* move to the next level */
! 682: if (IS_STATE_ACTION(next_state))
! 683: ret = do_action(parser, next_state);
! 684: else
! 685: parser->state = next_state;
! 686: if (ret)
! 687: break;
! 688: }
! 689: if (processed)
! 690: *processed = i;
! 691: return ret;
! 692: }
! 693:
! 694: /** json_parser_char append one single char to the parser
! 695: * return 0 if everything went ok, a JSON_ERROR_* otherwise */
! 696: int json_parser_char(json_parser *parser, unsigned char ch)
! 697: {
! 698: return json_parser_string(parser, (char *) &ch, 1, NULL);
! 699: }
E-mail: