rrichards               Wed May 10 12:04:47 2006 UTC

  Added files:                 (Branch: PHP_5_2)
    /php-src/ext/xmlreader/tests        013.phpt 013.xsd 

  Modified files:              
    /php-src/ext/xmlreader      php_xmlreader.c php_xmlreader.h 
  Log:
  Synch with HEAD
    add readInnerXML, readOuterXML, readString, and setSchema functionality
    allow parser options to be passed when loading reader
    optimization: use xmlTextReader const functions for string properties
    add test
  
http://cvs.php.net/viewcvs.cgi/php-src/ext/xmlreader/php_xmlreader.c?r1=1.13.2.14&r2=1.13.2.14.2.1&diff_format=u
Index: php-src/ext/xmlreader/php_xmlreader.c
diff -u php-src/ext/xmlreader/php_xmlreader.c:1.13.2.14 
php-src/ext/xmlreader/php_xmlreader.c:1.13.2.14.2.1
--- php-src/ext/xmlreader/php_xmlreader.c:1.13.2.14     Mon Apr  3 14:59:30 2006
+++ php-src/ext/xmlreader/php_xmlreader.c       Wed May 10 12:04:46 2006
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: php_xmlreader.c,v 1.13.2.14 2006/04/03 14:59:30 tony2001 Exp $ */
+/* $Id: php_xmlreader.c,v 1.13.2.14.2.1 2006/05/10 12:04:46 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -40,21 +40,23 @@
 
 typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
 typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
+typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr 
reader);
 typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval 
TSRMLS_DC);
 
 typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, 
const unsigned char *);
 
 typedef struct _xmlreader_prop_handler {
        xmlreader_read_int_t read_int_func;
-       xmlreader_read_char_t read_char_func;
+       xmlreader_read_const_char_t read_char_func;
        xmlreader_write_t write_func;
        int type;
 } xmlreader_prop_handler;
 
 #define XMLREADER_LOAD_STRING 0
 #define XMLREADER_LOAD_FILE 1
+
 /* {{{ xmlreader_register_prop_handler */
-static void xmlreader_register_prop_handler(HashTable *prop_handler, char 
*name, xmlreader_read_int_t read_int_func, xmlreader_read_char_t 
read_char_func, int rettype TSRMLS_DC)
+static void xmlreader_register_prop_handler(HashTable *prop_handler, char 
*name, xmlreader_read_int_t read_int_func, xmlreader_read_const_char_t 
read_char_func, int rettype TSRMLS_DC)
 {
        xmlreader_prop_handler hnd;
        
@@ -68,7 +70,7 @@
 /* {{{ xmlreader_property_reader */
 static int xmlreader_property_reader(xmlreader_object *obj, 
xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC)
 {
-       char *retchar = NULL;
+       const xmlChar *retchar = NULL;
        int retint = 0;
 
        if (obj->ptr != NULL) {
@@ -90,8 +92,7 @@
        switch (hnd->type) {
                case IS_STRING:
                        if (retchar) {
-                               ZVAL_STRING(*retval, retchar, 1);
-                               xmlFree(retchar);
+                               ZVAL_STRING(*retval, (xmlChar *) retchar, 1);
                        } else {
                                ZVAL_EMPTY_STRING(*retval);
                        }
@@ -377,20 +378,8 @@
 {
        xmlreader_object *intern = (xmlreader_object *)object;
 
-#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 
2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 
5)
        zend_object_std_dtor(&intern->std TSRMLS_CC);
-#else
-       if (intern->std.guards) {
-               zend_hash_destroy(intern->std.guards);
-               FREE_HASHTABLE(intern->std.guards);
-       }
-
-       if (intern->std.properties) {
-               zend_hash_destroy(intern->std.properties);
-               FREE_HASHTABLE(intern->std.properties);
-       }
-#endif
-
+       
        xmlreader_free_resources(intern);
 
        efree(object);
@@ -405,21 +394,13 @@
        zval *tmp;
 
        intern = emalloc(sizeof(xmlreader_object));
+       memset(&intern->std, 0, sizeof(zend_object));
        intern->ptr = NULL;
        intern->input = NULL;
        intern->schema = NULL;
        intern->prop_handler = &xmlreader_prop_handlers;
 
-#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 
2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 
5)
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
-#else
-       ALLOC_HASHTABLE(intern->std.properties);
-       zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
-
-       intern->std.ce = class_type;
-       intern->std.guards = NULL;
-#endif
-
        zend_hash_copy(intern->std.properties, &class_type->default_properties, 
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
        retval.handle = zend_objects_store_put(intern, 
(zend_objects_store_dtor_t)zend_objects_destroy_object, 
(zend_objects_free_object_storage_t) xmlreader_objects_free_storage, 
xmlreader_objects_clone TSRMLS_CC);
        intern->handle = retval.handle;
@@ -481,7 +462,7 @@
 }
 /* }}} */
 
-/* This function not yet needed until some additional functions are 
implemented in libxml
+/* {{{ php_xmlreader_no_arg_string */
 static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, 
xmlreader_read_char_t internal_function) {
        zval *id;
        char *retchar = NULL;
@@ -491,7 +472,7 @@
 
        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        if (intern && intern->ptr) {
-               retchar = xmlTextReaderReadString(intern->ptr);
+               retchar = internal_function(intern->ptr);
        }
        if (retchar) {
                RETVAL_STRING(retchar, 1);
@@ -501,7 +482,7 @@
                RETVAL_EMPTY_STRING();
        }
 }
-*/
+/* }}} */
 
 /* {{{ php_xmlreader_set_relaxng_schema */
 static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int 
type) {
@@ -876,18 +857,20 @@
 }
 /* }}} */
 
-/* {{{ proto boolean XMLReader::open(string URI)
+/* {{{ proto boolean XMLReader::open(string URI [, string encoding [, int 
options]])
 Sets the URI that the the XMLReader will parse. */
 PHP_METHOD(xmlreader, open)
 {
        zval *id;
-       int source_len = 0;
+       int source_len = 0, encoding_len = 0;
+       long options = 0;
        xmlreader_object *intern = NULL;
        char *source, *valid_file = NULL;
+       char *encoding = NULL;
        char resolved_path[MAXPATHLEN + 1];
        xmlTextReaderPtr reader = NULL;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, 
&source_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, 
&source_len, &encoding, &encoding_len, &options) == FAILURE) {
                return;
        }
 
