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

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.5 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       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[] = {
1.1.1.4   misho     277:        { (XML_Char *)"ISO-8859-1", xml_decode_iso_8859_1, xml_encode_iso_8859_1 },
                    278:        { (XML_Char *)"US-ASCII",   xml_decode_us_ascii,   xml_encode_us_ascii   },
                    279:        { (XML_Char *)"UTF-8",      NULL,                  NULL                  },
                    280:        { (XML_Char *)NULL,         NULL,                  NULL                  }
1.1       misho     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;
1.1.1.4   misho     431:                for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
1.1       misho     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) {
1.1.1.4   misho     808:                        if (parser->level <= XML_MAXLEVEL)  {
                    809:                                zval *tag, *atr;
                    810:                                int atcnt = 0;
1.1       misho     811: 
1.1.1.4   misho     812:                                MAKE_STD_ZVAL(tag);
                    813:                                MAKE_STD_ZVAL(atr);
1.1       misho     814: 
1.1.1.4   misho     815:                                array_init(tag);
                    816:                                array_init(atr);
1.1       misho     817: 
1.1.1.4   misho     818:                                _xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
1.1       misho     819: 
1.1.1.4   misho     820:                                add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
                    821:                                add_assoc_string(tag,"type","open",1);
                    822:                                add_assoc_long(tag,"level",parser->level);
1.1       misho     823: 
1.1.1.4   misho     824:                                parser->ltags[parser->level-1] = estrdup(tag_name);
                    825:                                parser->lastwasopen = 1;
1.1       misho     826: 
1.1.1.4   misho     827:                                attributes = (const XML_Char **) attrs;
1.1       misho     828: 
1.1.1.4   misho     829:                                while (attributes && *attributes) {
                    830:                                        att = _xml_decode_tag(parser, attributes[0]);
                    831:                                        val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
1.1       misho     832: 
1.1.1.4   misho     833:                                        add_assoc_stringl(atr,att,val,val_len,0);
1.1       misho     834: 
1.1.1.4   misho     835:                                        atcnt++;
                    836:                                        attributes += 2;
1.1       misho     837: 
1.1.1.4   misho     838:                                        efree(att);
                    839:                                }
                    840: 
                    841:                                if (atcnt) {
                    842:                                        zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL);
                    843:                                } else {
                    844:                                        zval_ptr_dtor(&atr);
                    845:                                }
1.1       misho     846: 
1.1.1.4   misho     847:                                zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag);
                    848:                        } else if (parser->level == (XML_MAXLEVEL + 1)) {
                    849:                                TSRMLS_FETCH();
                    850:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
                    851:                        }
