diff options
author | Jakub Zelenka <bukka@php.net> | 2014-11-23 19:53:06 +0000 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2014-11-23 19:53:06 +0000 |
commit | f00b80a511245c5026d1f912442c2198963c3336 (patch) | |
tree | 512eac71587e5c3d3bcf8395289a2b8370352761 /ext | |
parent | ba70ba5f139b4d8892153a1b416819001a891176 (diff) | |
download | php-git-f00b80a511245c5026d1f912442c2198963c3336.tar.gz |
Implement initial changes for json_parser
Diffstat (limited to 'ext')
-rw-r--r-- | ext/json/json_parser.y | 77 |
1 files changed, 31 insertions, 46 deletions
diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index 96a9ba30c0..354b97855c 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -44,7 +44,6 @@ int json_yydebug = 1; zval key; zval val; } pair; - HashTable *ht; } @@ -59,7 +58,7 @@ int json_yydebug = 1; %token <value> PHP_JSON_T_ERROR %type <value> start object key value array errlex -%type <ht> members member elements element +%type <value> members member elements element %type <pair> pair %destructor { zval_dtor(&$$); } <value> @@ -92,7 +91,7 @@ start: ; object: - '{' { PHP_JSON_DEPTH_INC; } members object_end { PHP_JSON_DEPTH_DEC; php_json_parser_object_to_zval(parser, &$$, $3); } + '{' { PHP_JSON_DEPTH_INC; } members object_end { PHP_JSON_DEPTH_DEC; $$ = $3; } ; object_end: @@ -101,13 +100,13 @@ object_end: ; members: - /* empty */ { php_json_parser_ht_init(&$$, 0); } + /* empty */ { php_json_parser_object_init(&$$); } | member ; member: - pair { php_json_parser_ht_init(&$$, 4); php_json_parser_ht_update(parser, $$, &$1.key, &$1.val); } - | member ',' pair { php_json_parser_ht_update(parser, $1, &$3.key, &$3.val); $$ = $1; } + pair { php_json_parser_object_init(&$$); php_json_parser_object_update(parser, &$$, &$1.key, &$1.val); } + | member ',' pair { php_json_parser_object_update(parser, &$1, &$3.key, &$3.val); $$ = $1; } | member errlex { PHP_JSON_USE_2($$, $1, $2); } ; @@ -117,7 +116,7 @@ pair: ; array: - '[' { PHP_JSON_DEPTH_INC; } elements array_end { PHP_JSON_DEPTH_DEC; php_json_parser_array_to_zval(&$$, $3); } + '[' { PHP_JSON_DEPTH_INC; } elements array_end { PHP_JSON_DEPTH_DEC; $$ = $3; } ; array_end: @@ -126,13 +125,13 @@ array_end: ; elements: - /* empty */ { php_json_parser_ht_init(&$$, 0); } + /* empty */ { php_json_parser_array_init(&$$); } | element ; element: - value { php_json_parser_ht_init(&$$, 4); php_json_parser_ht_append($$, &$1); } - | element ',' value { php_json_parser_ht_append($1, &$3); $$ = $1; } + value { php_json_parser_array_init(&$$); php_json_parser_array_append(&$$, &$1); } + | element ',' value { php_json_parser_array_append(&$1, &$3); $$ = $1; } | element errlex { PHP_JSON_USE_2($$, $1, $2); } ; @@ -175,56 +174,42 @@ php_json_error_code php_json_parser_error_code(php_json_parser *parser) return parser->scanner.errcode; } -void php_json_parser_object_to_zval(php_json_parser *parser, zval *zv, HashTable *ht) +void php_json_parser_object_init(zval *object) { - TSRMLS_FETCH_FROM_CTX(parser->zts_ctx); - - if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) { - php_json_parser_array_to_zval(zv, ht); - } else { - object_and_properties_init(zv, zend_standard_class_def, ht); - } -} - -void php_json_parser_array_to_zval(zval *zv, HashTable *ht) -{ - Z_TYPE_P(zv) = IS_ARRAY; - Z_ARRVAL_P(zv) = ht; -} - -void php_json_parser_ht_init(HashTable **ht, uint nSize) -{ - ALLOC_HASHTABLE(*ht); - zend_hash_init(*ht, nSize, NULL, ZVAL_PTR_DTOR, 0); + object_init(object); } -void php_json_parser_ht_update(php_json_parser *parser, HashTable *ht, zval *zkey, zval *zvalue) +void php_json_parser_object_update(php_json_parser *parser, zval *object, zval *zkey, zval *zvalue) { - zval *data; char *key = Z_STRVAL_P(zkey); - int key_len = Z_STRLEN_P(zkey)+1; - MAKE_STD_ZVAL(data); - ZVAL_ZVAL(data, zvalue, 0, 0); - + int key_len = Z_STRLEN_P(zkey); + TSRMLS_FETCH_FROM_CTX(parser->zts_ctx); + if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) { - zend_symtable_update(ht, key, key_len, &data, sizeof(zval *), NULL); + add_assoc_zval_ex(object, key, key_len, zvalue); } else { - if (key_len == 1) { + if (key_len == 0) { key = "_empty_"; key_len = sizeof("_empty_"); } - zend_hash_update(ht, key, key_len, &data, sizeof(zval *), NULL); + add_property_zval_ex(object, key, key_len, zvalue TSRMLS_CC); + /* + if (Z_REFCOUNTED_P(zvalue)) { + Z_DELREF_P(zvalue); + } + */ } - - zval_dtor(zkey); } -void php_json_parser_ht_append(HashTable *ht, zval *zvalue) + +void php_json_parser_array_init(zval *array) +{ + array_init(object); +} + +void php_json_parser_array_append(zval *array, zval *zvalue) { - zval *data; - MAKE_STD_ZVAL(data); - ZVAL_ZVAL(data, zvalue, 0, 0); - zend_hash_next_index_insert(ht, &data, sizeof(zval *), NULL); + add_next_index_zval(array, zvalue); } int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) |