@@ -909,7 +892,7 @@
        valid_file = _xmlreader_get_valid_file_path(source, resolved_path, 
MAXPATHLEN  TSRMLS_CC);
 
        if (valid_file) {
-               reader = xmlNewTextReaderFilename(valid_file);
+               reader = xmlReaderForFile(valid_file, encoding, options);
        }
 
        if (reader == NULL) {
@@ -932,26 +915,78 @@
 /* }}} */
 
 /* Not Yet Implemented in libxml - functions exist just not coded
+PHP_METHOD(xmlreader, resetState)
+{
+
+}
+*/
+
+#if LIBXML_VERSION >= 20620
+/* {{{ proto boolean XMLReader::readInnerXml()
+Reads the contents of the current node, including child nodes and markup. */
 PHP_METHOD(xmlreader, readInnerXml)
 {
        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
xmlTextReaderReadInnerXml);
 }
+/* }}} */
 
+/* {{{ proto boolean XMLReader::readOuterXml()
+Reads the contents of the current node, including child nodes and markup. */
 PHP_METHOD(xmlreader, readOuterXml)
 {
-       php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
xmlTextReaderReadInnerXml);
+       php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
xmlTextReaderReadOuterXml);
 }
+/* }}} */
 
+/* {{{ proto boolean XMLReader::readString()
+Reads the contents of an element or a text node as a string. */
 PHP_METHOD(xmlreader, readString)
 {
        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
xmlTextReaderReadString);
 }
+/* }}} */
 
-PHP_METHOD(xmlreader, resetState)
+/* {{{ proto boolean XMLReader::setSchema(string filename)
+Use W3C XSD schema to validate the document as it is processed. Activation is 
only possible before the first Read(). */
+PHP_METHOD(xmlreader, setSchema)
 {
+#ifdef LIBXML_SCHEMAS_ENABLED
+       zval *id;
+       int source_len = 0, retval = -1;
+       xmlreader_object *intern;
+       char *source;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &source, 
&source_len) == FAILURE) {
+               return;
+       }
+
+       if (source != NULL && !source_len) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source 
is required");
+               RETURN_FALSE;
+       }
+
+       id = getThis();
+
+       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       if (intern && intern->ptr) {
+               retval = xmlTextReaderSchemaValidate(intern->ptr, source);
+
+               if (retval == 0) {
+                       RETURN_TRUE;
+               }
+       }
+       
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This 
must be set prior to reading or schema contains errors.");
+
+       RETURN_FALSE;
+#else
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built 
into libxml.");
 
