PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - json - JSON_parser.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 238
Code covered: 95.4 % Executed lines: 227
Legend: not executed executed

       1                 : /* JSON_parser.c */
       2                 : 
       3                 : /* 2005-12-30 */
       4                 : 
       5                 : /*
       6                 : Copyright (c) 2005 JSON.org
       7                 : 
       8                 : Permission is hereby granted, free of charge, to any person obtaining a copy
       9                 : of this software and associated documentation files (the "Software"), to deal
      10                 : in the Software without restriction, including without limitation the rights
      11                 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12                 : copies of the Software, and to permit persons to whom the Software is
      13                 : furnished to do so, subject to the following conditions:
      14                 : 
      15                 : The above copyright notice and this permission notice shall be included in all
      16                 : copies or substantial portions of the Software.
      17                 : 
      18                 : The Software shall be used for Good, not Evil.
      19                 : 
      20                 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      21                 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22                 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      23                 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24                 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      25                 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      26                 : SOFTWARE.
      27                 : */
      28                 : 
      29                 : 
      30                 : #include "JSON_parser.h"
      31                 : #include <stdio.h>
      32                 : 
      33                 : #define true  1
      34                 : #define false 0
      35                 : 
      36                 : /*
      37                 :     Characters are mapped into these 32 symbol classes. This allows for
      38                 :     significant reductions in the size of the state transition table.
      39                 : */
      40                 : 
      41                 : /* error */
      42                 : #define S_ERR -1
      43                 : 
      44                 : /* space */
      45                 : #define S_SPA 0
      46                 : 
      47                 : /* other whitespace */
      48                 : #define S_WSP 1
      49                 : 
      50                 : /* {  */
      51                 : #define S_LBE 2
      52                 : 
      53                 : /* } */
      54                 : #define S_RBE 3
      55                 : 
      56                 : /* [ */
      57                 : #define S_LBT 4
      58                 : 
      59                 : /* ] */
      60                 : #define S_RBT 5
      61                 : 
      62                 : /* : */
      63                 : #define S_COL 6
      64                 : 
      65                 : /* , */
      66                 : #define S_COM 7
      67                 : 
      68                 : /* " */
      69                 : #define S_QUO 8
      70                 : 
      71                 : /* \ */
      72                 : #define S_BAC 9
      73                 : 
      74                 : /* / */
      75                 : #define S_SLA 10
      76                 : 
      77                 : /* + */
      78                 : #define S_PLU 11
      79                 : 
      80                 : /* - */
      81                 : #define S_MIN 12
      82                 : 
      83                 : /* . */
      84                 : #define S_DOT 13
      85                 : 
      86                 : /* 0 */
      87                 : #define S_ZER 14
      88                 : 
      89                 : /* 123456789 */
      90                 : #define S_DIG 15
      91                 : 
      92                 : /* a */
      93                 : #define S__A_ 16
      94                 : 
      95                 : /* b */
      96                 : #define S__B_ 17
      97                 : 
      98                 : /* c */
      99                 : #define S__C_ 18
     100                 : 
     101                 : /* d */
     102                 : #define S__D_ 19
     103                 : 
     104                 : /* e */
     105                 : #define S__E_ 20
     106                 : 
     107                 : /* f */
     108                 : #define S__F_ 21
     109                 : 
     110                 : /* l */
     111                 : #define S__L_ 22
     112                 : 
     113                 : /* n */
     114                 : #define S__N_ 23
     115                 : 
     116                 : /* r */
     117                 : #define S__R_ 24
     118                 : 
     119                 : /* s */
     120                 : #define S__S_ 25
     121                 : 
     122                 : /* t */
     123                 : #define S__T_ 26
     124                 : 
     125                 : /* u */
     126                 : #define S__U_ 27
     127                 : 
     128                 : /* ABCDF */
     129                 : #define S_A_F 28
     130                 : 
     131                 : /* E */
     132                 : #define S_E   29
     133                 : 
     134                 : /* everything else */
     135                 : #define S_ETC 30
     136                 : 
     137                 : 
     138                 : /*
     139                 :     This table maps the 128 ASCII characters into the 32 character classes.
     140                 :     The remaining Unicode characters should be mapped to S_ETC.
     141                 : */
     142                 : static const int ascii_class[128] = {
     143                 :     S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
     144                 :     S_ERR, S_WSP, S_WSP, S_ERR, S_ERR, S_WSP, S_ERR, S_ERR,
     145                 :     S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
     146                 :     S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
     147                 : 
     148                 :     S_SPA, S_ETC, S_QUO, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
     149                 :     S_ETC, S_ETC, S_ETC, S_PLU, S_COM, S_MIN, S_DOT, S_SLA,
     150                 :     S_ZER, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG,
     151                 :     S_DIG, S_DIG, S_COL, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
     152                 : 
     153                 :     S_ETC, S_A_F, S_A_F, S_A_F, S_A_F, S_E  , S_A_F, S_ETC,
     154                 :     S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
     155                 :     S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
     156                 :     S_ETC, S_ETC, S_ETC, S_LBT, S_BAC, S_RBT, S_ETC, S_ETC,
     157                 : 
     158                 :     S_ETC, S__A_, S__B_, S__C_, S__D_, S__E_, S__F_, S_ETC,
     159                 :     S_ETC, S_ETC, S_ETC, S_ETC, S__L_, S_ETC, S__N_, S_ETC,
     160                 :     S_ETC, S_ETC, S__R_, S__S_, S__T_, S__U_, S_ETC, S_ETC,
     161                 :     S_ETC, S_ETC, S_ETC, S_LBE, S_ETC, S_RBE, S_ETC, S_ETC
     162                 : };
     163                 : 
     164                 : 
     165                 : /*
     166                 :     The state transition table takes the current state and the current symbol,
     167                 :     and returns either a new state or an action. A new state is a number between
     168                 :     0 and 29. An action is a negative number between -1 and -9. A JSON text is
     169                 :     accepted if the end of the text is in state 9 and mode is MODE_DONE.
     170                 : */
     171                 : static const int state_transition_table[30][31] = {
     172                 : /* 0*/ { 0, 0,-8,-1,-6,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     173                 : /* 1*/ { 1, 1,-1,-9,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     174                 : /* 2*/ { 2, 2,-8,-1,-6,-5,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1},
     175                 : /* 3*/ { 3,-1, 3, 3, 3, 3, 3, 3,-4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
     176                 : /* 4*/ {-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1, 3,-1, 3, 3,-1, 3, 5,-1,-1,-1},
     177                 : /* 5*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 6, 6, 6, 6, 6, 6, 6, 6,-1,-1,-1,-1,-1,-1, 6, 6,-1},
     178                 : /* 6*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 7, 7, 7, 7, 7, 7, 7, 7,-1,-1,-1,-1,-1,-1, 7, 7,-1},
     179                 : /* 7*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 8, 8, 8, 8, 8, 8, 8, 8,-1,-1,-1,-1,-1,-1, 8, 8,-1},
     180                 : /* 8*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3, 3,-1},
     181                 : /* 9*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     182                 : /*10*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1},
     183                 : /*11*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1},
     184                 : /*12*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     185                 : /*13*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     186                 : /*14*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,-1,-1,-1,-1,-1,-1,-1,-1},
     187                 : /*15*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,-1,-1},
     188                 : /*16*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     189                 : /*17*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,18,-1,-1,-1},
     190                 : /*18*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,-1,-1,-1,-1,-1,-1,-1,-1},
     191                 : /*19*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1},
     192                 : /*20*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     193                 : /*21*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     194                 : /*22*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,22,22,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1},
     195                 : /*23*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,23,23,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1},
     196                 : /*24*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,25,25,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     197                 : /*25*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     198                 : /*26*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     199                 : /*27*/ {27,27,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
     200                 : /*28*/ {28,28,-8,-1,-6,-1,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1},
     201                 : /*29*/ {29,29,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
     202                 : };
     203                 : 
     204                 : #define JSON_PARSER_MAX_DEPTH 512
     205                 : 
     206                 : 
     207                 : /*
     208                 :    A stack maintains the states of nested structures.
     209                 : */
     210                 : 
     211                 : typedef struct json_parser
     212                 : {
     213                 :     int the_stack[JSON_PARSER_MAX_DEPTH];
     214                 :     zval *the_zstack[JSON_PARSER_MAX_DEPTH];
     215                 :     int the_top;
     216                 : } json_parser;
     217                 : 
     218                 : 
     219                 : /*
     220                 :     These modes can be pushed on the PDA stack.
     221                 : */
     222                 : #define MODE_DONE   1
     223                 : #define MODE_KEY    2
     224                 : #define MODE_OBJECT 3
     225                 : #define MODE_ARRAY  4
     226                 : 
     227                 : /*
     228                 :     Push a mode onto the stack. Return false if there is overflow.
     229                 : */
     230                 : static int
     231                 : push(json_parser *json, zval *z, int mode)
     232            2064 : {
     233            2064 :     json->the_top += 1;
     234            2064 :     if (json->the_top >= JSON_PARSER_MAX_DEPTH) {
     235               2 :         return false;
     236                 :     }
     237                 : 
     238            2062 :     json->the_stack[json->the_top] = mode;
     239            2062 :     return true;
     240                 : }
     241                 : 
     242                 : 
     243                 : /*
     244                 :     Pop the stack, assuring that the current mode matches the expectation.
     245                 :     Return false if there is underflow or if the modes mismatch.
     246                 : */
     247                 : static int
     248                 : pop(json_parser *json, zval *z, int mode)
     249             925 : {
     250             925 :     if (json->the_top < 0 || json->the_stack[json->the_top] != mode) {
     251               5 :         return false;
     252                 :     }
     253             920 :     json->the_stack[json->the_top] = 0;
     254             920 :     json->the_top -= 1;
     255                 : 
     256             920 :     return true;
     257                 : }
     258                 : 
     259                 : 
     260                 : static int dehexchar(char c)
     261             600 : {
     262             600 :     if (c >= '0' && c <= '9')
     263                 :     {
     264             261 :         return c - '0';
     265                 :     }
     266             339 :     else if (c >= 'A' && c <= 'F')
     267                 :     {
     268              88 :         return c - ('A' - 10);
     269                 :     }
     270             251 :     else if (c >= 'a' && c <= 'f')
     271                 :     {
     272             251 :         return c - ('a' - 10);
     273                 :     }
     274                 :     else
     275                 :     {
     276               0 :         return -1;
     277                 :     }
     278                 : }
     279                 : 
     280                 : 
     281                 : static void json_create_zval(zval **z, smart_str *buf, int type)
     282             546 : {
     283             546 :     ALLOC_INIT_ZVAL(*z);
     284                 : 
     285             546 :     if (type == IS_LONG)
     286                 :     {
     287             208 :                 if (buf->c[0] == '-') {
     288               8 :                         buf->len--;
     289                 :                 }
     290                 : 
     291             208 :                 if (buf->len >= MAX_LENGTH_OF_LONG - 1) {
     292              10 :                         if (buf->len == MAX_LENGTH_OF_LONG - 1) {
     293               8 :                                 int cmp = strcmp(buf->c + (buf->c[0] == '-'), long_min_digits);
     294                 : 
     295               8 :                                 if (!(cmp < 0 || (cmp == 0 && buf->c[0] == '-'))) {
     296                 :                                         goto use_double;
     297                 :                                 }
     298                 :                         } else {
     299               2 :                                 goto use_double;
     300                 :                         }
     301                 :                 }
     302                 : 
     303             206 :                 ZVAL_LONG(*z, strtol(buf->c, NULL, 10));
     304                 :     }
     305             338 :     else if (type == IS_DOUBLE)
     306                 :     {
     307              61 : use_double:
     308              61 :         ZVAL_DOUBLE(*z, zend_strtod(buf->c, NULL));
     309                 :     }
     310             279 :     else if (type == IS_STRING)
     311                 :     {
     312             223 :         ZVAL_STRINGL(*z, buf->c, buf->len, 1);
     313                 :     }
     314              56 :     else if (type == IS_BOOL)
     315                 :     {
     316              38 :         ZVAL_BOOL(*z, (*(buf->c) == 't'));
     317                 :     }
     318                 :     else /* type == IS_NULL) || type unknown */
     319                 :     {
     320              18 :         ZVAL_NULL(*z);
     321                 :     }
     322             546 : }
     323                 : 
     324                 : 
     325                 : static void utf16_to_utf8(smart_str *buf, unsigned short utf16)
     326            6790 : {
     327            6790 :     if (utf16 < 0x80)
     328                 :     {
     329            6620 :         smart_str_appendc(buf, (unsigned char) utf16);
     330                 :     }
     331             170 :     else if (utf16 < 0x800)
     332                 :     {
     333               8 :         smart_str_appendc(buf, 0xc0 | (utf16 >> 6));
     334               8 :         smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
     335                 :     }
     336             163 :     else if ((utf16 & 0xfc00) == 0xdc00
     337                 :                 && buf->len >= 3
     338                 :                 && ((unsigned char) buf->c[buf->len - 3]) == 0xed
     339                 :                 && ((unsigned char) buf->c[buf->len - 2] & 0xf0) == 0xa0
     340                 :                 && ((unsigned char) buf->c[buf->len - 1] & 0xc0) == 0x80)
     341                 :     {
     342                 :         /* found surrogate pair */
     343                 :         unsigned long utf32;
     344                 : 
     345               1 :         utf32 = (((buf->c[buf->len - 2] & 0xf) << 16)
     346                 :                     | ((buf->c[buf->len - 1] & 0x3f) << 10)
     347                 :                     | (utf16 & 0x3ff)) + 0x10000;
     348               1 :         buf->len -= 3;
     349                 : 
     350               1 :         smart_str_appendc(buf, 0xf0 | (utf32 >> 18));
     351               1 :         smart_str_appendc(buf, 0x80 | ((utf32 >> 12) & 0x3f));
     352               1 :         smart_str_appendc(buf, 0x80 | ((utf32 >> 6) & 0x3f));
     353               1 :         smart_str_appendc(buf, 0x80 | (utf32 & 0x3f));
     354                 :     }
     355                 :     else
     356                 :     {
     357             161 :         smart_str_appendc(buf, 0xe0 | (utf16 >> 12));
     358             161 :         smart_str_appendc(buf, 0x80 | ((utf16 >> 6) & 0x3f));
     359             161 :         smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
     360                 :     }
     361            6790 : }
     362                 : 
     363                 : static void attach_zval(json_parser *json, int up, int cur, smart_str *key, int assoc TSRMLS_DC)
     364            1193 : {
     365            1193 :     zval *root = json->the_zstack[up];
     366            1193 :     zval *child =  json->the_zstack[cur];
     367            1193 :     int up_mode = json->the_stack[up];
     368                 : 
     369            1193 :     if (up_mode == MODE_ARRAY)
     370                 :     {
     371            1124 :         add_next_index_zval(root, child);
     372                 :     }
     373              69 :     else if (up_mode == MODE_OBJECT)
     374                 :     {
     375              69 :         if (!assoc)
     376                 :         {
     377              37 :             add_property_zval_ex(root, (key->len ? key->c : "_empty_"), (key->len ? (key->len + 1) : sizeof("_empty_")), child TSRMLS_CC);
     378                 : #if PHP_MAJOR_VERSION >= 5
     379              37 :             ZVAL_DELREF(child);
     380                 : #endif
     381                 :         }
     382                 :         else
     383                 :         {
     384              32 :             add_assoc_zval_ex(root, (key->len ? key->c : ""), (key->len ? (key->len + 1) : sizeof("")), child);
     385                 :         }
     386              69 :         key->len = 0;
     387                 :     }
     388            1193 : }
     389                 : 
     390                 : 
     391                 : #define FREE_BUFFERS() do { smart_str_free(&buf); smart_str_free(&key); } while (0);
     392                 : #define SWAP_BUFFERS(from, to) do { \
     393                 :         char *t1 = from.c; \
     394                 :         int t2 = from.a; \
     395                 :         from.c = to.c; \
     396                 :         from.a = to.a; \
     397                 :         to.c = t1; \
     398                 :         to.a = t2; \
     399                 :         to.len = from.len; \
     400                 :         from.len = 0; \
     401                 :         } while(0);
     402                 : #define JSON_RESET_TYPE() do { type = -1; } while(0);
     403                 : #define JSON(x) the_json.x
     404                 : 
     405                 : 
     406                 : /*
     407                 :     The JSON_parser takes a UTF-16 encoded string and determines if it is a
     408                 :     syntactically correct JSON text. Along the way, it creates a PHP variable.
     409                 : 
     410                 :     It is implemented as a Pushdown Automaton; that means it is a finite state
     411                 :     machine with a stack.
     412                 : */
     413                 : int
     414                 : JSON_parser(zval *z, unsigned short p[], int length, int assoc TSRMLS_DC)
     415             129 : {
     416                 :     int b;  /* the next character */
     417                 :     int c;  /* the next character class */
     418                 :     int s;  /* the next state */
     419                 :     json_parser the_json; /* the parser state */
     420             129 :     int the_state = 0;
     421                 :     int the_index;
     422                 : 
     423             129 :     smart_str buf = {0};
     424             129 :     smart_str key = {0};
     425                 : 
     426             129 :     int type = -1;
     427             129 :     unsigned short utf16 = 0;
     428                 : 
     429             129 :     JSON(the_top) = -1;
     430             129 :     push(&the_json, z, MODE_DONE);
     431                 : 
     432           13895 :     for (the_index = 0; the_index < length; the_index += 1) {
     433           13842 :         b = p[the_index];
     434           13842 :         if ((b & 127) == b) {
     435           13817 :             c = ascii_class[b];
     436           13817 :             if (c <= S_ERR) {
     437               0 :                 FREE_BUFFERS();
     438               0 :                 return false;
     439                 :             }
     440                 :         } else {
     441              25 :             c = S_ETC;
     442                 :         }
     443                 : /*
     444                 :     Get the next state from the transition table.
     445                 : */
     446           13842 :         s = state_transition_table[the_state][c];
     447           13842 :         if (s < 0) {
     448                 : /*
     449                 :     Perform one of the predefined actions.
     450                 : */
     451            3074 :             switch (s) {
     452                 : /*
     453                 :     empty }
     454                 : */
     455                 :             case -9:
     456              14 :                 if (!pop(&the_json, z, MODE_KEY)) {
     457               0 :                     FREE_BUFFERS();
     458               0 :                     return false;
     459                 :                 }
     460              14 :                 the_state = 9;
     461              14 :                 break;
     462                 : /*
     463                 :     {
     464                 : */
     465                 :             case -8:
     466              88 :                 if (!push(&the_json, z, MODE_KEY)) {
     467               0 :                     FREE_BUFFERS();
     468               0 :                     return false;
     469                 :                 }
     470                 : 
     471              88 :                 the_state = 1;
     472              88 :                 if (JSON(the_top) > 0)
     473                 :                 {
     474                 :                     zval *obj;
     475                 : 
     476              88 :                     if (JSON(the_top) == 1)
     477                 :                     {
     478              39 :                         obj = z;
     479                 :                     }
     480                 :                     else
     481                 :                     {
     482              49 :                         ALLOC_INIT_ZVAL(obj);
     483                 :                     }
     484                 : 
     485              88 :                     if (!assoc)
     486                 :                     {
     487              50 :                         object_init(obj);
     488                 :                     }
     489                 :                     else
     490                 :                     {
     491              38 :                         array_init(obj);
     492                 :                     }
     493                 : 
     494              88 :                     JSON(the_zstack)[JSON(the_top)] = obj;
     495                 : 
     496              88 :                     if (JSON(the_top) > 1)
     497                 :                     {
     498              49 :                         attach_zval(&the_json, JSON(the_top-1), JSON(the_top), &key, assoc TSRMLS_CC);
     499                 :                     }
     500                 : 
     501              88 :                     JSON_RESET_TYPE();
     502                 :                 }
     503                 : 
     504              88 :                 break;
     505                 : /*
     506                 :     }
     507                 : */
     508                 :             case -7:
     509              54 :                 if (type != -1 && JSON(the_stack)[JSON(the_top)] == MODE_OBJECT)
     510                 :                 {
     511                 :                     zval *mval;
     512              26 :                     smart_str_0(&buf);
     513                 : 
     514              26 :                     json_create_zval(&mval, &buf, type);
     515                 : 
     516              26 :                     if (!assoc)
     517                 :                     {
     518              14 :                         add_property_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
     519                 : #if PHP_MAJOR_VERSION >= 5
     520              14 :                         ZVAL_DELREF(mval);
     521                 : #endif
     522                 :                     }
     523                 :                     else
     524                 :                     {
     525              12 :                         add_assoc_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
     526                 :                     }
     527              26 :                     key.len = 0;
     528              26 :                     buf.len = 0;
     529              26 :                     JSON_RESET_TYPE();
     530                 :                 }
     531                 : 
     532                 : 
     533              54 :                 if (!pop(&the_json, z, MODE_OBJECT)) {
     534               0 :                     FREE_BUFFERS();
     535               0 :                     return false;
     536                 :                 }
     537              54 :                 the_state = 9;
     538              54 :                 break;
     539                 : /*
     540                 :     [
     541                 : */
     542                 :             case -6:
     543            1193 :                 if (!push(&the_json, z, MODE_ARRAY)) {
     544               2 :                     FREE_BUFFERS();
     545               2 :                     return false;
     546                 :                 }
     547            1191 :                 the_state = 2;
     548                 : 
     549            1191 :                 if (JSON(the_top) > 0)
     550                 :                 {
     551                 :                     zval *arr;
     552                 : 
     553            1191 :                     if (JSON(the_top) == 1)
     554                 :                     {
     555              47 :                         arr = z;
     556                 :                     }
     557                 :                     else
     558                 :                     {
     559            1144 :                         ALLOC_INIT_ZVAL(arr);
     560                 :                     }
     561                 : 
     562            1191 :                     array_init(arr);
     563            1191 :                     JSON(the_zstack)[JSON(the_top)] = arr;
     564                 : 
     565            1191 :                     if (JSON(the_top) > 1)
     566                 :                     {
     567            1144 :                         attach_zval(&the_json, JSON(the_top-1), JSON(the_top), &key, assoc TSRMLS_CC);
     568                 :                     }
     569                 : 
     570            1191 :                     JSON_RESET_TYPE();
     571                 :                 }
     572                 : 
     573            1191 :                 break;
     574                 : /*
     575                 :     ]
     576                 : */
     577                 :             case -5:
     578                 :             {
     579             151 :                 if (type != -1 && JSON(the_stack)[JSON(the_top)] == MODE_ARRAY)
     580                 :                 {
     581                 :                     zval *mval;
     582              55 :                     smart_str_0(&buf);
     583                 : 
     584              55 :                     json_create_zval(&mval, &buf, type);
     585              55 :                     add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
     586              55 :                     buf.len = 0;
     587              55 :                     JSON_RESET_TYPE();
     588                 :                 }
     589                 : 
     590             151 :                 if (!pop(&the_json, z, MODE_ARRAY)) {
     591               2 :                     FREE_BUFFERS();
     592               2 :                     return false;
     593                 :                 }
     594             149 :                 the_state = 9;
     595                 :             }
     596             149 :                 break;
     597                 : /*
     598                 :     "
     599                 : */
     600                 :             case -4:
     601             605 :                 switch (JSON(the_stack)[JSON(the_top)]) {
     602                 :                 case MODE_KEY:
     603             364 :                     the_state = 27;
     604             364 :                     smart_str_0(&buf);
     605             364 :                     SWAP_BUFFERS(buf, key);
     606             364 :                     JSON_RESET_TYPE();
     607             364 :                     break;
     608                 :                 case MODE_ARRAY:
     609                 :                 case MODE_OBJECT:
     610             228 :                     the_state = 9;
     611             228 :                     break;
     612                 :                                 case MODE_DONE:
     613              13 :                                         if (type == IS_STRING) {
     614              13 :                                                 smart_str_0(&buf);
     615              13 :                                                 ZVAL_STRINGL(z, buf.c, buf.len, 1);
     616              13 :                                                 the_state = 9;
     617              13 :                                                 break;
     618                 :                                         }
     619                 :                                         /* fall through if not IS_STRING */
     620                 :                 default:
     621               0 :                     FREE_BUFFERS();
     622               0 :                     return false;
     623                 :                 }
     624             605 :                 break;
     625                 : /*
     626                 :     ,
     627                 : */
     628                 :             case -3:
     629                 :             {
     630                 :                 zval *mval;
     631                 : 
     632             539 :                 if (type != -1 &&
     633                 :                     (JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
     634                 :                      JSON(the_stack[JSON(the_top)]) == MODE_ARRAY))
     635                 :                 {
     636             465 :                     smart_str_0(&buf);
     637             465 :                     json_create_zval(&mval, &buf, type);
     638                 :                 }
     639                 : 
     640             539 :                 switch (JSON(the_stack)[JSON(the_top)]) {
     641                 :                     case MODE_OBJECT:
     642             294 :                         if (pop(&the_json, z, MODE_OBJECT) && push(&the_json, z, MODE_KEY)) {
     643             294 :                             if (type != -1)
     644                 :                             {
     645             254 :                                 if (!assoc)
     646                 :                                 {
     647             126 :                                     add_property_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
     648                 : #if PHP_MAJOR_VERSION >= 5
     649             126 :                                     ZVAL_DELREF(mval);
     650                 : #endif
     651                 :                                 }
     652                 :                                 else
     653                 :                                 {
     654             128 :                                     add_assoc_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
     655                 :                                 }
     656             254 :                                 key.len = 0;
     657                 :                             }
     658             294 :                             the_state = 29;
     659                 :                         }
     660             294 :                         break;
     661                 :                     case MODE_ARRAY:
     662             243 :                         if (type != -1)
     663                 :                         {
     664             211 :                             add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
     665                 :                         }
     666             243 :                         the_state = 28;
     667             243 :                         break;
     668                 :                     default:
     669               2 :                         FREE_BUFFERS();
     670               2 :                         return false;
     671                 :                 }
     672             537 :                 buf.len = 0;
     673             537 :                 JSON_RESET_TYPE();
     674                 :             }
     675             537 :             break;
     676                 : /*
     677                 :     :
     678                 : */
     679                 :             case -2:
     680             360 :                 if (pop(&the_json, z, MODE_KEY) && push(&the_json, z, MODE_OBJECT)) {
     681             360 :                     the_state = 28;
     682             360 :                     break;
     683                 :                 }
     684                 : /*
     685                 :     syntax error
     686                 : */
     687                 :             case -1:
     688                 :                 {
     689              70 :                     FREE_BUFFERS();
     690              70 :                     return false;
     691                 :                 }
     692                 :             }
     693                 :         } else {
     694                 : /*
     695                 :     Change the state and iterate.
     696                 : */
     697           10768 :             if (type == IS_STRING)
     698                 :             {
     699           13076 :                 if (s == 3 && the_state != 8)
     700                 :                 {
     701            5962 :                     if (the_state != 4)
     702                 :                     {
     703            5751 :                         utf16_to_utf8(&buf, b);
     704                 :                     }
     705                 :                     else
     706                 :                     {
     707             211 :                         switch (b)
     708                 :                         {
     709                 :                             case 'b':
     710              16 :                                 smart_str_appendc(&buf, '\b');
     711              16 :                                 break;
     712                 :                             case 't':
     713              16 :                                 smart_str_appendc(&buf, '\t');
     714              16 :                                 break;
     715                 :                             case 'n':
     716              18 :                                 smart_str_appendc(&buf, '\n');
     717              18 :                                 break;
     718                 :                             case 'f':
     719              16 :                                 smart_str_appendc(&buf, '\f');
     720              16 :                                 break;
     721                 :                             case 'r':
     722              18 :                                 smart_str_appendc(&buf, '\r');
     723              18 :                                 break;
     724                 :                             default:
     725             127 :                                 utf16_to_utf8(&buf, b);
     726                 :                                 break;
     727                 :                         }
     728                 :                     }
     729                 :                 }
     730            1152 :                 else if (s == 6)
     731                 :                 {
     732             150 :                     utf16 = dehexchar(b) << 12;
     733                 :                 }
     734            1002 :                 else if (s == 7)
     735                 :                 {
     736             150 :                     utf16 += dehexchar(b) << 8;
     737                 :                 }
     738             852 :                 else if (s == 8)
     739                 :                 {
     740             150 :                     utf16 += dehexchar(b) << 4;
     741                 :                 }
     742             702 :                 else if (s == 3 && the_state == 8)
     743                 :                 {
     744             150 :                     utf16 += dehexchar(b);
     745             150 :                     utf16_to_utf8(&buf, utf16);
     746                 :                 }
     747                 :             }
     748            3927 :             else if (type < IS_LONG && (c == S_DIG || c == S_ZER))
     749                 :             {
     750             273 :                 type = IS_LONG;
     751             273 :                 smart_str_appendc(&buf, b);
     752                 :             }
     753            3387 :             else if (type == IS_LONG && s == 24)
     754                 :             {
     755               6 :                 type = IS_DOUBLE;
     756               6 :                 smart_str_appendc(&buf, b);
     757                 :             }
     758            3428 :             else if (type < IS_DOUBLE && c == S_DOT)
     759                 :             {
     760              53 :                 type = IS_DOUBLE;
     761              53 :                 smart_str_appendc(&buf, b);
     762                 :             }
     763            3934 :             else if (type < IS_STRING && c == S_QUO)
     764                 :             {
     765             612 :                 type = IS_STRING;
     766                 :             }
     767            2748 :             else if (type < IS_BOOL && ((the_state == 12 && s == 9) || (the_state == 16 && s == 9)))
     768                 :             {
     769              38 :                 type = IS_BOOL;
     770                 :             }
     771            2690 :             else if (type < IS_NULL && the_state == 19 && s == 9)
     772                 :             {
     773              18 :                 type = IS_NULL;
     774                 :             }
     775            2654 :             else if (type != IS_STRING && c > S_WSP)
     776                 :             {
     777             762 :                 utf16_to_utf8(&buf, b);
     778                 :             }
     779                 : 
     780           10768 :             the_state = s;
     781                 :         }
     782                 :     }
     783                 : 
     784              53 :     FREE_BUFFERS();
     785                 : 
     786              53 :     return the_state == 9 && pop(&the_json, z, MODE_DONE);
     787                 : }
     788                 : 
     789                 : 
     790                 : /*
     791                 :  * Local variables:
     792                 :  * tab-width: 4
     793                 :  * c-basic-offset: 4
     794                 :  * End:
     795                 :  * vim600: noet sw=4 ts=4
     796                 :  * vim<600: noet sw=4 ts=4
     797                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:09 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.