Annotation of embedaddon/php/ext/xml/xml.c, revision 1.1.1.2

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:    | Authors: Stig Sæther Bakken <ssb@php.net>                            |
                     16:    |          Thies C. Arntzen <thies@thieso.net>                         |
                     17:    |          Sterling Hughes <sterling@php.net>                          |
                     18:    +----------------------------------------------------------------------+
                     19:  */
                     20: 
1.1.1.2 ! misho      21: /* $Id$ */
1.1       misho      22: 
                     23: #define IS_EXT_MODULE
                     24: 
                     25: #ifdef HAVE_CONFIG_H
                     26: #include "config.h"
                     27: #endif
                     28: 
                     29: #include "php.h"
                     30: 
                     31: #define PHP_XML_INTERNAL
                     32: #include "zend_variables.h"
                     33: #include "ext/standard/php_string.h"
                     34: #include "ext/standard/info.h"
1.1.1.2 ! misho      35: #include "ext/standard/html.h"
1.1       misho      36: 
                     37: #if HAVE_XML
                     38: 
                     39: #include "php_xml.h"
                     40: # include "ext/standard/head.h"
                     41: #ifdef LIBXML_EXPAT_COMPAT
                     42: #include "ext/libxml/php_libxml.h"
                     43: #endif
                     44: 
                     45: /* Short-term TODO list:
                     46:  * - Implement XML_ExternalEntityParserCreate()
                     47:  * - XML_SetCommentHandler
                     48:  * - XML_SetCdataSectionHandler
                     49:  * - XML_SetParamEntityParsing
                     50:  */
                     51: 
                     52: /* Long-term TODO list:
                     53:  * - Fix the expat library so you can install your own memory manager
                     54:  *   functions
                     55:  */
                     56: 
                     57: /* Known bugs:
                     58:  * - Weird things happen with <![CDATA[]]> sections.
                     59:  */
                     60: 
                     61: ZEND_DECLARE_MODULE_GLOBALS(xml)
                     62: 
                     63: /* {{{ dynamically loadable module stuff */
                     64: #ifdef COMPILE_DL_XML
                     65: ZEND_GET_MODULE(xml)
                     66: #endif /* COMPILE_DL_XML */
                     67: /* }}} */
                     68: 
                     69: /* {{{ function prototypes */
                     70: PHP_MINIT_FUNCTION(xml);
                     71: PHP_MINFO_FUNCTION(xml);
                     72: static PHP_GINIT_FUNCTION(xml);
                     73: 
                     74: static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
                     75: static void xml_set_handler(zval **, zval **);
                     76: inline static unsigned short xml_encode_iso_8859_1(unsigned char);
                     77: inline static char xml_decode_iso_8859_1(unsigned short);
                     78: inline static unsigned short xml_encode_us_ascii(unsigned char);
                     79: inline static char xml_decode_us_ascii(unsigned short);
                     80: static zval *xml_call_handler(xml_parser *, zval *, zend_function *, int, zval **);
                     81: static zval *_xml_xmlchar_zval(const XML_Char *, int, const XML_Char *);
                     82: static int _xml_xmlcharlen(const XML_Char *);
                     83: static void _xml_add_to_info(xml_parser *parser,char *name);
                     84: inline static char *_xml_decode_tag(xml_parser *parser, const char *tag);
                     85: 
                     86: void _xml_startElementHandler(void *, const XML_Char *, const XML_Char **);
                     87: void _xml_endElementHandler(void *, const XML_Char *);
                     88: void _xml_characterDataHandler(void *, const XML_Char *, int);
                     89: void _xml_processingInstructionHandler(void *, const XML_Char *, const XML_Char *);
                     90: void _xml_defaultHandler(void *, const XML_Char *, int);
                     91: void _xml_unparsedEntityDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
                     92: void _xml_notationDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
                     93: int  _xml_externalEntityRefHandler(XML_Parser, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
                     94: 
                     95: void _xml_startNamespaceDeclHandler(void *, const XML_Char *, const XML_Char *);
                     96: void _xml_endNamespaceDeclHandler(void *, const XML_Char *);
                     97: /* }}} */
                     98: 
                     99: /* {{{ extension definition structures */
                    100: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_create, 0, 0, 0)
                    101:        ZEND_ARG_INFO(0, encoding)
                    102: ZEND_END_ARG_INFO()
                    103: 
                    104: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_create_ns, 0, 0, 0)
                    105:        ZEND_ARG_INFO(0, encoding)
                    106:        ZEND_ARG_INFO(0, sep)
                    107: ZEND_END_ARG_INFO()
                    108: 
                    109: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_object, 0, 0, 2)
                    110:        ZEND_ARG_INFO(0, parser)
                    111:        ZEND_ARG_INFO(1, obj)
                    112: ZEND_END_ARG_INFO()
                    113: 
                    114: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_element_handler, 0, 0, 3)
                    115:        ZEND_ARG_INFO(0, parser)
                    116:        ZEND_ARG_INFO(0, shdl)
                    117:        ZEND_ARG_INFO(0, ehdl)
                    118: ZEND_END_ARG_INFO()
                    119: 
                    120: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_character_data_handler, 0, 0, 2)
                    121:        ZEND_ARG_INFO(0, parser)
                    122:        ZEND_ARG_INFO(0, hdl)
                    123: ZEND_END_ARG_INFO()
                    124: 
                    125: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_processing_instruction_handler, 0, 0, 2)
                    126:        ZEND_ARG_INFO(0, parser)
                    127:        ZEND_ARG_INFO(0, hdl)
                    128: ZEND_END_ARG_INFO()
                    129: 
                    130: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_default_handler, 0, 0, 2)
                    131:        ZEND_ARG_INFO(0, parser)
                    132:        ZEND_ARG_INFO(0, hdl)
                    133: ZEND_END_ARG_INFO()
                    134: 
                    135: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_unparsed_entity_decl_handler, 0, 0, 2)
                    136:        ZEND_ARG_INFO(0, parser)
                    137:        ZEND_ARG_INFO(0, hdl)
                    138: ZEND_END_ARG_INFO()
                    139: 
                    140: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_notation_decl_handler, 0, 0, 2)
                    141:        ZEND_ARG_INFO(0, parser)
                    142:        ZEND_ARG_INFO(0, hdl)
                    143: ZEND_END_ARG_INFO()
                    144: 
                    145: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_external_entity_ref_handler, 0, 0, 2)
                    146:        ZEND_ARG_INFO(0, parser)
                    147:        ZEND_ARG_INFO(0, hdl)
                    148: ZEND_END_ARG_INFO()
                    149: 
                    150: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_start_namespace_decl_handler, 0, 0, 2)
                    151:        ZEND_ARG_INFO(0, parser)
                    152:        ZEND_ARG_INFO(0, hdl)
                    153: ZEND_END_ARG_INFO()
                    154: 
                    155: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_end_namespace_decl_handler, 0, 0, 2)
                    156:        ZEND_ARG_INFO(0, parser)
                    157:        ZEND_ARG_INFO(0, hdl)
                    158: ZEND_END_ARG_INFO()
                    159: 
                    160: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parse, 0, 0, 2)
                    161:        ZEND_ARG_INFO(0, parser)
                    162:        ZEND_ARG_INFO(0, data)
                    163:        ZEND_ARG_INFO(0, isfinal)
                    164: ZEND_END_ARG_INFO()
                    165: 
                    166: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parse_into_struct, 0, 0, 3)
                    167:        ZEND_ARG_INFO(0, parser)
                    168:        ZEND_ARG_INFO(0, data)
                    169:        ZEND_ARG_INFO(1, values)
                    170:        ZEND_ARG_INFO(1, index)
                    171: ZEND_END_ARG_INFO()
                    172: 
                    173: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_error_code, 0, 0, 1)
                    174:        ZEND_ARG_INFO(0, parser)
                    175: ZEND_END_ARG_INFO()
                    176: 
                    177: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_error_string, 0, 0, 1)
                    178:        ZEND_ARG_INFO(0, code)
                    179: ZEND_END_ARG_INFO()
                    180: 
                    181: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_line_number, 0, 0, 1)
                    182:        ZEND_ARG_INFO(0, parser)
                    183: ZEND_END_ARG_INFO()
                    184: 
                    185: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_column_number, 0, 0, 1)
                    186:        ZEND_ARG_INFO(0, parser)
                    187: ZEND_END_ARG_INFO()
                    188: 
                    189: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_byte_index, 0, 0, 1)
                    190:        ZEND_ARG_INFO(0, parser)
                    191: ZEND_END_ARG_INFO()
                    192: 
                    193: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_free, 0, 0, 1)
                    194:        ZEND_ARG_INFO(0, parser)
                    195: ZEND_END_ARG_INFO()
                    196: 
                    197: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_set_option, 0, 0, 3)
                    198:        ZEND_ARG_INFO(0, parser)
                    199:        ZEND_ARG_INFO(0, option)
                    200:        ZEND_ARG_INFO(0, value)
                    201: ZEND_END_ARG_INFO()
                    202: 
                    203: ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_get_option, 0, 0, 2)
                    204:        ZEND_ARG_INFO(0, parser)
                    205:        ZEND_ARG_INFO(0, option)
                    206: ZEND_END_ARG_INFO()
                    207: 
                    208: ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_encode, 0, 0, 1)
                    209:        ZEND_ARG_INFO(0, data)
                    210: ZEND_END_ARG_INFO()
                    211: 
                    212: ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_decode, 0, 0, 1)
                    213:        ZEND_ARG_INFO(0, data)
                    214: ZEND_END_ARG_INFO()
                    215: 
                    216: const zend_function_entry xml_functions[] = {
                    217:        PHP_FE(xml_parser_create,                                       arginfo_xml_parser_create)
                    218:        PHP_FE(xml_parser_create_ns,                            arginfo_xml_parser_create_ns)
                    219:        PHP_FE(xml_set_object,                                          arginfo_xml_set_object)
                    220:        PHP_FE(xml_set_element_handler,                         arginfo_xml_set_element_handler)
                    221:        PHP_FE(xml_set_character_data_handler,          arginfo_xml_set_character_data_handler)
                    222:        PHP_FE(xml_set_processing_instruction_handler,  arginfo_xml_set_processing_instruction_handler)
                    223:        PHP_FE(xml_set_default_handler,                                 arginfo_xml_set_default_handler)
                    224:        PHP_FE(xml_set_unparsed_entity_decl_handler,arginfo_xml_set_unparsed_entity_decl_handler)
                    225:        PHP_FE(xml_set_notation_decl_handler,           arginfo_xml_set_notation_decl_handler)
                    226:        PHP_FE(xml_set_external_entity_ref_handler,     arginfo_xml_set_external_entity_ref_handler)
                    227:        PHP_FE(xml_set_start_namespace_decl_handler,arginfo_xml_set_start_namespace_decl_handler)
                    228:        PHP_FE(xml_set_end_namespace_decl_handler,      arginfo_xml_set_end_namespace_decl_handler)
                    229:        PHP_FE(xml_parse,                                                       arginfo_xml_parse)
                    230:        PHP_FE(xml_parse_into_struct,                           arginfo_xml_parse_into_struct)
                    231:        PHP_FE(xml_get_error_code,                                      arginfo_xml_get_error_code)
                    232:        PHP_FE(xml_error_string,                                        arginfo_xml_error_string)
                    233:        PHP_FE(xml_get_current_line_number,                     arginfo_xml_get_current_line_number)
                    234:        PHP_FE(xml_get_current_column_number,           arginfo_xml_get_current_column_number)
                    235:        PHP_FE(xml_get_current_byte_index,                      arginfo_xml_get_current_byte_index)
                    236:        PHP_FE(xml_parser_free,                                         arginfo_xml_parser_free)
                    237:        PHP_FE(xml_parser_set_option,                           arginfo_xml_parser_set_option)
                    238:        PHP_FE(xml_parser_get_option,                           arginfo_xml_parser_get_option)
                    239:        PHP_FE(utf8_encode,                                             arginfo_utf8_encode)
                    240:        PHP_FE(utf8_decode,                                             arginfo_utf8_decode)
                    241:        PHP_FE_END
                    242: };
                    243: 
                    244: #ifdef LIBXML_EXPAT_COMPAT
                    245: static const zend_module_dep xml_deps[] = {
                    246:        ZEND_MOD_REQUIRED("libxml")
                    247:        ZEND_MOD_END
                    248: };
                    249: #endif
                    250: 
                    251: zend_module_entry xml_module_entry = {
                    252: #ifdef LIBXML_EXPAT_COMPAT
                    253:     STANDARD_MODULE_HEADER_EX, NULL,
                    254:        xml_deps,
                    255: #else
                    256:     STANDARD_MODULE_HEADER,
                    257: #endif
                    258:        "xml",                /* extension name */
                    259:        xml_functions,        /* extension function list */
                    260:        PHP_MINIT(xml),       /* extension-wide startup function */
                    261:        NULL,                 /* extension-wide shutdown function */
                    262:        NULL,                 /* per-request startup function */
                    263:        NULL,                 /* per-request shutdown function */
                    264:        PHP_MINFO(xml),       /* information function */
                    265:     NO_VERSION_YET,
                    266:     PHP_MODULE_GLOBALS(xml), /* globals descriptor */
                    267:     PHP_GINIT(xml),          /* globals ctor */
                    268:     NULL,                    /* globals dtor */
                    269:     NULL,                    /* post deactivate */
                    270:        STANDARD_MODULE_PROPERTIES_EX
                    271: };
                    272: 
                    273: /* All the encoding functions are set to NULL right now, since all
                    274:  * the encoding is currently done internally by expat/xmltok.
                    275:  */
                    276: xml_encoding xml_encodings[] = {
                    277:        { "ISO-8859-1", xml_decode_iso_8859_1, xml_encode_iso_8859_1 },
                    278:        { "US-ASCII",   xml_decode_us_ascii,   xml_encode_us_ascii   },
                    279:        { "UTF-8",      NULL,                  NULL                  },
                    280:        { NULL,         NULL,                  NULL                  }
                    281: };
                    282: 
                    283: static XML_Memory_Handling_Suite php_xml_mem_hdlrs;
                    284: 
                    285: /* True globals, no need for thread safety */
                    286: static int le_xml_parser; 
                    287: 
                    288: /* }}} */
                    289: 
                    290: /* {{{ startup, shutdown and info functions */
                    291: static PHP_GINIT_FUNCTION(xml)
                    292: {
                    293:        xml_globals->default_encoding = "UTF-8";
                    294: }
                    295: 
                    296: static void *php_xml_malloc_wrapper(size_t sz)
                    297: {
                    298:        return emalloc(sz);
                    299: }
                    300: 
                    301: static void *php_xml_realloc_wrapper(void *ptr, size_t sz)
                    302: {
                    303:        return erealloc(ptr, sz);
                    304: }
                    305: 
                    306: static void php_xml_free_wrapper(void *ptr)
                    307: {
                    308:        if (ptr != NULL) {
                    309:                efree(ptr);
                    310:        }
                    311: }
                    312: 
                    313: PHP_MINIT_FUNCTION(xml)
                    314: {
                    315:        le_xml_parser = zend_register_list_destructors_ex(xml_parser_dtor, NULL, "xml", module_number);
                    316: 
                    317:        REGISTER_LONG_CONSTANT("XML_ERROR_NONE", XML_ERROR_NONE, CONST_CS|CONST_PERSISTENT);
                    318:        REGISTER_LONG_CONSTANT("XML_ERROR_NO_MEMORY", XML_ERROR_NO_MEMORY, CONST_CS|CONST_PERSISTENT);
                    319:        REGISTER_LONG_CONSTANT("XML_ERROR_SYNTAX", XML_ERROR_SYNTAX, CONST_CS|CONST_PERSISTENT);
                    320:        REGISTER_LONG_CONSTANT("XML_ERROR_NO_ELEMENTS", XML_ERROR_NO_ELEMENTS, CONST_CS|CONST_PERSISTENT);
                    321:        REGISTER_LONG_CONSTANT("XML_ERROR_INVALID_TOKEN", XML_ERROR_INVALID_TOKEN, CONST_CS|CONST_PERSISTENT);
                    322:        REGISTER_LONG_CONSTANT("XML_ERROR_UNCLOSED_TOKEN", XML_ERROR_UNCLOSED_TOKEN, CONST_CS|CONST_PERSISTENT);
                    323:        REGISTER_LONG_CONSTANT("XML_ERROR_PARTIAL_CHAR", XML_ERROR_PARTIAL_CHAR, CONST_CS|CONST_PERSISTENT);
                    324:        REGISTER_LONG_CONSTANT("XML_ERROR_TAG_MISMATCH", XML_ERROR_TAG_MISMATCH, CONST_CS|CONST_PERSISTENT);
                    325:        REGISTER_LONG_CONSTANT("XML_ERROR_DUPLICATE_ATTRIBUTE", XML_ERROR_DUPLICATE_ATTRIBUTE, CONST_CS|CONST_PERSISTENT);
                    326:        REGISTER_LONG_CONSTANT("XML_ERROR_JUNK_AFTER_DOC_ELEMENT", XML_ERROR_JUNK_AFTER_DOC_ELEMENT, CONST_CS|CONST_PERSISTENT);
                    327:        REGISTER_LONG_CONSTANT("XML_ERROR_PARAM_ENTITY_REF", XML_ERROR_PARAM_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
                    328:        REGISTER_LONG_CONSTANT("XML_ERROR_UNDEFINED_ENTITY", XML_ERROR_UNDEFINED_ENTITY, CONST_CS|CONST_PERSISTENT);
                    329:        REGISTER_LONG_CONSTANT("XML_ERROR_RECURSIVE_ENTITY_REF", XML_ERROR_RECURSIVE_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
                    330:        REGISTER_LONG_CONSTANT("XML_ERROR_ASYNC_ENTITY", XML_ERROR_ASYNC_ENTITY, CONST_CS|CONST_PERSISTENT);
                    331:        REGISTER_LONG_CONSTANT("XML_ERROR_BAD_CHAR_REF", XML_ERROR_BAD_CHAR_REF, CONST_CS|CONST_PERSISTENT);
                    332:        REGISTER_LONG_CONSTANT("XML_ERROR_BINARY_ENTITY_REF", XML_ERROR_BINARY_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
                    333:        REGISTER_LONG_CONSTANT("XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF", XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
                    334:        REGISTER_LONG_CONSTANT("XML_ERROR_MISPLACED_XML_PI", XML_ERROR_MISPLACED_XML_PI, CONST_CS|CONST_PERSISTENT);
                    335:        REGISTER_LONG_CONSTANT("XML_ERROR_UNKNOWN_ENCODING", XML_ERROR_UNKNOWN_ENCODING, CONST_CS|CONST_PERSISTENT);
                    336:        REGISTER_LONG_CONSTANT("XML_ERROR_INCORRECT_ENCODING", XML_ERROR_INCORRECT_ENCODING, CONST_CS|CONST_PERSISTENT);
                    337:        REGISTER_LONG_CONSTANT("XML_ERROR_UNCLOSED_CDATA_SECTION", XML_ERROR_UNCLOSED_CDATA_SECTION, CONST_CS|CONST_PERSISTENT);
                    338:        REGISTER_LONG_CONSTANT("XML_ERROR_EXTERNAL_ENTITY_HANDLING", XML_ERROR_EXTERNAL_ENTITY_HANDLING, CONST_CS|CONST_PERSISTENT);
                    339: 
                    340:        REGISTER_LONG_CONSTANT("XML_OPTION_CASE_FOLDING", PHP_XML_OPTION_CASE_FOLDING, CONST_CS|CONST_PERSISTENT);
                    341:        REGISTER_LONG_CONSTANT("XML_OPTION_TARGET_ENCODING", PHP_XML_OPTION_TARGET_ENCODING, CONST_CS|CONST_PERSISTENT);
                    342:        REGISTER_LONG_CONSTANT("XML_OPTION_SKIP_TAGSTART", PHP_XML_OPTION_SKIP_TAGSTART, CONST_CS|CONST_PERSISTENT);
                    343:        REGISTER_LONG_CONSTANT("XML_OPTION_SKIP_WHITE", PHP_XML_OPTION_SKIP_WHITE, CONST_CS|CONST_PERSISTENT);
                    344: 
                    345:        /* this object should not be pre-initialised at compile time,
                    346:           as the order of members may vary */  
                    347: 
                    348:        php_xml_mem_hdlrs.malloc_fcn = php_xml_malloc_wrapper;
                    349:        php_xml_mem_hdlrs.realloc_fcn = php_xml_realloc_wrapper;
                    350:        php_xml_mem_hdlrs.free_fcn = php_xml_free_wrapper;
                    351: 
                    352: #ifdef LIBXML_EXPAT_COMPAT
                    353:        REGISTER_STRING_CONSTANT("XML_SAX_IMPL", "libxml", CONST_CS|CONST_PERSISTENT);
                    354: #else
                    355:        REGISTER_STRING_CONSTANT("XML_SAX_IMPL", "expat", CONST_CS|CONST_PERSISTENT);
                    356: #endif
                    357: 
                    358:        return SUCCESS;
                    359: }
                    360: 
                    361: PHP_MINFO_FUNCTION(xml)
                    362: {
                    363:        php_info_print_table_start();
                    364:        php_info_print_table_row(2, "XML Support", "active");
                    365:        php_info_print_table_row(2, "XML Namespace Support", "active");
                    366: #if defined(LIBXML_DOTTED_VERSION) && defined(LIBXML_EXPAT_COMPAT)
                    367:        php_info_print_table_row(2, "libxml2 Version", LIBXML_DOTTED_VERSION);
                    368: #else
                    369:        php_info_print_table_row(2, "EXPAT Version", XML_ExpatVersion());
                    370: #endif
                    371:        php_info_print_table_end();
                    372: }
                    373: /* }}} */
                    374: 
                    375: /* {{{ extension-internal functions */
                    376: static zval *_xml_resource_zval(long value)
                    377: {
                    378:        zval *ret;
                    379:        TSRMLS_FETCH();
                    380: 
                    381:        MAKE_STD_ZVAL(ret);
                    382: 
                    383:        Z_TYPE_P(ret) = IS_RESOURCE;
                    384:        Z_LVAL_P(ret) = value;
                    385: 
                    386:        zend_list_addref(value);
                    387: 
                    388:        return ret;
                    389: }
                    390: 
                    391: static zval *_xml_string_zval(const char *str)
                    392: {
                    393:        zval *ret;
                    394:        int len = strlen(str);
                    395:        MAKE_STD_ZVAL(ret);
                    396: 
                    397:        Z_TYPE_P(ret) = IS_STRING;
                    398:        Z_STRLEN_P(ret) = len;
                    399:        Z_STRVAL_P(ret) = estrndup(str, len);
                    400:        return ret;
                    401: }
                    402: 
                    403: static zval *_xml_xmlchar_zval(const XML_Char *s, int len, const XML_Char *encoding)
                    404: {
                    405:        zval *ret;
                    406:        MAKE_STD_ZVAL(ret);
                    407:        
                    408:        if (s == NULL) {
                    409:                ZVAL_FALSE(ret);
                    410:                return ret;
                    411:        }
                    412:        if (len == 0) {
                    413:                len = _xml_xmlcharlen(s);
                    414:        }
                    415:        Z_TYPE_P(ret) = IS_STRING;
                    416:        Z_STRVAL_P(ret) = xml_utf8_decode(s, len, &Z_STRLEN_P(ret), encoding);
                    417:        return ret;
                    418: }
                    419: /* }}} */
                    420: 
                    421: /* {{{ xml_parser_dtor() */
                    422: static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
                    423: {
                    424:        xml_parser *parser = (xml_parser *)rsrc->ptr;
                    425:        
                    426:        if (parser->parser) {
                    427:                XML_ParserFree(parser->parser);
                    428:        }
                    429:        if (parser->ltags) {
                    430:                int inx;
                    431:                for (inx = 0; inx < parser->level; inx++)
                    432:                        efree(parser->ltags[ inx ]);
                    433:                efree(parser->ltags);
                    434:        }
                    435:        if (parser->startElementHandler) {
                    436:                zval_ptr_dtor(&parser->startElementHandler);
                    437:        }
                    438:        if (parser->endElementHandler) {
                    439:                zval_ptr_dtor(&parser->endElementHandler);
                    440:        }
                    441:        if (parser->characterDataHandler) {
                    442:                zval_ptr_dtor(&parser->characterDataHandler);
                    443:        }
                    444:        if (parser->processingInstructionHandler) {
                    445:                zval_ptr_dtor(&parser->processingInstructionHandler);
                    446:        }
                    447:        if (parser->defaultHandler) {
                    448:                zval_ptr_dtor(&parser->defaultHandler);
                    449:        }
                    450:        if (parser->unparsedEntityDeclHandler) {
                    451:                zval_ptr_dtor(&parser->unparsedEntityDeclHandler);
                    452:        }
                    453:        if (parser->notationDeclHandler) {
                    454:                zval_ptr_dtor(&parser->notationDeclHandler);
                    455:        }
                    456:        if (parser->externalEntityRefHandler) {
                    457:                zval_ptr_dtor(&parser->externalEntityRefHandler);
                    458:        }
                    459:        if (parser->unknownEncodingHandler) {
                    460:                zval_ptr_dtor(&parser->unknownEncodingHandler);
                    461:        }
                    462:        if (parser->startNamespaceDeclHandler) {
                    463:                zval_ptr_dtor(&parser->startNamespaceDeclHandler);
                    464:        }
                    465:        if (parser->endNamespaceDeclHandler) {
                    466:                zval_ptr_dtor(&parser->endNamespaceDeclHandler);
                    467:        }
                    468:        if (parser->baseURI) {
                    469:                efree(parser->baseURI);
                    470:        }
                    471:        if (parser->object) {
                    472:                zval_ptr_dtor(&parser->object);
                    473:        }
                    474: 
                    475:        efree(parser);
                    476: }
                    477: /* }}} */
                    478: 
                    479: /* {{{ xml_set_handler() */
                    480: static void xml_set_handler(zval **handler, zval **data)
                    481: {
                    482:        /* If we have already a handler, release it */
                    483:        if (*handler) {
                    484:                zval_ptr_dtor(handler);
                    485:        }
                    486: 
                    487:        /* IS_ARRAY might indicate that we're using array($obj, 'method') syntax */
                    488:        if (Z_TYPE_PP(data) != IS_ARRAY && Z_TYPE_PP(data) != IS_OBJECT) {
                    489: 
                    490:                convert_to_string_ex(data);
                    491:                if (Z_STRLEN_PP(data) == 0) {
                    492:                        *handler = NULL;
                    493:                        return;
                    494:                }
                    495:        }
                    496: 
                    497:        zval_add_ref(data);
                    498: 
                    499:        *handler = *data;
                    500: }
                    501: /* }}} */
                    502: 
                    503: /* {{{ xml_call_handler() */
                    504: static zval *xml_call_handler(xml_parser *parser, zval *handler, zend_function *function_ptr, int argc, zval **argv)
                    505: {
                    506:        int i;  
                    507:        TSRMLS_FETCH();
                    508: 
                    509:        if (parser && handler && !EG(exception)) {
                    510:                zval ***args;
                    511:                zval *retval;
                    512:                int result;
                    513:                zend_fcall_info fci;
                    514: 
                    515:                args = safe_emalloc(sizeof(zval **), argc, 0);
                    516:                for (i = 0; i < argc; i++) {
                    517:                        args[i] = &argv[i];
                    518:                }
                    519:                
                    520:                fci.size = sizeof(fci);
                    521:                fci.function_table = EG(function_table);
                    522:                fci.function_name = handler;
                    523:                fci.symbol_table = NULL;
                    524:                fci.object_ptr = parser->object;
                    525:                fci.retval_ptr_ptr = &retval;
                    526:                fci.param_count = argc;
                    527:                fci.params = args;
                    528:                fci.no_separation = 0;
                    529:                /*fci.function_handler_cache = &function_ptr;*/
                    530: 
                    531:                result = zend_call_function(&fci, NULL TSRMLS_CC);
                    532:                if (result == FAILURE) {
                    533:                        zval **method;
                    534:                        zval **obj;
                    535: 
                    536:                        if (Z_TYPE_P(handler) == IS_STRING) {
                    537:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(handler));
                    538:                        } else if (zend_hash_index_find(Z_ARRVAL_P(handler), 0, (void **) &obj) == SUCCESS &&
                    539:                                           zend_hash_index_find(Z_ARRVAL_P(handler), 1, (void **) &method) == SUCCESS &&
                    540:                                           Z_TYPE_PP(obj) == IS_OBJECT &&
                    541:                                           Z_TYPE_PP(method) == IS_STRING) {
                    542:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s::%s()", Z_OBJCE_PP(obj)->name, Z_STRVAL_PP(method));
                    543:                        } else 
                    544:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler");
                    545:                }
                    546: 
                    547:                for (i = 0; i < argc; i++) {
                    548:                        zval_ptr_dtor(args[i]);
                    549:                }
                    550:                efree(args);
                    551: 
                    552:                if (result == FAILURE) {
                    553:                        return NULL;
                    554:                } else {
                    555:                        return EG(exception) ? NULL : retval;
                    556:                }
                    557:        } else {
                    558:                for (i = 0; i < argc; i++) {
                    559:                        zval_ptr_dtor(&argv[i]);
                    560:                }
                    561:                return NULL;
                    562:        }
                    563: }
                    564: /* }}} */
                    565: 
                    566: /* {{{ xml_encode_iso_8859_1() */
                    567: inline static unsigned short xml_encode_iso_8859_1(unsigned char c)
                    568: {
                    569:        return (unsigned short)c;
                    570: }
                    571: /* }}} */
                    572: 
                    573: /* {{{ xml_decode_iso_8859_1() */
                    574: inline static char xml_decode_iso_8859_1(unsigned short c)
                    575: {
                    576:        return (char)(c > 0xff ? '?' : c);
                    577: }
                    578: /* }}} */
                    579: 
                    580: /* {{{ xml_encode_us_ascii() */
                    581: inline static unsigned short xml_encode_us_ascii(unsigned char c)
                    582: {
                    583:        return (unsigned short)c;
                    584: }
                    585: /* }}} */
                    586: 
                    587: /* {{{ xml_decode_us_ascii() */
                    588: inline static char xml_decode_us_ascii(unsigned short c)
                    589: {
                    590:        return (char)(c > 0x7f ? '?' : c);
                    591: }
                    592: /* }}} */
                    593: 
                    594: /* {{{ xml_get_encoding() */
                    595: static xml_encoding *xml_get_encoding(const XML_Char *name)
                    596: {
                    597:        xml_encoding *enc = &xml_encodings[0];
                    598: 
                    599:        while (enc && enc->name) {
                    600:                if (strcasecmp(name, enc->name) == 0) {
                    601:                        return enc;
                    602:                }
                    603:                enc++;
                    604:        }
                    605:        return NULL;
                    606: }
                    607: /* }}} */
                    608: 
                    609: /* {{{ xml_utf8_encode */
                    610: PHPAPI char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding)
                    611: {
                    612:        int pos = len;
                    613:        char *newbuf;
                    614:        unsigned int c;
                    615:        unsigned short (*encoder)(unsigned char) = NULL;
                    616:        xml_encoding *enc = xml_get_encoding(encoding);
                    617: 
                    618:        *newlen = 0;
                    619:        if (enc) {
                    620:                encoder = enc->encoding_function;
                    621:        } else {
                    622:                /* If the target encoding was unknown, fail */
                    623:                return NULL;
                    624:        }
                    625:        if (encoder == NULL) {
                    626:                /* If no encoder function was specified, return the data as-is.
                    627:                 */
                    628:                newbuf = emalloc(len + 1);
                    629:                memcpy(newbuf, s, len);
                    630:                *newlen = len;
                    631:                newbuf[*newlen] = '\0';
                    632:                return newbuf;
                    633:        }
                    634:        /* This is the theoretical max (will never get beyond len * 2 as long
                    635:         * as we are converting from single-byte characters, though) */
                    636:        newbuf = safe_emalloc(len, 4, 1);
                    637:        while (pos > 0) {
                    638:                c = encoder ? encoder((unsigned char)(*s)) : (unsigned short)(*s);
                    639:                if (c < 0x80) {
                    640:                        newbuf[(*newlen)++] = (char) c;
                    641:                } else if (c < 0x800) {
                    642:                        newbuf[(*newlen)++] = (0xc0 | (c >> 6));
                    643:                        newbuf[(*newlen)++] = (0x80 | (c & 0x3f));
                    644:                } else if (c < 0x10000) {
                    645:                        newbuf[(*newlen)++] = (0xe0 | (c >> 12));
                    646:                        newbuf[(*newlen)++] = (0xc0 | ((c >> 6) & 0x3f));
                    647:                        newbuf[(*newlen)++] = (0x80 | (c & 0x3f));
                    648:                } else if (c < 0x200000) {
                    649:                        newbuf[(*newlen)++] = (0xf0 | (c >> 18));
                    650:                        newbuf[(*newlen)++] = (0xe0 | ((c >> 12) & 0x3f));
                    651:                        newbuf[(*newlen)++] = (0xc0 | ((c >> 6) & 0x3f));
                    652:                        newbuf[(*newlen)++] = (0x80 | (c & 0x3f));
                    653:                }
                    654:                pos--;
                    655:                s++;
                    656:        }
                    657:        newbuf[*newlen] = 0;
                    658:        newbuf = erealloc(newbuf, (*newlen)+1);
                    659:        return newbuf;
                    660: }
                    661: /* }}} */
                    662: 
                    663: /* {{{ xml_utf8_decode */
                    664: PHPAPI char *xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_Char *encoding)
                    665: {
                    666:        size_t pos = 0;
                    667:        char *newbuf = emalloc(len + 1);
                    668:        unsigned int c;
                    669:        char (*decoder)(unsigned short) = NULL;
                    670:        xml_encoding *enc = xml_get_encoding(encoding);
                    671: 
                    672:        *newlen = 0;
                    673:        if (enc) {
                    674:                decoder = enc->decoding_function;
                    675:        }
                    676:        if (decoder == NULL) {
                    677:                /* If the target encoding was unknown, or no decoder function
                    678:                 * was specified, return the UTF-8-encoded data as-is.
                    679:                 */
                    680:                memcpy(newbuf, s, len);
                    681:                *newlen = len;
                    682:                newbuf[*newlen] = '\0';
                    683:                return newbuf;
                    684:        }
                    685: 
                    686:        while (pos < (size_t)len) {
                    687:                int status = FAILURE;
                    688:                c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status);
                    689: 
                    690:                if (status == FAILURE || c > 0xFFU) {
                    691:                        c = '?';
                    692:                }
                    693: 
                    694:                newbuf[*newlen] = decoder ? decoder(c) : c;
                    695:                ++*newlen;
                    696:        }
                    697:        if (*newlen < len) {
                    698:                newbuf = erealloc(newbuf, *newlen + 1);
                    699:        }
                    700:        newbuf[*newlen] = '\0';
                    701:        return newbuf;
                    702: }
                    703: /* }}} */
                    704: 
                    705: /* {{{ _xml_xmlcharlen() */
                    706: static int _xml_xmlcharlen(const XML_Char *s)
                    707: {
                    708:        int len = 0;
                    709: 
                    710:        while (*s) {
                    711:                len++;
                    712:                s++;
                    713:        }
                    714:        return len;
                    715: }
                    716: /* }}} */
                    717: 
                    718: /* {{{ _xml_zval_strdup() */
                    719: PHPAPI char *_xml_zval_strdup(zval *val)
                    720: {
                    721:        if (Z_TYPE_P(val) == IS_STRING) {
                    722:                char *buf = emalloc(Z_STRLEN_P(val) + 1);
                    723:                memcpy(buf, Z_STRVAL_P(val), Z_STRLEN_P(val));
                    724:                buf[Z_STRLEN_P(val)] = '\0';
                    725:                return buf;
                    726:        }
                    727:        return NULL;
                    728: }
                    729: /* }}} */
                    730: 
                    731: /* {{{ _xml_add_to_info */
                    732: static void _xml_add_to_info(xml_parser *parser,char *name)
                    733: {
                    734:        zval **element, *values;
                    735: 
                    736:        if (! parser->info) {
                    737:                return;
                    738:        }
                    739: 
                    740:        if (zend_hash_find(Z_ARRVAL_P(parser->info),name,strlen(name) + 1,(void **) &element) == FAILURE) {
                    741:                MAKE_STD_ZVAL(values);
                    742:                
                    743:                array_init(values);
                    744:                
                    745:                zend_hash_update(Z_ARRVAL_P(parser->info), name, strlen(name)+1, (void *) &values, sizeof(zval*), (void **) &element);
                    746:        } 
                    747:                        
                    748:        add_next_index_long(*element,parser->curtag);
                    749:        
                    750:        parser->curtag++;
                    751: }
                    752: /* }}} */
                    753: 
                    754: /* {{{ _xml_decode_tag() */
                    755: static char *_xml_decode_tag(xml_parser *parser, const char *tag)
                    756: {
                    757:        char *newstr;
                    758:        int out_len;
                    759: 
                    760:        newstr = xml_utf8_decode(tag, strlen(tag), &out_len, parser->target_encoding);
                    761: 
                    762:        if (parser->case_folding) {
                    763:                php_strtoupper(newstr, out_len);
                    764:        }
                    765: 
                    766:        return newstr;
                    767: }
                    768: /* }}} */
                    769: 
                    770: /* {{{ _xml_startElementHandler() */
                    771: void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Char **attributes)
                    772: {
                    773:        xml_parser *parser = (xml_parser *)userData;
                    774:        const char **attrs = (const char **) attributes;
                    775:        char *tag_name;
                    776:        char *att, *val;
                    777:        int val_len;
                    778:        zval *retval, *args[3];
                    779: 
                    780:        if (parser) {
                    781:                parser->level++;
                    782: 
                    783:                tag_name = _xml_decode_tag(parser, name);
                    784: 
                    785:                if (parser->startElementHandler) {
                    786:                        args[0] = _xml_resource_zval(parser->index);
                    787:                        args[1] = _xml_string_zval(((char *) tag_name) + parser->toffset);
                    788:                        MAKE_STD_ZVAL(args[2]);
                    789:                        array_init(args[2]);
                    790: 
                    791:                        while (attributes && *attributes) {
                    792:                                att = _xml_decode_tag(parser, attributes[0]);
                    793:                                val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
                    794: 
                    795:                                add_assoc_stringl(args[2], att, val, val_len, 0);
                    796: 
                    797:                                attributes += 2;
                    798: 
                    799:                                efree(att);
                    800:                        }
                    801:                        
                    802:                        if ((retval = xml_call_handler(parser, parser->startElementHandler, parser->startElementPtr, 3, args))) {
                    803:                                zval_ptr_dtor(&retval);
                    804:                        }
                    805:                } 
                    806: 
                    807:                if (parser->data) {
                    808:                        zval *tag, *atr;
                    809:                        int atcnt = 0;
                    810: 
                    811:                        MAKE_STD_ZVAL(tag);
                    812:                        MAKE_STD_ZVAL(atr);
                    813: 
                    814:                        array_init(tag);
                    815:                        array_init(atr);
                    816: 
                    817:                        _xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
                    818: 
                    819:                        add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
                    820:                        add_assoc_string(tag,"type","open",1);
                    821:                        add_assoc_long(tag,"level",parser->level);
                    822: 
                    823:                        parser->ltags[parser->level-1] = estrdup(tag_name);
                    824:                        parser->lastwasopen = 1;
                    825: 
                    826:                        attributes = (const XML_Char **) attrs;
                    827: 
                    828:                        while (attributes && *attributes) {
                    829:                                att = _xml_decode_tag(parser, attributes[0]);
                    830:                                val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
                    831:                                
                    832:                                add_assoc_stringl(atr,att,val,val_len,0);
                    833: 
                    834:                                atcnt++;
                    835:                                attributes += 2;
                    836: 
                    837:                                efree(att);
                    838:                        }
                    839: 
                    840:                        if (atcnt) {
                    841:                                zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL);
                    842:                        } else {
                    843:                                zval_ptr_dtor(&atr);
                    844:                        }
                    845: 
                    846:                        zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag);
                    847:                }
                    848: 
                    849:                efree(tag_name);
                    850:        }
                    851: }
                    852: /* }}} */
                    853: 
                    854: /* {{{ _xml_endElementHandler() */
                    855: void _xml_endElementHandler(void *userData, const XML_Char *name)
                    856: {
                    857:        xml_parser *parser = (xml_parser *)userData;
                    858:        char *tag_name;
                    859: 
                    860:        if (parser) {
                    861:                zval *retval, *args[2];
                    862: 
                    863:                tag_name = _xml_decode_tag(parser, name);
                    864: 
                    865:                if (parser->endElementHandler) {
                    866:                        args[0] = _xml_resource_zval(parser->index);
                    867:                        args[1] = _xml_string_zval(((char *) tag_name) + parser->toffset);
                    868: 
                    869:                        if ((retval = xml_call_handler(parser, parser->endElementHandler, parser->endElementPtr, 2, args))) {
                    870:                                zval_ptr_dtor(&retval);
                    871:                        }
                    872:                } 
                    873: 
                    874:                if (parser->data) {
                    875:                        zval *tag;
                    876: 
                    877:                        if (parser->lastwasopen) {
                    878:                                add_assoc_string(*(parser->ctag),"type","complete",1);
                    879:                        } else {
                    880:                                MAKE_STD_ZVAL(tag);
                    881: 
                    882:                                array_init(tag);
                    883:                                  
                    884:                                _xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
                    885: 
                    886:                                add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
                    887:                                add_assoc_string(tag,"type","close",1);
                    888:                                add_assoc_long(tag,"level",parser->level);
                    889:                                  
                    890:                                zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
                    891:                        }
                    892: 
                    893:                        parser->lastwasopen = 0;
                    894:                }
                    895: 
                    896:                efree(tag_name);
                    897: 
                    898:                if (parser->ltags) {
                    899:                        efree(parser->ltags[parser->level-1]);
                    900:                }
                    901: 
                    902:                parser->level--;
                    903:        }
                    904: }
                    905: /* }}} */
                    906: 
                    907: /* {{{ _xml_characterDataHandler() */
                    908: void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)
                    909: {
                    910:        xml_parser *parser = (xml_parser *)userData;
                    911: 
                    912:        if (parser) {
                    913:                zval *retval, *args[2];
                    914: 
                    915:                if (parser->characterDataHandler) {
                    916:                        args[0] = _xml_resource_zval(parser->index);
                    917:                        args[1] = _xml_xmlchar_zval(s, len, parser->target_encoding);
                    918:                        if ((retval = xml_call_handler(parser, parser->characterDataHandler, parser->characterDataPtr, 2, args))) {
                    919:                                zval_ptr_dtor(&retval);
                    920:                        }
                    921:                } 
                    922: 
                    923:                if (parser->data) {
                    924:                        int i;
                    925:                        int doprint = 0;
                    926: 
                    927:                        char *decoded_value;
                    928:                        int decoded_len;
                    929:                        
                    930:                        decoded_value = xml_utf8_decode(s,len,&decoded_len,parser->target_encoding);
                    931:                        for (i = 0; i < decoded_len; i++) {
                    932:                                switch (decoded_value[i]) {
                    933:                                case ' ':
                    934:                                case '\t':
                    935:                                case '\n':
                    936:                                        continue;
                    937:                                default:
                    938:                                        doprint = 1;
                    939:                                        break;
                    940:                                }
                    941:                                if (doprint) {
                    942:                                        break;
                    943:                                }
                    944:                        }
                    945:                        if (doprint || (! parser->skipwhite)) {
                    946:                                if (parser->lastwasopen) {
                    947:                                        zval **myval;
                    948:                                        
                    949:                                        /* check if the current tag already has a value - if yes append to that! */
                    950:                                        if (zend_hash_find(Z_ARRVAL_PP(parser->ctag),"value",sizeof("value"),(void **) &myval) == SUCCESS) {
                    951:                                                int newlen = Z_STRLEN_PP(myval) + decoded_len;
                    952:                                                Z_STRVAL_PP(myval) = erealloc(Z_STRVAL_PP(myval),newlen+1);
                    953:                                                strncpy(Z_STRVAL_PP(myval) + Z_STRLEN_PP(myval), decoded_value, decoded_len + 1);
                    954:                                                Z_STRLEN_PP(myval) += decoded_len;
                    955:                                                efree(decoded_value);
                    956:                                        } else {
                    957:                                                add_assoc_string(*(parser->ctag),"value",decoded_value,0);
                    958:                                        }
                    959:                                        
                    960:                                } else {
                    961:                                        zval *tag;
                    962:                                        zval **curtag, **mytype, **myval;
                    963:                                        HashPosition hpos=NULL;
                    964: 
                    965:                                        zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(parser->data), &hpos);
                    966: 
                    967:                                        if (hpos && (zend_hash_get_current_data_ex(Z_ARRVAL_P(parser->data), (void **) &curtag, &hpos) == SUCCESS)) {
                    968:                                                if (zend_hash_find(Z_ARRVAL_PP(curtag),"type",sizeof("type"),(void **) &mytype) == SUCCESS) {
                    969:                                                        if (!strcmp(Z_STRVAL_PP(mytype), "cdata")) {
                    970:                                                                if (zend_hash_find(Z_ARRVAL_PP(curtag),"value",sizeof("value"),(void **) &myval) == SUCCESS) {
                    971:                                                                        int newlen = Z_STRLEN_PP(myval) + decoded_len;
                    972:                                                                        Z_STRVAL_PP(myval) = erealloc(Z_STRVAL_PP(myval),newlen+1);
                    973:                                                                        strncpy(Z_STRVAL_PP(myval) + Z_STRLEN_PP(myval), decoded_value, decoded_len + 1);
                    974:                                                                        Z_STRLEN_PP(myval) += decoded_len;
                    975:                                                                        efree(decoded_value);
                    976:                                                                        return;
                    977:                                                                }
                    978:                                                        }
                    979:                                                }
                    980:                                        }
                    981: 
                    982:                                        MAKE_STD_ZVAL(tag);
                    983:                                        
                    984:                                        array_init(tag);
                    985:                                        
                    986:                                        _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
                    987: 
                    988:                                        add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1);
                    989:                                        add_assoc_string(tag,"value",decoded_value,0);
                    990:                                        add_assoc_string(tag,"type","cdata",1);
                    991:                                        add_assoc_long(tag,"level",parser->level);
                    992: 
                    993:                                        zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
                    994:                                }
                    995:                        } else {
                    996:                                efree(decoded_value);
                    997:                        }
                    998:                }
                    999:        }
                   1000: }
                   1001: /* }}} */
                   1002: 
                   1003: /* {{{ _xml_processingInstructionHandler() */
                   1004: void _xml_processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data)
                   1005: {
                   1006:        xml_parser *parser = (xml_parser *)userData;
                   1007: 
                   1008:        if (parser && parser->processingInstructionHandler) {
                   1009:                zval *retval, *args[3];
                   1010: 
                   1011:                args[0] = _xml_resource_zval(parser->index);
                   1012:                args[1] = _xml_xmlchar_zval(target, 0, parser->target_encoding);
                   1013:                args[2] = _xml_xmlchar_zval(data, 0, parser->target_encoding);
                   1014:                if ((retval = xml_call_handler(parser, parser->processingInstructionHandler, parser->processingInstructionPtr, 3, args))) {
                   1015:                        zval_ptr_dtor(&retval);
                   1016:                }
                   1017:        }
                   1018: }
                   1019: /* }}} */
                   1020: 
                   1021: /* {{{ _xml_defaultHandler() */
                   1022: void _xml_defaultHandler(void *userData, const XML_Char *s, int len)
                   1023: {
                   1024:        xml_parser *parser = (xml_parser *)userData;
                   1025: 
                   1026:        if (parser && parser->defaultHandler) {
                   1027:                zval *retval, *args[2];
                   1028: 
                   1029:                args[0] = _xml_resource_zval(parser->index);
                   1030:                args[1] = _xml_xmlchar_zval(s, len, parser->target_encoding);
                   1031:                if ((retval = xml_call_handler(parser, parser->defaultHandler, parser->defaultPtr, 2, args))) {
                   1032:                        zval_ptr_dtor(&retval);
                   1033:                }
                   1034:        }
                   1035: }
                   1036: /* }}} */
                   1037: 
                   1038: /* {{{ _xml_unparsedEntityDeclHandler() */
                   1039: void _xml_unparsedEntityDeclHandler(void *userData, 
                   1040:                                                                                 const XML_Char *entityName, 
                   1041:                                                                                 const XML_Char *base,
                   1042:                                                                                 const XML_Char *systemId,
                   1043:                                                                                 const XML_Char *publicId,
                   1044:                                                                                 const XML_Char *notationName)
                   1045: {
                   1046:        xml_parser *parser = (xml_parser *)userData;
                   1047: 
                   1048:        if (parser && parser->unparsedEntityDeclHandler) {
                   1049:                zval *retval, *args[6];
                   1050: 
                   1051:                args[0] = _xml_resource_zval(parser->index);
                   1052:                args[1] = _xml_xmlchar_zval(entityName, 0, parser->target_encoding);
                   1053:                args[2] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
                   1054:                args[3] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
                   1055:                args[4] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
                   1056:                args[5] = _xml_xmlchar_zval(notationName, 0, parser->target_encoding);
                   1057:                if ((retval = xml_call_handler(parser, parser->unparsedEntityDeclHandler, parser->unparsedEntityDeclPtr, 6, args))) {
                   1058:                        zval_ptr_dtor(&retval);
                   1059:                }
                   1060:        }
                   1061: }
                   1062: /* }}} */
                   1063: 
                   1064: /* {{{ _xml_notationDeclHandler() */
                   1065: void _xml_notationDeclHandler(void *userData,
                   1066:                                                          const XML_Char *notationName,
                   1067:                                                          const XML_Char *base,
                   1068:                                                          const XML_Char *systemId,
                   1069:                                                          const XML_Char *publicId)
                   1070: {
                   1071:        xml_parser *parser = (xml_parser *)userData;
                   1072: 
                   1073:        if (parser && parser->notationDeclHandler) {
                   1074:                zval *retval, *args[5];
                   1075: 
                   1076:                args[0] = _xml_resource_zval(parser->index);
                   1077:                args[1] = _xml_xmlchar_zval(notationName, 0, parser->target_encoding);
                   1078:                args[2] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
                   1079:                args[3] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
                   1080:                args[4] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
                   1081:                if ((retval = xml_call_handler(parser, parser->notationDeclHandler, parser->notationDeclPtr, 5, args))) {
                   1082:                        zval_ptr_dtor(&retval);
                   1083:                }
                   1084:        }
                   1085: }
                   1086: /* }}} */
                   1087: 
                   1088: /* {{{ _xml_externalEntityRefHandler() */
                   1089: int _xml_externalEntityRefHandler(XML_Parser parserPtr,
                   1090:                                                                   const XML_Char *openEntityNames,
                   1091:                                                                   const XML_Char *base,
                   1092:                                                                   const XML_Char *systemId,
                   1093:                                                                   const XML_Char *publicId)
                   1094: {
                   1095:        xml_parser *parser = XML_GetUserData(parserPtr);
                   1096:        int ret = 0; /* abort if no handler is set (should be configurable?) */
                   1097: 
                   1098:        if (parser && parser->externalEntityRefHandler) {
                   1099:                zval *retval, *args[5];
                   1100: 
                   1101:                args[0] = _xml_resource_zval(parser->index);
                   1102:                args[1] = _xml_xmlchar_zval(openEntityNames, 0, parser->target_encoding);
                   1103:                args[2] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
                   1104:                args[3] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
                   1105:                args[4] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
                   1106:                if ((retval = xml_call_handler(parser, parser->externalEntityRefHandler, parser->externalEntityRefPtr, 5, args))) {
                   1107:                        convert_to_long(retval);
                   1108:                        ret = Z_LVAL_P(retval);
                   1109:                        efree(retval);
                   1110:                } else {
                   1111:                        ret = 0;
                   1112:                }
                   1113:        }
                   1114:        return ret;
                   1115: }
                   1116: /* }}} */
                   1117: 
                   1118: /* {{{ _xml_startNamespaceDeclHandler() */
                   1119: void _xml_startNamespaceDeclHandler(void *userData,const XML_Char *prefix, const XML_Char *uri)
                   1120: {
                   1121:        xml_parser *parser = (xml_parser *)userData;
                   1122: 
                   1123:        if (parser && parser->startNamespaceDeclHandler) {
                   1124:                zval *retval, *args[3];
                   1125: 
                   1126:                args[0] = _xml_resource_zval(parser->index);
                   1127:                args[1] = _xml_xmlchar_zval(prefix, 0, parser->target_encoding);
                   1128:                args[2] = _xml_xmlchar_zval(uri, 0, parser->target_encoding);
                   1129:                if ((retval = xml_call_handler(parser, parser->startNamespaceDeclHandler, parser->startNamespaceDeclPtr, 3, args))) {
                   1130:                        zval_ptr_dtor(&retval);
                   1131:                }
                   1132:        }
                   1133: }
                   1134: /* }}} */
                   1135: 
                   1136: /* {{{ _xml_endNamespaceDeclHandler() */
                   1137: void _xml_endNamespaceDeclHandler(void *userData, const XML_Char *prefix)
                   1138: {
                   1139:        xml_parser *parser = (xml_parser *)userData;
                   1140: 
                   1141:        if (parser && parser->endNamespaceDeclHandler) {
                   1142:                zval *retval, *args[2];
                   1143: 
                   1144:                args[0] = _xml_resource_zval(parser->index);
                   1145:                args[1] = _xml_xmlchar_zval(prefix, 0, parser->target_encoding);
                   1146:                if ((retval = xml_call_handler(parser, parser->endNamespaceDeclHandler, parser->endNamespaceDeclPtr, 2, args))) {
                   1147:                        zval_ptr_dtor(&retval);
                   1148:                }
                   1149:        }
                   1150: }
                   1151: /* }}} */
                   1152: 
                   1153: /************************* EXTENSION FUNCTIONS *************************/
                   1154: 
                   1155: static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_support) /* {{{ */
                   1156: {
                   1157:        xml_parser *parser;
                   1158:        int auto_detect = 0;
                   1159: 
                   1160:        char *encoding_param = NULL;
                   1161:        int encoding_param_len = 0;
                   1162: 
                   1163:        char *ns_param = NULL;
                   1164:        int ns_param_len = 0;
                   1165:        
                   1166:        XML_Char *encoding;
                   1167:        
                   1168:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (ns_support ? "|ss": "|s"), &encoding_param, &encoding_param_len, &ns_param, &ns_param_len) == FAILURE) {
                   1169:                RETURN_FALSE;
                   1170:        }
                   1171: 
                   1172:        if (encoding_param != NULL) {
                   1173:                /* The supported encoding types are hardcoded here because
                   1174:                 * we are limited to the encodings supported by expat/xmltok.
                   1175:                 */
                   1176:                if (encoding_param_len == 0) {
                   1177:                        encoding = XML(default_encoding);
                   1178:                        auto_detect = 1;
                   1179:                } else if (strcasecmp(encoding_param, "ISO-8859-1") == 0) {
                   1180:                        encoding = "ISO-8859-1";
                   1181:                } else if (strcasecmp(encoding_param, "UTF-8") == 0) {
                   1182:                        encoding = "UTF-8";
                   1183:                } else if (strcasecmp(encoding_param, "US-ASCII") == 0) {
                   1184:                        encoding = "US-ASCII";
                   1185:                } else {
                   1186:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "unsupported source encoding \"%s\"", encoding_param);
                   1187:                        RETURN_FALSE;
                   1188:                }
                   1189:        } else {
                   1190:                encoding = XML(default_encoding);
                   1191:        }
                   1192: 
                   1193:        if (ns_support && ns_param == NULL){
                   1194:                ns_param = ":";
                   1195:        }
                   1196: 
                   1197:        parser = ecalloc(1, sizeof(xml_parser));
                   1198:        parser->parser = XML_ParserCreate_MM((auto_detect ? NULL : encoding),
                   1199:                                          &php_xml_mem_hdlrs, ns_param);
                   1200: 
                   1201:        parser->target_encoding = encoding;
                   1202:        parser->case_folding = 1;
                   1203:        parser->object = NULL;
                   1204:        parser->isparsing = 0;
                   1205: 
                   1206:        XML_SetUserData(parser->parser, parser);
                   1207: 
                   1208:        ZEND_REGISTER_RESOURCE(return_value, parser,le_xml_parser);
                   1209:        parser->index = Z_LVAL_P(return_value);
                   1210: }
                   1211: /* }}} */
                   1212: 
                   1213: /* {{{ proto resource xml_parser_create([string encoding]) 
                   1214:    Create an XML parser */
                   1215: PHP_FUNCTION(xml_parser_create)
                   1216: {
                   1217:        php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);        
                   1218: }
                   1219: /* }}} */
                   1220: 
                   1221: /* {{{ proto resource xml_parser_create_ns([string encoding [, string sep]]) 
                   1222:    Create an XML parser */
                   1223: PHP_FUNCTION(xml_parser_create_ns)
                   1224: {
                   1225:        php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                   1226: }
                   1227: /* }}} */
                   1228: 
                   1229: /* {{{ proto int xml_set_object(resource parser, object &obj) 
                   1230:    Set up object which should be used for callbacks */
                   1231: PHP_FUNCTION(xml_set_object)
                   1232: {
                   1233:        xml_parser *parser;
                   1234:        zval *pind, *mythis;
                   1235: 
                   1236:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ro", &pind, &mythis) == FAILURE) {
                   1237:                return;
                   1238:        }
                   1239: 
                   1240:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1241: 
                   1242:        /* please leave this commented - or ask thies@thieso.net before doing it (again) */
                   1243:        if (parser->object) {
                   1244:                zval_ptr_dtor(&parser->object);
                   1245:        }
                   1246: 
                   1247:        /* please leave this commented - or ask thies@thieso.net before doing it (again) */
                   1248: /* #ifdef ZEND_ENGINE_2
                   1249:        zval_add_ref(&parser->object); 
                   1250: #endif */
                   1251: 
                   1252:        ALLOC_ZVAL(parser->object);
                   1253:        MAKE_COPY_ZVAL(&mythis, parser->object);
                   1254: 
                   1255:        RETVAL_TRUE;
                   1256: }
                   1257: /* }}} */
                   1258: 
                   1259: /* {{{ proto int xml_set_element_handler(resource parser, string shdl, string ehdl) 
                   1260:    Set up start and end element handlers */
                   1261: PHP_FUNCTION(xml_set_element_handler)
                   1262: {
                   1263:        xml_parser *parser;
                   1264:        zval *pind, **shdl, **ehdl;
                   1265: 
                   1266:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZZ", &pind, &shdl, &ehdl) == FAILURE) {
                   1267:                return;
                   1268:        }
                   1269: 
                   1270:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1271: 
                   1272:        xml_set_handler(&parser->startElementHandler, shdl);
                   1273:        xml_set_handler(&parser->endElementHandler, ehdl);
                   1274:        XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
                   1275:        RETVAL_TRUE;
                   1276: }
                   1277: /* }}} */
                   1278: 
                   1279: /* {{{ proto int xml_set_character_data_handler(resource parser, string hdl) 
                   1280:    Set up character data handler */
                   1281: PHP_FUNCTION(xml_set_character_data_handler)
                   1282: {
                   1283:        xml_parser *parser;
                   1284:        zval *pind, **hdl;
                   1285: 
                   1286:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1287:                return;
                   1288:        }
                   1289: 
                   1290:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1291: 
                   1292:        xml_set_handler(&parser->characterDataHandler, hdl);
                   1293:        XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
                   1294:        RETVAL_TRUE;
                   1295: }
                   1296: /* }}} */
                   1297: 
                   1298: /* {{{ proto int xml_set_processing_instruction_handler(resource parser, string hdl) 
                   1299:    Set up processing instruction (PI) handler */
                   1300: PHP_FUNCTION(xml_set_processing_instruction_handler)
                   1301: {
                   1302:        xml_parser *parser;
                   1303:        zval *pind, **hdl;
                   1304: 
                   1305:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1306:                return;
                   1307:        }
                   1308: 
                   1309:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1310: 
                   1311:        xml_set_handler(&parser->processingInstructionHandler, hdl);
                   1312:        XML_SetProcessingInstructionHandler(parser->parser, _xml_processingInstructionHandler);
                   1313:        RETVAL_TRUE;
                   1314: }
                   1315: /* }}} */
                   1316: 
                   1317: /* {{{ proto int xml_set_default_handler(resource parser, string hdl) 
                   1318:    Set up default handler */
                   1319: PHP_FUNCTION(xml_set_default_handler)
                   1320: {
                   1321:        xml_parser *parser;
                   1322:        zval *pind, **hdl;
                   1323: 
                   1324:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1325:                return;
                   1326:        }
                   1327:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1328: 
                   1329:        xml_set_handler(&parser->defaultHandler, hdl);
                   1330:        XML_SetDefaultHandler(parser->parser, _xml_defaultHandler);
                   1331:        RETVAL_TRUE;
                   1332: }
                   1333: /* }}} */
                   1334: 
                   1335: /* {{{ proto int xml_set_unparsed_entity_decl_handler(resource parser, string hdl) 
                   1336:    Set up unparsed entity declaration handler */
                   1337: PHP_FUNCTION(xml_set_unparsed_entity_decl_handler)
                   1338: {
                   1339:        xml_parser *parser;
                   1340:        zval *pind, **hdl;
                   1341: 
                   1342:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1343:                return;
                   1344:        }
                   1345: 
                   1346:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1347: 
                   1348:        xml_set_handler(&parser->unparsedEntityDeclHandler, hdl);
                   1349:        XML_SetUnparsedEntityDeclHandler(parser->parser, _xml_unparsedEntityDeclHandler);
                   1350:        RETVAL_TRUE;
                   1351: }
                   1352: /* }}} */
                   1353: 
                   1354: /* {{{ proto int xml_set_notation_decl_handler(resource parser, string hdl) 
                   1355:    Set up notation declaration handler */
                   1356: PHP_FUNCTION(xml_set_notation_decl_handler)
                   1357: {
                   1358:        xml_parser *parser;
                   1359:        zval *pind, **hdl;
                   1360: 
                   1361:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1362:                return;
                   1363:        }
                   1364:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1365: 
                   1366:        xml_set_handler(&parser->notationDeclHandler, hdl);
                   1367:        XML_SetNotationDeclHandler(parser->parser, _xml_notationDeclHandler);
                   1368:        RETVAL_TRUE;
                   1369: }
                   1370: /* }}} */
                   1371: 
                   1372: /* {{{ proto int xml_set_external_entity_ref_handler(resource parser, string hdl) 
                   1373:    Set up external entity reference handler */
                   1374: PHP_FUNCTION(xml_set_external_entity_ref_handler)
                   1375: {
                   1376:        xml_parser *parser;
                   1377:        zval *pind, **hdl;
                   1378: 
                   1379:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1380:                return;
                   1381:        }
                   1382:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1383: 
                   1384:        xml_set_handler(&parser->externalEntityRefHandler, hdl);
                   1385:        XML_SetExternalEntityRefHandler(parser->parser, (void *) _xml_externalEntityRefHandler);
                   1386:        RETVAL_TRUE;
                   1387: }
                   1388: /* }}} */
                   1389: 
                   1390: /* {{{ proto int xml_set_start_namespace_decl_handler(resource parser, string hdl) 
                   1391:    Set up character data handler */
                   1392: PHP_FUNCTION(xml_set_start_namespace_decl_handler)
                   1393: {
                   1394:        xml_parser *parser;
                   1395:        zval *pind, **hdl;
                   1396: 
                   1397:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1398:                return;
                   1399:        }
                   1400: 
                   1401:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1402: 
                   1403:        xml_set_handler(&parser->startNamespaceDeclHandler, hdl);
                   1404:        XML_SetStartNamespaceDeclHandler(parser->parser, _xml_startNamespaceDeclHandler);
                   1405:        RETVAL_TRUE;
                   1406: }
                   1407: /* }}} */
                   1408: 
                   1409: /* {{{ proto int xml_set_end_namespace_decl_handler(resource parser, string hdl) 
                   1410:    Set up character data handler */
                   1411: PHP_FUNCTION(xml_set_end_namespace_decl_handler)
                   1412: {
                   1413:        xml_parser *parser;
                   1414:        zval *pind, **hdl;
                   1415: 
                   1416:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1417:                return;
                   1418:        }
                   1419: 
                   1420:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1421: 
                   1422:        xml_set_handler(&parser->endNamespaceDeclHandler, hdl);
                   1423:        XML_SetEndNamespaceDeclHandler(parser->parser, _xml_endNamespaceDeclHandler);
                   1424:        RETVAL_TRUE;
                   1425: }
                   1426: /* }}} */
                   1427: 
                   1428: /* {{{ proto int xml_parse(resource parser, string data [, int isFinal]) 
                   1429:    Start parsing an XML document */
                   1430: PHP_FUNCTION(xml_parse)
                   1431: {
                   1432:        xml_parser *parser;
                   1433:        zval *pind;
                   1434:        char *data;
                   1435:        int data_len, ret;
                   1436:        long isFinal = 0;
                   1437: 
                   1438:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &pind, &data, &data_len, &isFinal) == FAILURE) {
                   1439:                return;
                   1440:        }
                   1441:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1442: 
                   1443:        parser->isparsing = 1;
                   1444:        ret = XML_Parse(parser->parser, data, data_len, isFinal);
                   1445:        parser->isparsing = 0;
                   1446:        RETVAL_LONG(ret);
                   1447: }
                   1448: 
                   1449: /* }}} */
                   1450: 
                   1451: /* {{{ proto int xml_parse_into_struct(resource parser, string data, array &values [, array &index ])
                   1452:    Parsing a XML document */
                   1453: 
                   1454: PHP_FUNCTION(xml_parse_into_struct)
                   1455: {
                   1456:        xml_parser *parser;
                   1457:        zval *pind, **xdata, **info = NULL;
                   1458:        char *data;
                   1459:        int data_len, ret;
                   1460: 
                   1461:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ|Z", &pind, &data, &data_len, &xdata, &info) == FAILURE) {
                   1462:                return;
                   1463:        }
                   1464:        
                   1465:        if (info) {     
                   1466:                zval_dtor(*info);
                   1467:                array_init(*info);
                   1468:        }
                   1469: 
                   1470:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1471: 
                   1472:        zval_dtor(*xdata);
                   1473:        array_init(*xdata);
                   1474: 
                   1475:        parser->data = *xdata;
                   1476:        
                   1477:        if (info) {
                   1478:                parser->info = *info;
                   1479:        }
                   1480:        
                   1481:        parser->level = 0;
                   1482:        parser->ltags = safe_emalloc(XML_MAXLEVEL, sizeof(char *), 0);
                   1483: 
                   1484:        XML_SetDefaultHandler(parser->parser, _xml_defaultHandler);
                   1485:        XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
                   1486:        XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
                   1487: 
                   1488:        parser->isparsing = 1;
                   1489:        ret = XML_Parse(parser->parser, data, data_len, 1);
                   1490:        parser->isparsing = 0;
                   1491: 
                   1492:        RETVAL_LONG(ret);
                   1493: }
                   1494: /* }}} */
                   1495: 
                   1496: /* {{{ proto int xml_get_error_code(resource parser) 
                   1497:    Get XML parser error code */
                   1498: PHP_FUNCTION(xml_get_error_code)
                   1499: {
                   1500:        xml_parser *parser;
                   1501:        zval *pind;
                   1502: 
                   1503:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1504:                return;
                   1505:        }
                   1506:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1507: 
                   1508:        RETVAL_LONG((long)XML_GetErrorCode(parser->parser));
                   1509: }
                   1510: /* }}} */
                   1511: 
                   1512: /* {{{ proto string xml_error_string(int code)
                   1513:    Get XML parser error string */
                   1514: PHP_FUNCTION(xml_error_string)
                   1515: {
                   1516:        long code;
                   1517:        char *str;
                   1518: 
                   1519:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code) == FAILURE) {
                   1520:                return;
                   1521:        }
                   1522: 
                   1523:        str = (char *)XML_ErrorString((int)code);
                   1524:        if (str) {
                   1525:                RETVAL_STRING(str, 1);
                   1526:        }
                   1527: }
                   1528: /* }}} */
                   1529: 
                   1530: /* {{{ proto int xml_get_current_line_number(resource parser) 
                   1531:    Get current line number for an XML parser */
                   1532: PHP_FUNCTION(xml_get_current_line_number)
                   1533: {
                   1534:        xml_parser *parser;
                   1535:        zval *pind;
                   1536: 
                   1537:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1538:                return;
                   1539:        }
                   1540:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1541: 
                   1542:        RETVAL_LONG(XML_GetCurrentLineNumber(parser->parser));
                   1543: }
                   1544: /* }}} */
                   1545: 
                   1546: /* {{{ proto int xml_get_current_column_number(resource parser)
                   1547:    Get current column number for an XML parser */
                   1548: PHP_FUNCTION(xml_get_current_column_number)
                   1549: {
                   1550:        xml_parser *parser;
                   1551:        zval *pind;
                   1552: 
                   1553:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1554:                return;
                   1555:        }
                   1556:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1557: 
                   1558:        RETVAL_LONG(XML_GetCurrentColumnNumber(parser->parser));
                   1559: }
                   1560: /* }}} */
                   1561: 
                   1562: /* {{{ proto int xml_get_current_byte_index(resource parser) 
                   1563:    Get current byte index for an XML parser */
                   1564: PHP_FUNCTION(xml_get_current_byte_index)
                   1565: {
                   1566:        xml_parser *parser;
                   1567:        zval *pind;
                   1568: 
                   1569:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1570:                return;
                   1571:        }
                   1572:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1573: 
                   1574:        RETVAL_LONG(XML_GetCurrentByteIndex(parser->parser));
                   1575: }
                   1576: /* }}} */
                   1577: 
                   1578: /* {{{ proto int xml_parser_free(resource parser) 
                   1579:    Free an XML parser */
                   1580: PHP_FUNCTION(xml_parser_free)
                   1581: {
                   1582:        zval *pind;
                   1583:        xml_parser *parser;
                   1584: 
                   1585:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1586:                return;
                   1587:        }
                   1588: 
                   1589:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1590: 
                   1591:        if (parser->isparsing == 1) {
                   1592:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parser cannot be freed while it is parsing.");
                   1593:                RETURN_FALSE;
                   1594:        }
                   1595: 
                   1596:        if (zend_list_delete(parser->index) == FAILURE) {
                   1597:                RETURN_FALSE;
                   1598:        }
                   1599: 
                   1600:        RETVAL_TRUE;
                   1601: }
                   1602: /* }}} */
                   1603: 
                   1604: /* {{{ proto int xml_parser_set_option(resource parser, int option, mixed value) 
                   1605:    Set options in an XML parser */
                   1606: PHP_FUNCTION(xml_parser_set_option)
                   1607: {
                   1608:        xml_parser *parser;
                   1609:        zval *pind, **val;
                   1610:        long opt;
                   1611: 
                   1612:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &pind, &opt, &val) == FAILURE) {
                   1613:                return;
                   1614:        }
                   1615:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1616: 
                   1617:        switch (opt) {
                   1618:                case PHP_XML_OPTION_CASE_FOLDING:
                   1619:                        convert_to_long_ex(val);
                   1620:                        parser->case_folding = Z_LVAL_PP(val);
                   1621:                        break;
                   1622:                case PHP_XML_OPTION_SKIP_TAGSTART:
                   1623:                        convert_to_long_ex(val);
                   1624:                        parser->toffset = Z_LVAL_PP(val);
                   1625:                        break;
                   1626:                case PHP_XML_OPTION_SKIP_WHITE:
                   1627:                        convert_to_long_ex(val);
                   1628:                        parser->skipwhite = Z_LVAL_PP(val);
                   1629:                        break;
                   1630:                case PHP_XML_OPTION_TARGET_ENCODING: {
                   1631:                        xml_encoding *enc;
                   1632:                        convert_to_string_ex(val);
                   1633:                        enc = xml_get_encoding(Z_STRVAL_PP(val));
                   1634:                        if (enc == NULL) {
                   1635:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported target encoding \"%s\"", Z_STRVAL_PP(val));
                   1636:                                RETURN_FALSE;
                   1637:                        }
                   1638:                        parser->target_encoding = enc->name;
                   1639:                        break;
                   1640:                }
                   1641:                default:
                   1642:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option");
                   1643:                        RETURN_FALSE;
                   1644:                        break;
                   1645:        }
                   1646:        RETVAL_TRUE;
                   1647: }
                   1648: /* }}} */
                   1649: 
                   1650: /* {{{ proto int xml_parser_get_option(resource parser, int option) 
                   1651:    Get options from an XML parser */
                   1652: PHP_FUNCTION(xml_parser_get_option)
                   1653: {
                   1654:        xml_parser *parser;
                   1655:        zval *pind;
                   1656:        long opt;
                   1657: 
                   1658:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pind, &opt) == FAILURE) {
                   1659:                return;
                   1660:        }
                   1661:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1662: 
                   1663:        switch (opt) {
                   1664:                case PHP_XML_OPTION_CASE_FOLDING:
                   1665:                        RETURN_LONG(parser->case_folding);
                   1666:                        break;
                   1667:                case PHP_XML_OPTION_TARGET_ENCODING:
                   1668:                        RETURN_STRING(parser->target_encoding, 1);
                   1669:                        break;
                   1670:                default:
                   1671:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option");
                   1672:                        RETURN_FALSE;
                   1673:                        break;
                   1674:        }
                   1675: 
                   1676:        RETVAL_FALSE;   /* never reached */
                   1677: }
                   1678: /* }}} */
                   1679: 
                   1680: /* {{{ proto string utf8_encode(string data) 
                   1681:    Encodes an ISO-8859-1 string to UTF-8 */
                   1682: PHP_FUNCTION(utf8_encode)
                   1683: {
                   1684:        char *arg;
                   1685:        XML_Char *encoded;
                   1686:        int arg_len, len;
                   1687: 
                   1688:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                   1689:                return;
                   1690:        }
                   1691: 
                   1692:        encoded = xml_utf8_encode(arg, arg_len, &len, "ISO-8859-1");
                   1693:        if (encoded == NULL) {
                   1694:                RETURN_FALSE;
                   1695:        }
                   1696:        RETVAL_STRINGL(encoded, len, 0);
                   1697: }
                   1698: /* }}} */
                   1699: 
                   1700: /* {{{ proto string utf8_decode(string data) 
                   1701:    Converts a UTF-8 encoded string to ISO-8859-1 */
                   1702: PHP_FUNCTION(utf8_decode)
                   1703: {
                   1704:        char *arg;
                   1705:        XML_Char *decoded;
                   1706:        int arg_len, len;
                   1707: 
                   1708:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                   1709:                return;
                   1710:        }
                   1711: 
                   1712:        decoded = xml_utf8_decode(arg, arg_len, &len, "ISO-8859-1");
                   1713:        if (decoded == NULL) {
                   1714:                RETURN_FALSE;
                   1715:        }
                   1716:        RETVAL_STRINGL(decoded, len, 0);
                   1717: }
                   1718: /* }}} */
                   1719: 
                   1720: #endif
                   1721: 
                   1722: /*
                   1723:  * Local variables:
                   1724:  * tab-width: 4
                   1725:  * c-basic-offset: 4
                   1726:  * End:
                   1727:  * vim600: sw=4 ts=4 fdm=marker
                   1728:  * vim<600: sw=4 ts=4
                   1729:  */

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