+       RETURN_FALSE;
+#endif
 }
-*/
+/* }}} */
+#endif
 
 /* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value)
 Sets parser property (one of the parser option constants).
@@ -959,7 +994,8 @@
 PHP_METHOD(xmlreader, setParserProperty)
 {
        zval *id;
-       int property, retval = -1;
+       long property;
+       int retval = -1;
        zend_bool value;
        xmlreader_object *intern;
 
@@ -982,7 +1018,7 @@
 }
 /* }}} */
 
-/* {{{ proto boolean XMLReader::setRelaxNGSchemaSource(string filename)
+/* {{{ proto boolean XMLReader::setRelaxNGSchema(string filename)
 Sets the string that the the XMLReader will parse. */
 PHP_METHOD(xmlreader, setRelaxNGSchema)
 {
@@ -998,20 +1034,27 @@
 }
 /* }}} */
 
-/* {{{ proto boolean XMLReader::XML(string source)
+/* TODO
+XMLPUBFUN int XMLCALL          
+                   xmlTextReaderSetSchema      (xmlTextReaderPtr reader,
+                                                xmlSchemaPtr schema);
+*/
+
+/* {{{ proto boolean XMLReader::XML(string source [, string encoding [, int 
options]])
 Sets the string that the the XMLReader will parse. */
 PHP_METHOD(xmlreader, XML)
 {
        zval *id;
-       int source_len = 0;
+       int source_len = 0, encoding_len = 0;
+       long options = 0;
        xmlreader_object *intern = NULL;
-       char *source, *uri = NULL;
+       char *source, *uri = NULL, *encoding = NULL;
        int resolved_path_len;
        char *directory=NULL, resolved_path[MAXPATHLEN];
        xmlParserInputBufferPtr inputbfr;
        xmlTextReaderPtr reader;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, 
&source_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, 
&source_len, &encoding, &encoding_len, &options) == FAILURE) {
                return;
        }
 
@@ -1054,15 +1097,12 @@
                        if (id == NULL) {
                                object_init_ex(return_value, 
xmlreader_class_entry);
                                intern = (xmlreader_object 
*)zend_objects_get_address(return_value TSRMLS_CC);
-                               intern->input = inputbfr;
-                               intern->ptr = reader;
-                               return;
                        } else {
-                               intern->input = inputbfr;
-                               intern->ptr = reader;
-                               RETURN_TRUE;
-
+                               RETVAL_TRUE;
                        }
+                       intern->input = inputbfr;
+                       intern->ptr = reader;
+                       return;
                }
        }
 
@@ -1095,7 +1135,12 @@
                        RETURN_FALSE;
                } else {
                        nodec = xmlCopyNode(node, 1);
-                       DOM_RET_OBJ(rv, nodec, &ret, NULL);
+                       if (nodec == NULL) {
+                               php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
"Cannot expand this node type");
+                               RETURN_FALSE;
+                       } else {
+                               DOM_RET_OBJ(rv, nodec, &ret, NULL);
+                       }
                }
        } else {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before 
trying to expand");
@@ -1125,10 +1170,13 @@
        PHP_ME(xmlreader, open, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
        PHP_ME(xmlreader, read, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(xmlreader, next, NULL, ZEND_ACC_PUBLIC)
-/* Not Yet Implemented though defined in libxml as of 2.6.9dev
+#if LIBXML_VERSION >= 20620
        PHP_ME(xmlreader, readInnerXml, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(xmlreader, readOuterXml, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(xmlreader, readString, NULL, ZEND_ACC_PUBLIC)
+       PHP_ME(xmlreader, setSchema, NULL, ZEND_ACC_PUBLIC)
+#endif
+/* Not Yet Implemented though defined in libxml as of 2.6.9dev
        PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC)
 */
        PHP_ME(xmlreader, setParserProperty, NULL, ZEND_ACC_PUBLIC)
@@ -1157,19 +1205,19 @@
 
        zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, 
"attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", 
NULL, xmlTextReaderBaseUri, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", 
NULL, xmlTextReaderConstBaseUri, IS_STRING TSRMLS_CC);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", 
xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, 
"hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", 
xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", 
xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, 
"isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", 
NULL, xmlTextReaderLocalName, IS_STRING TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, 
xmlTextReaderName, IS_STRING TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, 
"namespaceURI", NULL, xmlTextReaderNamespaceUri, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", 
NULL, xmlTextReaderConstLocalName, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, 
xmlTextReaderConstName, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, 
"namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING TSRMLS_CC);
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", 
xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", 
NULL, xmlTextReaderPrefix, IS_STRING TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", 
NULL, xmlTextReaderValue, IS_STRING TSRMLS_CC);
-       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", 
NULL, xmlTextReaderXmlLang, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", 
NULL, xmlTextReaderConstPrefix, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", 
NULL, xmlTextReaderConstValue, IS_STRING TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", 
NULL, xmlTextReaderConstXmlLang, IS_STRING TSRMLS_CC);
 
        /* Constants for NodeType - cannot define common types to share with 
dom as there are differences in these types */
 
