Annotation of embedaddon/php/ext/json/json.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   +----------------------------------------------------------------------+
        !             3:   | PHP Version 5                                                        |
        !             4:   +----------------------------------------------------------------------+
        !             5:   | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:   +----------------------------------------------------------------------+
        !             7:   | This source file is subject to version 3.01 of the PHP license,      |
        !             8:   | that is bundled with this package in the file LICENSE, and is        |
        !             9:   | available through the world-wide-web at the following url:           |
        !            10:   | http://www.php.net/license/3_01.txt                                  |
        !            11:   | If you did not receive a copy of the PHP license and are unable to   |
        !            12:   | obtain it through the world-wide-web, please send a note to          |
        !            13:   | license@php.net so we can mail you a copy immediately.               |
        !            14:   +----------------------------------------------------------------------+
        !            15:   | Author: Omar Kilani <omar@php.net>                                   |
        !            16:   +----------------------------------------------------------------------+
        !            17: */
        !            18: 
        !            19: /* $Id: json.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            20: 
        !            21: #ifdef HAVE_CONFIG_H
        !            22: #include "config.h"
        !            23: #endif
        !            24: 
        !            25: #include "php.h"
        !            26: #include "php_ini.h"
        !            27: #include "ext/standard/info.h"
        !            28: #include "ext/standard/php_smart_str.h"
        !            29: #include "utf8_to_utf16.h"
        !            30: #include "JSON_parser.h"
        !            31: #include "php_json.h"
        !            32: 
        !            33: static PHP_MINFO_FUNCTION(json);
        !            34: static PHP_FUNCTION(json_encode);
        !            35: static PHP_FUNCTION(json_decode);
        !            36: static PHP_FUNCTION(json_last_error);
        !            37: 
        !            38: static const char digits[] = "0123456789abcdef";
        !            39: 
        !            40: ZEND_DECLARE_MODULE_GLOBALS(json)
        !            41: 
        !            42: /* {{{ arginfo */
        !            43: ZEND_BEGIN_ARG_INFO_EX(arginfo_json_encode, 0, 0, 1)
        !            44:        ZEND_ARG_INFO(0, value)
        !            45:        ZEND_ARG_INFO(0, options)
        !            46: ZEND_END_ARG_INFO()
        !            47: 
        !            48: ZEND_BEGIN_ARG_INFO_EX(arginfo_json_decode, 0, 0, 1)
        !            49:        ZEND_ARG_INFO(0, json)
        !            50:        ZEND_ARG_INFO(0, assoc)
        !            51:        ZEND_ARG_INFO(0, depth)
        !            52: ZEND_END_ARG_INFO()
        !            53: 
        !            54: ZEND_BEGIN_ARG_INFO(arginfo_json_last_error, 0)
        !            55: ZEND_END_ARG_INFO()
        !            56: /* }}} */
        !            57: 
        !            58: /* {{{ json_functions[] */
        !            59: static const function_entry json_functions[] = {
        !            60:        PHP_FE(json_encode, arginfo_json_encode)
        !            61:        PHP_FE(json_decode, arginfo_json_decode)
        !            62:        PHP_FE(json_last_error, arginfo_json_last_error)
        !            63:        PHP_FE_END
        !            64: };
        !            65: /* }}} */
        !            66: 
        !            67: /* {{{ MINIT */
        !            68: static PHP_MINIT_FUNCTION(json)
        !            69: {
        !            70:        REGISTER_LONG_CONSTANT("JSON_HEX_TAG",  PHP_JSON_HEX_TAG,  CONST_CS | CONST_PERSISTENT);
        !            71:        REGISTER_LONG_CONSTANT("JSON_HEX_AMP",  PHP_JSON_HEX_AMP,  CONST_CS | CONST_PERSISTENT);
        !            72:        REGISTER_LONG_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS, CONST_CS | CONST_PERSISTENT);
        !            73:        REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | CONST_PERSISTENT);
        !            74:        REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, CONST_CS | CONST_PERSISTENT);
        !            75:        REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, CONST_CS | CONST_PERSISTENT);
        !            76: 
        !            77:        REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
        !            78:        REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
        !            79:        REGISTER_LONG_CONSTANT("JSON_ERROR_STATE_MISMATCH", PHP_JSON_ERROR_STATE_MISMATCH, CONST_CS | CONST_PERSISTENT);
        !            80:        REGISTER_LONG_CONSTANT("JSON_ERROR_CTRL_CHAR", PHP_JSON_ERROR_CTRL_CHAR, CONST_CS | CONST_PERSISTENT);
        !            81:        REGISTER_LONG_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX, CONST_CS | CONST_PERSISTENT);
        !            82:        REGISTER_LONG_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8, CONST_CS | CONST_PERSISTENT);
        !            83: 
        !            84:        return SUCCESS;
        !            85: }
        !            86: /* }}} */
        !            87: 
        !            88: /* {{{ PHP_GINIT_FUNCTION
        !            89: */
        !            90: static PHP_GINIT_FUNCTION(json)
        !            91: {
        !            92:        json_globals->error_code = 0;
        !            93: }
        !            94: /* }}} */
        !            95: 
        !            96: 
        !            97: /* {{{ json_module_entry
        !            98:  */
        !            99: zend_module_entry json_module_entry = {
        !           100:        STANDARD_MODULE_HEADER,
        !           101:        "json",
        !           102:        json_functions,
        !           103:        PHP_MINIT(json),
        !           104:        NULL,
        !           105:        NULL,
        !           106:        NULL,
        !           107:        PHP_MINFO(json),
        !           108:        PHP_JSON_VERSION,
        !           109:        PHP_MODULE_GLOBALS(json),
        !           110:        PHP_GINIT(json),
        !           111:        NULL,
        !           112:        NULL,
        !           113:        STANDARD_MODULE_PROPERTIES_EX
        !           114: };
        !           115: /* }}} */
        !           116: 
        !           117: #ifdef COMPILE_DL_JSON
        !           118: ZEND_GET_MODULE(json)
        !           119: #endif
        !           120: 
        !           121: /* {{{ PHP_MINFO_FUNCTION
        !           122:  */
        !           123: static PHP_MINFO_FUNCTION(json)
        !           124: {
        !           125:        php_info_print_table_start();
        !           126:        php_info_print_table_row(2, "json support", "enabled");
        !           127:        php_info_print_table_row(2, "json version", PHP_JSON_VERSION);
        !           128:        php_info_print_table_end();
        !           129: }
        !           130: /* }}} */
        !           131: 
        !           132: static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC);
        !           133: 
        !           134: static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */
        !           135: {
        !           136:        int i;
        !           137:        HashTable *myht = HASH_OF(*val);
        !           138: 
        !           139:        i = myht ? zend_hash_num_elements(myht) : 0;
        !           140:        if (i > 0) {
        !           141:                char *key;
        !           142:                ulong index, idx;
        !           143:                uint key_len;
        !           144:                HashPosition pos;
        !           145: 
        !           146:                zend_hash_internal_pointer_reset_ex(myht, &pos);
        !           147:                idx = 0;
        !           148:                for (;; zend_hash_move_forward_ex(myht, &pos)) {
        !           149:                        i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
        !           150:                        if (i == HASH_KEY_NON_EXISTANT)
        !           151:                                break;
        !           152: 
        !           153:                        if (i == HASH_KEY_IS_STRING) {
        !           154:                                return 1;
        !           155:                        } else {
        !           156:                                if (index != idx) {
        !           157:                                        return 1;
        !           158:                                }
        !           159:                        }
        !           160:                        idx++;
        !           161:                }
        !           162:        }
        !           163: 
        !           164:        return PHP_JSON_OUTPUT_ARRAY;
        !           165: }
        !           166: /* }}} */
        !           167: 
        !           168: static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */
        !           169: {
        !           170:        int i, r;
        !           171:        HashTable *myht;
        !           172: 
        !           173:        if (Z_TYPE_PP(val) == IS_ARRAY) {
        !           174:                myht = HASH_OF(*val);
        !           175:                r = (options & PHP_JSON_FORCE_OBJECT) ? PHP_JSON_OUTPUT_OBJECT : json_determine_array_type(val TSRMLS_CC);
        !           176:        } else {
        !           177:                myht = Z_OBJPROP_PP(val);
        !           178:                r = PHP_JSON_OUTPUT_OBJECT;
        !           179:        }
        !           180: 
        !           181:        if (myht && myht->nApplyCount > 1) {
        !           182:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
        !           183:                smart_str_appendl(buf, "null", 4);
        !           184:                return;
        !           185:        }
        !           186: 
        !           187:        if (r == PHP_JSON_OUTPUT_ARRAY) {
        !           188:                smart_str_appendc(buf, '[');
        !           189:        } else {
        !           190:                smart_str_appendc(buf, '{');
        !           191:        }
        !           192: 
        !           193:        i = myht ? zend_hash_num_elements(myht) : 0;
        !           194: 
        !           195:        if (i > 0)
        !           196:        {
        !           197:                char *key;
        !           198:                zval **data;
        !           199:                ulong index;
        !           200:                uint key_len;
        !           201:                HashPosition pos;
        !           202:                HashTable *tmp_ht;
        !           203:                int need_comma = 0;
        !           204: 
        !           205:                zend_hash_internal_pointer_reset_ex(myht, &pos);
        !           206:                for (;; zend_hash_move_forward_ex(myht, &pos)) {
        !           207:                        i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
        !           208:                        if (i == HASH_KEY_NON_EXISTANT)
        !           209:                                break;
        !           210: 
        !           211:                        if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS) {
        !           212:                                tmp_ht = HASH_OF(*data);
        !           213:                                if (tmp_ht) {
        !           214:                                        tmp_ht->nApplyCount++;
        !           215:                                }
        !           216: 
        !           217:                                if (r == PHP_JSON_OUTPUT_ARRAY) {
        !           218:                                        if (need_comma) {
        !           219:                                                smart_str_appendc(buf, ',');
        !           220:                                        } else {
        !           221:                                                need_comma = 1;
        !           222:                                        }
        !           223:  
        !           224:                                        php_json_encode(buf, *data, options TSRMLS_CC);
        !           225:                                } else if (r == PHP_JSON_OUTPUT_OBJECT) {
        !           226:                                        if (i == HASH_KEY_IS_STRING) {
        !           227:                                                if (key[0] == '\0' && Z_TYPE_PP(val) == IS_OBJECT) {
        !           228:                                                        /* Skip protected and private members. */
        !           229:                                                        if (tmp_ht) {
        !           230:                                                                tmp_ht->nApplyCount--;
        !           231:                                                        }
        !           232:                                                        continue;
        !           233:                                                }
        !           234: 
        !           235:                                                if (need_comma) {
        !           236:                                                        smart_str_appendc(buf, ',');
        !           237:                                                } else {
        !           238:                                                        need_comma = 1;
        !           239:                                                }
        !           240: 
        !           241:                                                json_escape_string(buf, key, key_len - 1, options & ~PHP_JSON_NUMERIC_CHECK TSRMLS_CC);
        !           242:                                                smart_str_appendc(buf, ':');
        !           243: 
        !           244:                                                php_json_encode(buf, *data, options TSRMLS_CC);
        !           245:                                        } else {
        !           246:                                                if (need_comma) {
        !           247:                                                        smart_str_appendc(buf, ',');
        !           248:                                                } else {
        !           249:                                                        need_comma = 1;
        !           250:                                                }
        !           251: 
        !           252:                                                smart_str_appendc(buf, '"');
        !           253:                                                smart_str_append_long(buf, (long) index);
        !           254:                                                smart_str_appendc(buf, '"');
        !           255:                                                smart_str_appendc(buf, ':');
        !           256: 
        !           257:                                                php_json_encode(buf, *data, options TSRMLS_CC);
        !           258:                                        }
        !           259:                                }
        !           260: 
        !           261:                                if (tmp_ht) {
        !           262:                                        tmp_ht->nApplyCount--;
        !           263:                                }
        !           264:                        }
        !           265:                }
        !           266:        }
        !           267: 
        !           268:        if (r == PHP_JSON_OUTPUT_ARRAY) {
        !           269:                smart_str_appendc(buf, ']');
        !           270:        } else {
        !           271:                smart_str_appendc(buf, '}');
        !           272:        }
        !           273: }
        !           274: /* }}} */
        !           275: 
        !           276: #define REVERSE16(us) (((us & 0xf) << 12) | (((us >> 4) & 0xf) << 8) | (((us >> 8) & 0xf) << 4) | ((us >> 12) & 0xf))
        !           277: 
        !           278: static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC) /* {{{ */
        !           279: {
        !           280:        int pos = 0;
        !           281:        unsigned short us;
        !           282:        unsigned short *utf16;
        !           283: 
        !           284:        if (len == 0) {
        !           285:                smart_str_appendl(buf, "\"\"", 2);
        !           286:                return;
        !           287:        }
        !           288: 
        !           289:        if (options & PHP_JSON_NUMERIC_CHECK) {
        !           290:                double d;
        !           291:                int type;
        !           292:                long p;
        !           293: 
        !           294:                if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
        !           295:                        if (type == IS_LONG) {
        !           296:                                smart_str_append_long(buf, p);
        !           297:                        } else if (type == IS_DOUBLE) {
        !           298:                                if (!zend_isinf(d) && !zend_isnan(d)) {
        !           299:                                        char *tmp;
        !           300:                                        int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);
        !           301:                                        smart_str_appendl(buf, tmp, l);
        !           302:                                        efree(tmp);
        !           303:                                } else {
        !           304:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
        !           305:                                        smart_str_appendc(buf, '0');
        !           306:                                }
        !           307:                        }
        !           308:                        return;
        !           309:                }
        !           310:                
        !           311:        }
        !           312: 
        !           313:        utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);
        !           314: 
        !           315:        len = utf8_to_utf16(utf16, s, len);
        !           316:        if (len <= 0) {
        !           317:                if (utf16) {
        !           318:                        efree(utf16);
        !           319:                }
        !           320:                if (len < 0) {
        !           321:                        JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
        !           322:                        if (!PG(display_errors)) {
        !           323:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument");
        !           324:                        }
        !           325:                        smart_str_appendl(buf, "null", 4);
        !           326:                } else {
        !           327:                        smart_str_appendl(buf, "\"\"", 2);
        !           328:                }
        !           329:                return;
        !           330:        }
        !           331: 
        !           332:        smart_str_appendc(buf, '"');
        !           333: 
        !           334:        while (pos < len)
        !           335:        {
        !           336:                us = utf16[pos++];
        !           337: 
        !           338:                switch (us)
        !           339:                {
        !           340:                        case '"':
        !           341:                                if (options & PHP_JSON_HEX_QUOT) {
        !           342:                                        smart_str_appendl(buf, "\\u0022", 6);
        !           343:                                } else {
        !           344:                                        smart_str_appendl(buf, "\\\"", 2);
        !           345:                                }
        !           346:                                break;
        !           347: 
        !           348:                        case '\\':
        !           349:                                smart_str_appendl(buf, "\\\\", 2);
        !           350:                                break;
        !           351: 
        !           352:                        case '/':
        !           353:                                smart_str_appendl(buf, "\\/", 2);
        !           354:                                break;
        !           355: 
        !           356:                        case '\b':
        !           357:                                smart_str_appendl(buf, "\\b", 2);
        !           358:                                break;
        !           359: 
        !           360:                        case '\f':
        !           361:                                smart_str_appendl(buf, "\\f", 2);
        !           362:                                break;
        !           363: 
        !           364:                        case '\n':
        !           365:                                smart_str_appendl(buf, "\\n", 2);
        !           366:                                break;
        !           367: 
        !           368:                        case '\r':
        !           369:                                smart_str_appendl(buf, "\\r", 2);
        !           370:                                break;
        !           371: 
        !           372:                        case '\t':
        !           373:                                smart_str_appendl(buf, "\\t", 2);
        !           374:                                break;
        !           375: 
        !           376:                        case '<':
        !           377:                                if (options & PHP_JSON_HEX_TAG) {
        !           378:                                        smart_str_appendl(buf, "\\u003C", 6);
        !           379:                                } else {
        !           380:                                        smart_str_appendc(buf, '<');
        !           381:                                }
        !           382:                                break;
        !           383: 
        !           384:                        case '>':
        !           385:                                if (options & PHP_JSON_HEX_TAG) {
        !           386:                                        smart_str_appendl(buf, "\\u003E", 6);
        !           387:                                } else {
        !           388:                                        smart_str_appendc(buf, '>');
        !           389:                                }
        !           390:                                break;
        !           391: 
        !           392:                        case '&':
        !           393:                                if (options & PHP_JSON_HEX_AMP) {
        !           394:                                        smart_str_appendl(buf, "\\u0026", 6);
        !           395:                                } else {
        !           396:                                        smart_str_appendc(buf, '&');
        !           397:                                }
        !           398:                                break;
        !           399: 
        !           400:                        case '\'':
        !           401:                                if (options & PHP_JSON_HEX_APOS) {
        !           402:                                        smart_str_appendl(buf, "\\u0027", 6);
        !           403:                                } else {
        !           404:                                        smart_str_appendc(buf, '\'');
        !           405:                                }
        !           406:                                break;
        !           407: 
        !           408:                        default:
        !           409:                                if (us >= ' ' && (us & 127) == us) {
        !           410:                                        smart_str_appendc(buf, (unsigned char) us);
        !           411:                                } else {
        !           412:                                        smart_str_appendl(buf, "\\u", 2);
        !           413:                                        us = REVERSE16(us);
        !           414: 
        !           415:                                        smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
        !           416:                                        us >>= 4;
        !           417:                                        smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
        !           418:                                        us >>= 4;
        !           419:                                        smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
        !           420:                                        us >>= 4;
        !           421:                                        smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
        !           422:                                }
        !           423:                                break;
        !           424:                }
        !           425:        }
        !           426: 
        !           427:        smart_str_appendc(buf, '"');
        !           428:        efree(utf16);
        !           429: }
        !           430: /* }}} */
        !           431: 
        !           432: PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */
        !           433: {
        !           434:        switch (Z_TYPE_P(val))
        !           435:        {
        !           436:                case IS_NULL:
        !           437:                        smart_str_appendl(buf, "null", 4);
        !           438:                        break;
        !           439: 
        !           440:                case IS_BOOL:
        !           441:                        if (Z_BVAL_P(val)) {
        !           442:                                smart_str_appendl(buf, "true", 4);
        !           443:                        } else {
        !           444:                                smart_str_appendl(buf, "false", 5);
        !           445:                        }
        !           446:                        break;
        !           447: 
        !           448:                case IS_LONG:
        !           449:                        smart_str_append_long(buf, Z_LVAL_P(val));
        !           450:                        break;
        !           451: 
        !           452:                case IS_DOUBLE:
        !           453:                        {
        !           454:                                char *d = NULL;
        !           455:                                int len;
        !           456:                                double dbl = Z_DVAL_P(val);
        !           457: 
        !           458:                                if (!zend_isinf(dbl) && !zend_isnan(dbl)) {
        !           459:                                        len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl);
        !           460:                                        smart_str_appendl(buf, d, len);
        !           461:                                        efree(d);
        !           462:                                } else {
        !           463:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
        !           464:                                        smart_str_appendc(buf, '0');
        !           465:                                }
        !           466:                        }
        !           467:                        break;
        !           468: 
        !           469:                case IS_STRING:
        !           470:                        json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options TSRMLS_CC);
        !           471:                        break;
        !           472: 
        !           473:                case IS_ARRAY:
        !           474:                case IS_OBJECT:
        !           475:                        json_encode_array(buf, &val, options TSRMLS_CC);
        !           476:                        break;
        !           477: 
        !           478:                default:
        !           479:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
        !           480:                        smart_str_appendl(buf, "null", 4);
        !           481:                        break;
        !           482:        }
        !           483: 
        !           484:        return;
        !           485: }
        !           486: /* }}} */
        !           487: 
        !           488: PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC) /* {{{ */
        !           489: {
        !           490:        int utf16_len;
        !           491:        zval *z;
        !           492:        unsigned short *utf16;
        !           493:        JSON_parser jp;
        !           494: 
        !           495:        utf16 = (unsigned short *) safe_emalloc((str_len+1), sizeof(unsigned short), 1);
        !           496: 
        !           497:        utf16_len = utf8_to_utf16(utf16, str, str_len);
        !           498:        if (utf16_len <= 0) {
        !           499:                if (utf16) {
        !           500:                        efree(utf16);
        !           501:                }
        !           502:                JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
        !           503:                RETURN_NULL();
        !           504:        }
        !           505: 
        !           506:        if (depth <= 0) {
        !           507:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Depth must be greater than zero");
        !           508:                efree(utf16);
        !           509:                RETURN_NULL();
        !           510:        }
        !           511: 
        !           512:        ALLOC_INIT_ZVAL(z);
        !           513:        jp = new_JSON_parser(depth);
        !           514:        if (parse_JSON(jp, z, utf16, utf16_len, assoc TSRMLS_CC)) {
        !           515:                *return_value = *z;
        !           516:        }
        !           517:        else
        !           518:        {
        !           519:                double d;
        !           520:                int type;
        !           521:                long p;
        !           522: 
        !           523:                RETVAL_NULL();
        !           524:                if (str_len == 4) {
        !           525:                        if (!strcasecmp(str, "null")) {
        !           526:                                /* We need to explicitly clear the error because its an actual NULL and not an error */
        !           527:                                jp->error_code = PHP_JSON_ERROR_NONE;
        !           528:                                RETVAL_NULL();
        !           529:                        } else if (!strcasecmp(str, "true")) {
        !           530:                                RETVAL_BOOL(1);
        !           531:                        }
        !           532:                } else if (str_len == 5 && !strcasecmp(str, "false")) {
        !           533:                        RETVAL_BOOL(0);
        !           534:                }
        !           535: 
        !           536:                if ((type = is_numeric_string(str, str_len, &p, &d, 0)) != 0) {
        !           537:                        if (type == IS_LONG) {
        !           538:                                RETVAL_LONG(p);
        !           539:                        } else if (type == IS_DOUBLE) {
        !           540:                                RETVAL_DOUBLE(d);
        !           541:                        }
        !           542:                }
        !           543: 
        !           544:                if (Z_TYPE_P(return_value) != IS_NULL) {
        !           545:                        jp->error_code = PHP_JSON_ERROR_NONE;
        !           546:                }
        !           547: 
        !           548:                zval_dtor(z);
        !           549:        }
        !           550:        FREE_ZVAL(z);
        !           551:        efree(utf16);
        !           552:        JSON_G(error_code) = jp->error_code;
        !           553:        free_JSON_parser(jp);
        !           554: }
        !           555: /* }}} */
        !           556: 
        !           557: /* {{{ proto string json_encode(mixed data [, int options])
        !           558:    Returns the JSON representation of a value */
        !           559: static PHP_FUNCTION(json_encode)
        !           560: {
        !           561:        zval *parameter;
        !           562:        smart_str buf = {0};
        !           563:        long options = 0;
        !           564: 
        !           565:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &parameter, &options) == FAILURE) {
        !           566:                return;
        !           567:        }
        !           568: 
        !           569:        JSON_G(error_code) = PHP_JSON_ERROR_NONE;
        !           570: 
        !           571:        php_json_encode(&buf, parameter, options TSRMLS_CC);
        !           572: 
        !           573:        ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
        !           574: 
        !           575:        smart_str_free(&buf);
        !           576: }
        !           577: /* }}} */
        !           578: 
        !           579: /* {{{ proto mixed json_decode(string json [, bool assoc [, long depth]])
        !           580:    Decodes the JSON representation into a PHP value */
        !           581: static PHP_FUNCTION(json_decode)
        !           582: {
        !           583:        char *str;
        !           584:        int str_len;
        !           585:        zend_bool assoc = 0; /* return JS objects as PHP objects by default */
        !           586:        long depth = JSON_PARSER_DEFAULT_DEPTH;
        !           587: 
        !           588:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &str, &str_len, &assoc, &depth) == FAILURE) {
        !           589:                return;
        !           590:        }
        !           591: 
        !           592:        JSON_G(error_code) = 0;
        !           593: 
        !           594:        if (!str_len) {
        !           595:                RETURN_NULL();
        !           596:        }
        !           597: 
        !           598:        php_json_decode(return_value, str, str_len, assoc, depth TSRMLS_CC);
        !           599: }
        !           600: /* }}} */
        !           601: 
        !           602: /* {{{ proto int json_last_error()
        !           603:    Returns the error code of the last json_decode(). */
        !           604: static PHP_FUNCTION(json_last_error)
        !           605: {
        !           606:        if (zend_parse_parameters_none() == FAILURE) {
        !           607:                return;
        !           608:        }
        !           609: 
        !           610:        RETURN_LONG(JSON_G(error_code));
        !           611: }
        !           612: /* }}} */
        !           613: 
        !           614: /*
        !           615:  * Local variables:
        !           616:  * tab-width: 4
        !           617:  * c-basic-offset: 4
        !           618:  * End:
        !           619:  * vim600: noet sw=4 ts=4 fdm=marker
        !           620:  * vim<600: noet sw=4 ts=4
        !           621:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>