1.1       misho     852:                }
                    853: 
                    854:                efree(tag_name);
                    855:        }
                    856: }
                    857: /* }}} */
                    858: 
                    859: /* {{{ _xml_endElementHandler() */
                    860: void _xml_endElementHandler(void *userData, const XML_Char *name)
                    861: {
                    862:        xml_parser *parser = (xml_parser *)userData;
                    863:        char *tag_name;
                    864: 
                    865:        if (parser) {
                    866:                zval *retval, *args[2];
                    867: 
                    868:                tag_name = _xml_decode_tag(parser, name);
                    869: 
                    870:                if (parser->endElementHandler) {
                    871:                        args[0] = _xml_resource_zval(parser->index);
                    872:                        args[1] = _xml_string_zval(((char *) tag_name) + parser->toffset);
                    873: 
                    874:                        if ((retval = xml_call_handler(parser, parser->endElementHandler, parser->endElementPtr, 2, args))) {
                    875:                                zval_ptr_dtor(&retval);
                    876:                        }
                    877:                } 
                    878: 
                    879:                if (parser->data) {
                    880:                        zval *tag;
                    881: 
                    882:                        if (parser->lastwasopen) {
                    883:                                add_assoc_string(*(parser->ctag),"type","complete",1);
                    884:                        } else {
                    885:                                MAKE_STD_ZVAL(tag);
                    886: 
                    887:                                array_init(tag);
                    888:                                  
                    889:                                _xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
                    890: 
                    891:                                add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
                    892:                                add_assoc_string(tag,"type","close",1);
                    893:                                add_assoc_long(tag,"level",parser->level);
                    894:                                  
                    895:                                zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
                    896:                        }
                    897: 
                    898:                        parser->lastwasopen = 0;
                    899:                }
                    900: 
                    901:                efree(tag_name);
                    902: 
1.1.1.4   misho     903:                if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) {
1.1       misho     904:                        efree(parser->ltags[parser->level-1]);
                    905:                }
                    906: 
                    907:                parser->level--;
                    908:        }
                    909: }
                    910: /* }}} */
                    911: 
                    912: /* {{{ _xml_characterDataHandler() */
                    913: void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)
                    914: {
                    915:        xml_parser *parser = (xml_parser *)userData;
                    916: 
                    917:        if (parser) {
                    918:                zval *retval, *args[2];
                    919: 
                    920:                if (parser->characterDataHandler) {
                    921:                        args[0] = _xml_resource_zval(parser->index);
                    922:                        args[1] = _xml_xmlchar_zval(s, len, parser->target_encoding);
                    923:                        if ((retval = xml_call_handler(parser, parser->characterDataHandler, parser->characterDataPtr, 2, args))) {
                    924:                                zval_ptr_dtor(&retval);
                    925:                        }
                    926:                } 
                    927: 
                    928:                if (parser->data) {
                    929:                        int i;
                    930:                        int doprint = 0;
                    931: 
                    932:                        char *decoded_value;
                    933:                        int decoded_len;
                    934:                        
                    935:                        decoded_value = xml_utf8_decode(s,len,&decoded_len,parser->target_encoding);
                    936:                        for (i = 0; i < decoded_len; i++) {
                    937:                                switch (decoded_value[i]) {
                    938:                                case ' ':
                    939:                                case '\t':
                    940:                                case '\n':
                    941:                                        continue;
                    942:                                default:
                    943:                                        doprint = 1;
                    944:                                        break;
                    945:                                }
                    946:                                if (doprint) {
                    947:                                        break;
                    948:                                }
                    949:                        }
                    950:                        if (doprint || (! parser->skipwhite)) {
                    951:                                if (parser->lastwasopen) {
                    952:                                        zval **myval;
                    953:                                        
                    954:                                        /* check if the current tag already has a value - if yes append to that! */
                    955:                                        if (zend_hash_find(Z_ARRVAL_PP(parser->ctag),"value",sizeof("value"),(void **) &myval) == SUCCESS) {
                    956:                                                int newlen = Z_STRLEN_PP(myval) + decoded_len;
                    957:                                                Z_STRVAL_PP(myval) = erealloc(Z_STRVAL_PP(myval),newlen+1);
                    958:                                                strncpy(Z_STRVAL_PP(myval) + Z_STRLEN_PP(myval), decoded_value, decoded_len + 1);
                    959:                                                Z_STRLEN_PP(myval) += decoded_len;
                    960:                                                efree(decoded_value);
                    961:                                        } else {
                    962:                                                add_assoc_string(*(parser->ctag),"value",decoded_value,0);
                    963:                                        }
                    964:                                        
                    965:                                } else {
                    966:                                        zval *tag;
                    967:                                        zval **curtag, **mytype, **myval;
                    968:                                        HashPosition hpos=NULL;
                    969: 
                    970:                                        zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(parser->data), &hpos);
                    971: 
                    972:                                        if (hpos && (zend_hash_get_current_data_ex(Z_ARRVAL_P(parser->data), (void **) &curtag, &hpos) == SUCCESS)) {
                    973:                                                if (zend_hash_find(Z_ARRVAL_PP(curtag),"type",sizeof("type"),(void **) &mytype) == SUCCESS) {
                    974:                                                        if (!strcmp(Z_STRVAL_PP(mytype), "cdata")) {
                    975:                                                                if (zend_hash_find(Z_ARRVAL_PP(curtag),"value",sizeof("value"),(void **) &myval) == SUCCESS) {
                    976:                                                                        int newlen = Z_STRLEN_PP(myval) + decoded_len;
                    977:                                                                        Z_STRVAL_PP(myval) = erealloc(Z_STRVAL_PP(myval),newlen+1);
                    978:                                                                        strncpy(Z_STRVAL_PP(myval) + Z_STRLEN_PP(myval), decoded_value, decoded_len + 1);
                    979:                                                                        Z_STRLEN_PP(myval) += decoded_len;
                    980:                                                                        efree(decoded_value);
                    981:                                                                        return;
                    982:                                                                }
                    983:                                                        }
                    984:                                                }
                    985:                                        }
                    986: 
1.1.1.4   misho     987:                                        if (parser->level <= XML_MAXLEVEL) {
                    988:                                                MAKE_STD_ZVAL(tag);
1.1       misho     989: 
1.1.1.4   misho     990:                                                array_init(tag);
1.1       misho     991: 
1.1.1.4   misho     992:                                                _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
                    993: 
                    994:                                                add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1);
                    995:                                                add_assoc_string(tag,"value",decoded_value,0);
                    996:                                                add_assoc_string(tag,"type","cdata",1);
                    997:                                                add_assoc_long(tag,"level",parser->level);
                    998: 
                    999:                                                zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
                   1000:                                        } else if (parser->level == (XML_MAXLEVEL + 1)) {
                   1001:                                                TSRMLS_FETCH();
                   1002:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
                   1003:                                        }
1.1       misho    1004:                                }
                   1005:                        } else {
                   1006:                                efree(decoded_value);
                   1007:                        }
                   1008:                }
                   1009:        }
                   1010: }
                   1011: /* }}} */
                   1012: 
                   1013: /* {{{ _xml_processingInstructionHandler() */
                   1014: void _xml_processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data)
                   1015: {
                   1016:        xml_parser *parser = (xml_parser *)userData;
                   1017: 
                   1018:        if (parser && parser->processingInstructionHandler) {
                   1019:                zval *retval, *args[3];
                   1020: 
                   1021:                args[0] = _xml_resource_zval(parser->index);
                   1022:                args[1] = _xml_xmlchar_zval(target, 0, parser->target_encoding);
                   1023:                args[2] = _xml_xmlchar_zval(data, 0, parser->target_encoding);
                   1024:                if ((retval = xml_call_handler(parser, parser->processingInstructionHandler, parser->processingInstructionPtr, 3, args))) {
                   1025:                        zval_ptr_dtor(&retval);
                   1026:                }
                   1027:        }
                   1028: }
                   1029: /* }}} */
                   1030: 
                   1031: /* {{{ _xml_defaultHandler() */
                   1032: void _xml_defaultHandler(void *userData, const XML_Char *s, int len)
                   1033: {
                   1034:        xml_parser *parser = (xml_parser *)userData;
                   1035: 
                   1036:        if (parser && parser->defaultHandler) {
                   1037:                zval *retval, *args[2];
                   1038: 
                   1039:                args[0] = _xml_resource_zval(parser->index);
                   1040:                args[1] = _xml_xmlchar_zval(s, len, parser->target_encoding);
                   1041:                if ((retval = xml_call_handler(parser, parser->defaultHandler, parser->defaultPtr, 2, args))) {
                   1042:                        zval_ptr_dtor(&retval);
                   1043:                }
                   1044:        }
                   1045: }
                   1046: /* }}} */
                   1047: 
                   1048: /* {{{ _xml_unparsedEntityDeclHandler() */
                   1049: void _xml_unparsedEntityDeclHandler(void *userData, 
                   1050:                                                                                 const XML_Char *entityName, 
                   1051:                                                                                 const XML_Char *base,
                   1052:                                                                                 const XML_Char *systemId,
                   1053:                                                                                 const XML_Char *publicId,
                   1054:                                                                                 const XML_Char *notationName)
                   1055: {
                   1056:        xml_parser *parser = (xml_parser *)userData;
                   1057: 
                   1058:        if (parser && parser->unparsedEntityDeclHandler) {
                   1059:                zval *retval, *args[6];
                   1060: 
                   1061:                args[0] = _xml_resource_zval(parser->index);
                   1062:                args[1] = _xml_xmlchar_zval(entityName, 0, parser->target_encoding);
                   1063:                args[2] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
                   1064:                args[3] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
                   1065:                args[4] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
                   1066:                args[5] = _xml_xmlchar_zval(notationName, 0, parser->target_encoding);
                   1067:                if ((retval = xml_call_handler(parser, parser->unparsedEntityDeclHandler, parser->unparsedEntityDeclPtr, 6, args))) {
                   1068:                        zval_ptr_dtor(&retval);
                   1069:                }
                   1070:        }
                   1071: }
                   1072: /* }}} */
                   1073: 
                   1074: /* {{{ _xml_notationDeclHandler() */
                   1075: void _xml_notationDeclHandler(void *userData,
                   1076:                                                          const XML_Char *notationName,
                   1077:                                                          const XML_Char *base,
                   1078:                                                          const XML_Char *systemId,
                   1079:                                                          const XML_Char *publicId)
                   1080: {
                   1081:        xml_parser *parser = (xml_parser *)userData;
                   1082: 
                   1083:        if (parser && parser->notationDeclHandler) {
                   1084:                zval *retval, *args[5];
                   1085: 
                   1086:                args[0] = _xml_resource_zval(parser->index);
                   1087:                args[1] = _xml_xmlchar_zval(notationName, 0, parser->target_encoding);
                   1088:                args[2] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
                   1089:                args[3] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
                   1090:                args[4] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
                   1091:                if ((retval = xml_call_handler(parser, parser->notationDeclHandler, parser->notationDeclPtr, 5, args))) {
                   1092:                        zval_ptr_dtor(&retval);
                   1093:                }
                   1094:        }
                   1095: }
                   1096: /* }}} */
                   1097: 
                   1098: /* {{{ _xml_externalEntityRefHandler() */
                   1099: int _xml_externalEntityRefHandler(XML_Parser parserPtr,
                   1100:                                                                   const XML_Char *openEntityNames,
                   1101:                                                                   const XML_Char *base,
                   1102:                                                                   const XML_Char *systemId,
                   1103:                                                                   const XML_Char *publicId)
                   1104: {
                   1105:        xml_parser *parser = XML_GetUserData(parserPtr);
                   1106:        int ret = 0; /* abort if no handler is set (should be configurable?) */
                   1107: 
                   1108:        if (parser && parser->externalEntityRefHandler) {
                   1109:                zval *retval, *args[5];
                   1110: 
                   1111:                args[0] = _xml_resource_zval(parser->index);
                   1112:                args[1] = _xml_xmlchar_zval(openEntityNames, 0, parser->target_encoding);
                   1113:                args[2] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
                   1114:                args[3] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
                   1115:                args[4] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
                   1116:                if ((retval = xml_call_handler(parser, parser->externalEntityRefHandler, parser->externalEntityRefPtr, 5, args))) {
                   1117:                        convert_to_long(retval);
                   1118:                        ret = Z_LVAL_P(retval);
                   1119:                        efree(retval);
                   1120:                } else {
                   1121:                        ret = 0;
                   1122:                }
                   1123:        }
                   1124:        return ret;
                   1125: }
                   1126: /* }}} */
                   1127: 
                   1128: /* {{{ _xml_startNamespaceDeclHandler() */
                   1129: void _xml_startNamespaceDeclHandler(void *userData,const XML_Char *prefix, const XML_Char *uri)
                   1130: {
                   1131:        xml_parser *parser = (xml_parser *)userData;
                   1132: 
                   1133:        if (parser && parser->startNamespaceDeclHandler) {
                   1134:                zval *retval, *args[3];
                   1135: 
                   1136:                args[0] = _xml_resource_zval(parser->index);
                   1137:                args[1] = _xml_xmlchar_zval(prefix, 0, parser->target_encoding);
                   1138:                args[2] = _xml_xmlchar_zval(uri, 0, parser->target_encoding);
                   1139:                if ((retval = xml_call_handler(parser, parser->startNamespaceDeclHandler, parser->startNamespaceDeclPtr, 3, args))) {
                   1140:                        zval_ptr_dtor(&retval);
                   1141:                }
                   1142:        }
                   1143: }
                   1144: /* }}} */
                   1145: 
                   1146: /* {{{ _xml_endNamespaceDeclHandler() */
                   1147: void _xml_endNamespaceDeclHandler(void *userData, const XML_Char *prefix)
                   1148: {
                   1149:        xml_parser *parser = (xml_parser *)userData;
                   1150: 
                   1151:        if (parser && parser->endNamespaceDeclHandler) {
                   1152:                zval *retval, *args[2];
                   1153: 
                   1154:                args[0] = _xml_resource_zval(parser->index);
                   1155:                args[1] = _xml_xmlchar_zval(prefix, 0, parser->target_encoding);
                   1156:                if ((retval = xml_call_handler(parser, parser->endNamespaceDeclHandler, parser->endNamespaceDeclPtr, 2, args))) {
                   1157:                        zval_ptr_dtor(&retval);
                   1158:                }
                   1159:        }
                   1160: }
                   1161: /* }}} */
                   1162: 
                   1163: /************************* EXTENSION FUNCTIONS *************************/
                   1164: 
                   1165: static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_support) /* {{{ */
                   1166: {
                   1167:        xml_parser *parser;
                   1168:        int auto_detect = 0;
                   1169: 
                   1170:        char *encoding_param = NULL;
                   1171:        int encoding_param_len = 0;
                   1172: 
                   1173:        char *ns_param = NULL;
                   1174:        int ns_param_len = 0;
                   1175:        
                   1176:        XML_Char *encoding;
                   1177:        
                   1178:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (ns_support ? "|ss": "|s"), &encoding_param, &encoding_param_len, &ns_param, &ns_param_len) == FAILURE) {
                   1179:                RETURN_FALSE;
                   1180:        }
                   1181: 
                   1182:        if (encoding_param != NULL) {
                   1183:                /* The supported encoding types are hardcoded here because
                   1184:                 * we are limited to the encodings supported by expat/xmltok.
                   1185:                 */
                   1186:                if (encoding_param_len == 0) {
                   1187:                        encoding = XML(default_encoding);
                   1188:                        auto_detect = 1;
                   1189:                } else if (strcasecmp(encoding_param, "ISO-8859-1") == 0) {
                   1190:                        encoding = "ISO-8859-1";
                   1191:                } else if (strcasecmp(encoding_param, "UTF-8") == 0) {
                   1192:                        encoding = "UTF-8";
                   1193:                } else if (strcasecmp(encoding_param, "US-ASCII") == 0) {
                   1194:                        encoding = "US-ASCII";
                   1195:                } else {
                   1196:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "unsupported source encoding \"%s\"", encoding_param);
                   1197:                        RETURN_FALSE;
                   1198:                }
                   1199:        } else {
                   1200:                encoding = XML(default_encoding);
                   1201:        }
                   1202: 
                   1203:        if (ns_support && ns_param == NULL){
                   1204:                ns_param = ":";
                   1205:        }
                   1206: 
                   1207:        parser = ecalloc(1, sizeof(xml_parser));
                   1208:        parser->parser = XML_ParserCreate_MM((auto_detect ? NULL : encoding),
                   1209:                                          &php_xml_mem_hdlrs, ns_param);
                   1210: 
                   1211:        parser->target_encoding = encoding;
                   1212:        parser->case_folding = 1;
                   1213:        parser->object = NULL;
                   1214:        parser->isparsing = 0;
                   1215: 
                   1216:        XML_SetUserData(parser->parser, parser);
                   1217: 
                   1218:        ZEND_REGISTER_RESOURCE(return_value, parser,le_xml_parser);
                   1219:        parser->index = Z_LVAL_P(return_value);
                   1220: }
                   1221: /* }}} */
                   1222: 
                   1223: /* {{{ proto resource xml_parser_create([string encoding]) 
                   1224:    Create an XML parser */
                   1225: PHP_FUNCTION(xml_parser_create)
                   1226: {
                   1227:        php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);        
                   1228: }
                   1229: /* }}} */
                   1230: 
                   1231: /* {{{ proto resource xml_parser_create_ns([string encoding [, string sep]]) 
                   1232:    Create an XML parser */
                   1233: PHP_FUNCTION(xml_parser_create_ns)
                   1234: {
                   1235:        php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                   1236: }
                   1237: /* }}} */
                   1238: 
                   1239: /* {{{ proto int xml_set_object(resource parser, object &obj) 
                   1240:    Set up object which should be used for callbacks */
                   1241: PHP_FUNCTION(xml_set_object)
                   1242: {
                   1243:        xml_parser *parser;
                   1244:        zval *pind, *mythis;
                   1245: 
                   1246:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ro", &pind, &mythis) == FAILURE) {
                   1247:                return;
                   1248:        }
                   1249: 
                   1250:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1251: 
                   1252:        /* please leave this commented - or ask thies@thieso.net before doing it (again) */
                   1253:        if (parser->object) {
                   1254:                zval_ptr_dtor(&parser->object);
                   1255:        }
                   1256: 
                   1257:        /* please leave this commented - or ask thies@thieso.net before doing it (again) */
                   1258: /* #ifdef ZEND_ENGINE_2
                   1259:        zval_add_ref(&parser->object); 
                   1260: #endif */
                   1261: 
                   1262:        ALLOC_ZVAL(parser->object);
                   1263:        MAKE_COPY_ZVAL(&mythis, parser->object);
                   1264: 
                   1265:        RETVAL_TRUE;
                   1266: }
                   1267: /* }}} */
                   1268: 
                   1269: /* {{{ proto int xml_set_element_handler(resource parser, string shdl, string ehdl) 
                   1270:    Set up start and end element handlers */
                   1271: PHP_FUNCTION(xml_set_element_handler)
                   1272: {
                   1273:        xml_parser *parser;
                   1274:        zval *pind, **shdl, **ehdl;
                   1275: 
                   1276:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZZ", &pind, &shdl, &ehdl) == FAILURE) {
                   1277:                return;
                   1278:        }
                   1279: 
                   1280:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1281: 
                   1282:        xml_set_handler(&parser->startElementHandler, shdl);
                   1283:        xml_set_handler(&parser->endElementHandler, ehdl);
                   1284:        XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
                   1285:        RETVAL_TRUE;
                   1286: }
                   1287: /* }}} */
                   1288: 
                   1289: /* {{{ proto int xml_set_character_data_handler(resource parser, string hdl) 
                   1290:    Set up character data handler */
                   1291: PHP_FUNCTION(xml_set_character_data_handler)
                   1292: {
                   1293:        xml_parser *parser;
                   1294:        zval *pind, **hdl;
                   1295: 
                   1296:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1297:                return;
                   1298:        }
                   1299: 
                   1300:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1301: 
                   1302:        xml_set_handler(&parser->characterDataHandler, hdl);
                   1303:        XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
                   1304:        RETVAL_TRUE;
                   1305: }
                   1306: /* }}} */
                   1307: 
                   1308: /* {{{ proto int xml_set_processing_instruction_handler(resource parser, string hdl) 
                   1309:    Set up processing instruction (PI) handler */
                   1310: PHP_FUNCTION(xml_set_processing_instruction_handler)
                   1311: {
                   1312:        xml_parser *parser;
                   1313:        zval *pind, **hdl;
                   1314: 
                   1315:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1316:                return;
                   1317:        }
                   1318: 
                   1319:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1320: 
                   1321:        xml_set_handler(&parser->processingInstructionHandler, hdl);
                   1322:        XML_SetProcessingInstructionHandler(parser->parser, _xml_processingInstructionHandler);
                   1323:        RETVAL_TRUE;
                   1324: }
                   1325: /* }}} */
                   1326: 
                   1327: /* {{{ proto int xml_set_default_handler(resource parser, string hdl) 
                   1328:    Set up default handler */
                   1329: PHP_FUNCTION(xml_set_default_handler)
                   1330: {
                   1331:        xml_parser *parser;
                   1332:        zval *pind, **hdl;
                   1333: 
                   1334:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1335:                return;
                   1336:        }
                   1337:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1338: 
                   1339:        xml_set_handler(&parser->defaultHandler, hdl);
                   1340:        XML_SetDefaultHandler(parser->parser, _xml_defaultHandler);
                   1341:        RETVAL_TRUE;
                   1342: }
                   1343: /* }}} */
                   1344: 
                   1345: /* {{{ proto int xml_set_unparsed_entity_decl_handler(resource parser, string hdl) 
                   1346:    Set up unparsed entity declaration handler */
                   1347: PHP_FUNCTION(xml_set_unparsed_entity_decl_handler)
                   1348: {
                   1349:        xml_parser *parser;
                   1350:        zval *pind, **hdl;
                   1351: 
                   1352:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1353:                return;
                   1354:        }
                   1355: 
                   1356:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1357: 
                   1358:        xml_set_handler(&parser->unparsedEntityDeclHandler, hdl);
                   1359:        XML_SetUnparsedEntityDeclHandler(parser->parser, _xml_unparsedEntityDeclHandler);
                   1360:        RETVAL_TRUE;
                   1361: }
                   1362: /* }}} */
                   1363: 
                   1364: /* {{{ proto int xml_set_notation_decl_handler(resource parser, string hdl) 
                   1365:    Set up notation declaration handler */
                   1366: PHP_FUNCTION(xml_set_notation_decl_handler)
                   1367: {
                   1368:        xml_parser *parser;
                   1369:        zval *pind, **hdl;
                   1370: 
                   1371:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1372:                return;
                   1373:        }
                   1374:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1375: 
                   1376:        xml_set_handler(&parser->notationDeclHandler, hdl);
                   1377:        XML_SetNotationDeclHandler(parser->parser, _xml_notationDeclHandler);
                   1378:        RETVAL_TRUE;
                   1379: }
                   1380: /* }}} */
                   1381: 
                   1382: /* {{{ proto int xml_set_external_entity_ref_handler(resource parser, string hdl) 
                   1383:    Set up external entity reference handler */
                   1384: PHP_FUNCTION(xml_set_external_entity_ref_handler)
                   1385: {
                   1386:        xml_parser *parser;
                   1387:        zval *pind, **hdl;
                   1388: 
                   1389:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1390:                return;
                   1391:        }
                   1392:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1393: 
                   1394:        xml_set_handler(&parser->externalEntityRefHandler, hdl);
                   1395:        XML_SetExternalEntityRefHandler(parser->parser, (void *) _xml_externalEntityRefHandler);
                   1396:        RETVAL_TRUE;
                   1397: }
                   1398: /* }}} */
                   1399: 
                   1400: /* {{{ proto int xml_set_start_namespace_decl_handler(resource parser, string hdl) 
                   1401:    Set up character data handler */
                   1402: PHP_FUNCTION(xml_set_start_namespace_decl_handler)
                   1403: {
                   1404:        xml_parser *parser;
                   1405:        zval *pind, **hdl;
                   1406: 
                   1407:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1408:                return;
                   1409:        }
                   1410: 
                   1411:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1412: 
                   1413:        xml_set_handler(&parser->startNamespaceDeclHandler, hdl);
                   1414:        XML_SetStartNamespaceDeclHandler(parser->parser, _xml_startNamespaceDeclHandler);
                   1415:        RETVAL_TRUE;
                   1416: }
                   1417: /* }}} */
                   1418: 
                   1419: /* {{{ proto int xml_set_end_namespace_decl_handler(resource parser, string hdl) 
                   1420:    Set up character data handler */
                   1421: PHP_FUNCTION(xml_set_end_namespace_decl_handler)
                   1422: {
                   1423:        xml_parser *parser;
                   1424:        zval *pind, **hdl;
                   1425: 
                   1426:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
                   1427:                return;
                   1428:        }
                   1429: 
                   1430:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1431: 
                   1432:        xml_set_handler(&parser->endNamespaceDeclHandler, hdl);
                   1433:        XML_SetEndNamespaceDeclHandler(parser->parser, _xml_endNamespaceDeclHandler);
                   1434:        RETVAL_TRUE;
                   1435: }
                   1436: /* }}} */
                   1437: 
                   1438: /* {{{ proto int xml_parse(resource parser, string data [, int isFinal]) 
                   1439:    Start parsing an XML document */
                   1440: PHP_FUNCTION(xml_parse)
                   1441: {
                   1442:        xml_parser *parser;
                   1443:        zval *pind;
                   1444:        char *data;
                   1445:        int data_len, ret;
                   1446:        long isFinal = 0;
                   1447: 
                   1448:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &pind, &data, &data_len, &isFinal) == FAILURE) {
                   1449:                return;
                   1450:        }
                   1451:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1452: 
                   1453:        parser->isparsing = 1;
                   1454:        ret = XML_Parse(parser->parser, data, data_len, isFinal);
                   1455:        parser->isparsing = 0;
                   1456:        RETVAL_LONG(ret);
                   1457: }
                   1458: 
                   1459: /* }}} */
                   1460: 
                   1461: /* {{{ proto int xml_parse_into_struct(resource parser, string data, array &values [, array &index ])
                   1462:    Parsing a XML document */
                   1463: 
                   1464: PHP_FUNCTION(xml_parse_into_struct)
                   1465: {
                   1466:        xml_parser *parser;
                   1467:        zval *pind, **xdata, **info = NULL;
                   1468:        char *data;
                   1469:        int data_len, ret;
                   1470: 
                   1471:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ|Z", &pind, &data, &data_len, &xdata, &info) == FAILURE) {
                   1472:                return;
                   1473:        }
                   1474:        
                   1475:        if (info) {     
                   1476:                zval_dtor(*info);
                   1477:                array_init(*info);
                   1478:        }
                   1479: 
                   1480:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1481: 
                   1482:        zval_dtor(*xdata);
                   1483:        array_init(*xdata);
                   1484: 
                   1485:        parser->data = *xdata;
                   1486:        
                   1487:        if (info) {
                   1488:                parser->info = *info;
                   1489:        }
                   1490:        
                   1491:        parser->level = 0;
                   1492:        parser->ltags = safe_emalloc(XML_MAXLEVEL, sizeof(char *), 0);
                   1493: 
                   1494:        XML_SetDefaultHandler(parser->parser, _xml_defaultHandler);
                   1495:        XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
                   1496:        XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
                   1497: 
                   1498:        parser->isparsing = 1;
                   1499:        ret = XML_Parse(parser->parser, data, data_len, 1);
                   1500:        parser->isparsing = 0;
                   1501: 
                   1502:        RETVAL_LONG(ret);
                   1503: }
                   1504: /* }}} */
                   1505: 
                   1506: /* {{{ proto int xml_get_error_code(resource parser) 
                   1507:    Get XML parser error code */
                   1508: PHP_FUNCTION(xml_get_error_code)
                   1509: {
                   1510:        xml_parser *parser;
                   1511:        zval *pind;
                   1512: 
                   1513:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1514:                return;
                   1515:        }
                   1516:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1517: 
                   1518:        RETVAL_LONG((long)XML_GetErrorCode(parser->parser));
                   1519: }
                   1520: /* }}} */
                   1521: 
                   1522: /* {{{ proto string xml_error_string(int code)
                   1523:    Get XML parser error string */
                   1524: PHP_FUNCTION(xml_error_string)
                   1525: {
                   1526:        long code;
                   1527:        char *str;
                   1528: 
                   1529:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code) == FAILURE) {
                   1530:                return;
                   1531:        }
                   1532: 
                   1533:        str = (char *)XML_ErrorString((int)code);
                   1534:        if (str) {
                   1535:                RETVAL_STRING(str, 1);
                   1536:        }
                   1537: }
                   1538: /* }}} */
                   1539: 
                   1540: /* {{{ proto int xml_get_current_line_number(resource parser) 
                   1541:    Get current line number for an XML parser */
                   1542: PHP_FUNCTION(xml_get_current_line_number)
                   1543: {
                   1544:        xml_parser *parser;
                   1545:        zval *pind;
                   1546: 
                   1547:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1548:                return;
                   1549:        }
                   1550:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1551: 
                   1552:        RETVAL_LONG(XML_GetCurrentLineNumber(parser->parser));
                   1553: }
                   1554: /* }}} */
                   1555: 
                   1556: /* {{{ proto int xml_get_current_column_number(resource parser)
                   1557:    Get current column number for an XML parser */
                   1558: PHP_FUNCTION(xml_get_current_column_number)
                   1559: {
                   1560:        xml_parser *parser;
                   1561:        zval *pind;
                   1562: 
                   1563:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1564:                return;
                   1565:        }
                   1566:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1567: 
                   1568:        RETVAL_LONG(XML_GetCurrentColumnNumber(parser->parser));
                   1569: }
                   1570: /* }}} */
                   1571: 
                   1572: /* {{{ proto int xml_get_current_byte_index(resource parser) 
                   1573:    Get current byte index for an XML parser */
                   1574: PHP_FUNCTION(xml_get_current_byte_index)
                   1575: {
                   1576:        xml_parser *parser;
                   1577:        zval *pind;
                   1578: 
                   1579:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1580:                return;
                   1581:        }
                   1582:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1583: 
                   1584:        RETVAL_LONG(XML_GetCurrentByteIndex(parser->parser));
                   1585: }
                   1586: /* }}} */
                   1587: 
                   1588: /* {{{ proto int xml_parser_free(resource parser) 
                   1589:    Free an XML parser */
                   1590: PHP_FUNCTION(xml_parser_free)
                   1591: {
                   1592:        zval *pind;
                   1593:        xml_parser *parser;
                   1594: 
                   1595:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
                   1596:                return;
                   1597:        }
                   1598: 
                   1599:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1600: 
                   1601:        if (parser->isparsing == 1) {
                   1602:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parser cannot be freed while it is parsing.");
                   1603:                RETURN_FALSE;
                   1604:        }
                   1605: 
                   1606:        if (zend_list_delete(parser->index) == FAILURE) {
                   1607:                RETURN_FALSE;
                   1608:        }
                   1609: 
                   1610:        RETVAL_TRUE;
                   1611: }
                   1612: /* }}} */
                   1613: 
                   1614: /* {{{ proto int xml_parser_set_option(resource parser, int option, mixed value) 
                   1615:    Set options in an XML parser */
                   1616: PHP_FUNCTION(xml_parser_set_option)
                   1617: {
                   1618:        xml_parser *parser;
                   1619:        zval *pind, **val;
                   1620:        long opt;
                   1621: 
                   1622:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &pind, &opt, &val) == FAILURE) {
                   1623:                return;
                   1624:        }
                   1625:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1626: 
                   1627:        switch (opt) {
                   1628:                case PHP_XML_OPTION_CASE_FOLDING:
                   1629:                        convert_to_long_ex(val);
                   1630:                        parser->case_folding = Z_LVAL_PP(val);
                   1631:                        break;
                   1632:                case PHP_XML_OPTION_SKIP_TAGSTART:
                   1633:                        convert_to_long_ex(val);
                   1634:                        parser->toffset = Z_LVAL_PP(val);
                   1635:                        break;
                   1636:                case PHP_XML_OPTION_SKIP_WHITE:
                   1637:                        convert_to_long_ex(val);
                   1638:                        parser->skipwhite = Z_LVAL_PP(val);
                   1639:                        break;
                   1640:                case PHP_XML_OPTION_TARGET_ENCODING: {
                   1641:                        xml_encoding *enc;
                   1642:                        convert_to_string_ex(val);
                   1643:                        enc = xml_get_encoding(Z_STRVAL_PP(val));
                   1644:                        if (enc == NULL) {
                   1645:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported target encoding \"%s\"", Z_STRVAL_PP(val));
                   1646:                                RETURN_FALSE;
                   1647:                        }
                   1648:                        parser->target_encoding = enc->name;
                   1649:                        break;
                   1650:                }
                   1651:                default:
                   1652:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option");
                   1653:                        RETURN_FALSE;
                   1654:                        break;
                   1655:        }
                   1656:        RETVAL_TRUE;
                   1657: }
                   1658: /* }}} */
                   1659: 
                   1660: /* {{{ proto int xml_parser_get_option(resource parser, int option) 
                   1661:    Get options from an XML parser */
                   1662: PHP_FUNCTION(xml_parser_get_option)
                   1663: {
                   1664:        xml_parser *parser;
                   1665:        zval *pind;
                   1666:        long opt;
                   1667: 
                   1668:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pind, &opt) == FAILURE) {
                   1669:                return;
                   1670:        }
                   1671:        ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
                   1672: 
                   1673:        switch (opt) {
                   1674:                case PHP_XML_OPTION_CASE_FOLDING:
                   1675:                        RETURN_LONG(parser->case_folding);
                   1676:                        break;
                   1677:                case PHP_XML_OPTION_TARGET_ENCODING:
                   1678:                        RETURN_STRING(parser->target_encoding, 1);
                   1679:                        break;
                   1680:                default:
                   1681:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option");
                   1682:                        RETURN_FALSE;
                   1683:                        break;
                   1684:        }
                   1685: 
                   1686:        RETVAL_FALSE;   /* never reached */
                   1687: }
                   1688: /* }}} */
                   1689: 
                   1690: /* {{{ proto string utf8_encode(string data) 
                   1691:    Encodes an ISO-8859-1 string to UTF-8 */
                   1692: PHP_FUNCTION(utf8_encode)
                   1693: {
                   1694:        char *arg;
                   1695:        XML_Char *encoded;
                   1696:        int arg_len, len;
                   1697: 
                   1698:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                   1699:                return;
                   1700:        }
                   1701: 
                   1702:        encoded = xml_utf8_encode(arg, arg_len, &len, "ISO-8859-1");
                   1703:        if (encoded == NULL) {
                   1704:                RETURN_FALSE;
                   1705:        }
                   1706:        RETVAL_STRINGL(encoded, len, 0);
                   1707: }
                   1708: /* }}} */
                   1709: 
                   1710: /* {{{ proto string utf8_decode(string data) 
                   1711:    Converts a UTF-8 encoded string to ISO-8859-1 */
                   1712: PHP_FUNCTION(utf8_decode)
                   1713: {
                   1714:        char *arg;
                   1715:        XML_Char *decoded;
                   1716:        int arg_len, len;
                   1717: 
                   1718:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                   1719:                return;
                   1720:        }
                   1721: 
                   1722:        decoded = xml_utf8_decode(arg, arg_len, &len, "ISO-8859-1");
                   1723:        if (decoded == NULL) {
                   1724:                RETURN_FALSE;
                   1725:        }
                   1726:        RETVAL_STRINGL(decoded, len, 0);
                   1727: }
                   1728: /* }}} */
                   1729: 
                   1730: #endif
                   1731: 
                   1732: /*
                   1733:  * Local variables:
                   1734:  * tab-width: 4
                   1735:  * c-basic-offset: 4
                   1736:  * End:
                   1737:  * vim600: sw=4 ts=4 fdm=marker
                   1738:  * vim<600: sw=4 ts=4
                   1739:  */

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