http://cvs.php.net/viewcvs.cgi/php-src/ext/xmlreader/php_xmlreader.h?r1=1.3.2.2&r2=1.3.2.2.2.1&diff_format=u
Index: php-src/ext/xmlreader/php_xmlreader.h
diff -u php-src/ext/xmlreader/php_xmlreader.h:1.3.2.2 
php-src/ext/xmlreader/php_xmlreader.h:1.3.2.2.2.1
--- php-src/ext/xmlreader/php_xmlreader.h:1.3.2.2       Sun Jan  1 12:50:16 2006
+++ php-src/ext/xmlreader/php_xmlreader.h       Wed May 10 12:04:46 2006
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: php_xmlreader.h,v 1.3.2.2 2006/01/01 12:50:16 sniper Exp $ */
+/* $Id: php_xmlreader.h,v 1.3.2.2.2.1 2006/05/10 12:04:46 rrichards Exp $ */
 
 #ifndef PHP_XMLREADER_H
 #define PHP_XMLREADER_H
@@ -40,9 +40,7 @@
 typedef struct _xmlreader_object {
        zend_object  std;
        xmlTextReaderPtr ptr;
-       /* input is used to allow strings to be loaded under libxml 2.5.x
-       must manually allocate and de-allocate these - can be refactored when
-       libxml 2.6.x becomes minimum version */
+       /* strings must be set in input buffer as copy is required */
        xmlParserInputBufferPtr input;
        void *schema;
        HashTable *prop_handler;

http://cvs.php.net/viewcvs.cgi/php-src/ext/xmlreader/tests/013.phpt?view=markup&rev=1.1
Index: php-src/ext/xmlreader/tests/013.phpt
+++ php-src/ext/xmlreader/tests/013.phpt
--TEST--
XMLReader: Schema validation
--SKIPIF--
<?php if (!extension_loaded('xmlreader')) die('skip');?>
<?php if (!method_exists('XMLReader','setSchema')) die('skip 
XMLReader::setSchema() not supported');?>
--FILE--
<?php 
/* $Id: 013.phpt,v 1.1 2006/03/31 20:50:29 helly Exp $ */

$xml =<<<EOF
<?xml version="1.0" encoding="UTF-8" ?>
<items>
  <item>123</item>
  <item>456</item>
</items>
EOF;

$reader = new XMLReader();
$reader->XML($xml);
$reader->setSchema(dirname(__FILE__) . '/013.xsd');
while($reader->read()) {
        if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'item') 
{
                $reader->read();
                var_dump($reader->value);
        }
}
$reader->close();

?>
===FAIL===
<?php

$xml =<<<EOF
<?xml version="1.0" encoding="UTF-8" ?>
<foo/>
EOF;

$reader = new XMLReader();
$reader->XML($xml);
$reader->setSchema(dirname(__FILE__) . '/013.xsd');
while($reader->read() && $reader->nodeType != XMLReader::ELEMENT);
$reader->close();

?>
===DONE===
--EXPECTF--
string(3) "123"
string(3) "456"
===FAIL===

Warning: XMLReader::read(): Element 'foo': %s
===DONE===

http://cvs.php.net/viewcvs.cgi/php-src/ext/xmlreader/tests/013.xsd?view=markup&rev=1.1
Index: php-src/ext/xmlreader/tests/013.xsd
+++ php-src/ext/xmlreader/tests/013.xsd
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
  <xsd:element name="items">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="item" type="xsd:integer" minOccurs="0" 
maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to