]> granicus.if.org Git - php/commitdiff
Port XMLReader
authorXinchen Hui <laruence@gmail.com>
Sun, 4 May 2014 03:12:55 +0000 (11:12 +0800)
committerXinchen Hui <laruence@gmail.com>
Sun, 4 May 2014 03:12:55 +0000 (11:12 +0800)
ext/xmlreader/php_xmlreader.c
ext/xmlreader/php_xmlreader.h

index 329812cb2119e5de18629daf29fe323ce2017fa1..8945222e32e11df51c21143956f2c99cfbb9549c 100644 (file)
@@ -64,12 +64,12 @@ static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name,
        hnd.read_char_func = read_char_func;
        hnd.read_int_func = read_int_func;
        hnd.type = rettype;
-       zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(xmlreader_prop_handler), NULL);
+       zend_hash_str_add_mem(prop_handler, name, strlen(name), &hnd, sizeof(xmlreader_prop_handler));
 }
 /* }}} */
 
 /* {{{ xmlreader_property_reader */
-static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC)
+static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval *rv TSRMLS_DC)
 {
        const xmlChar *retchar = NULL;
        int retint = 0;
@@ -88,24 +88,23 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl
                }
        }
 
-       ALLOC_ZVAL(*retval);
-
        switch (hnd->type) {
                case IS_STRING:
                        if (retchar) {
-                               ZVAL_STRING(*retval, (char *) retchar, 1);
+                               ZVAL_STRING(rv, (char *) retchar);
                        } else {
-                               ZVAL_EMPTY_STRING(*retval);
+                               ZVAL_EMPTY_STRING(rv);
                        }
                        break;
-               case IS_BOOL:
-                       ZVAL_BOOL(*retval, retint);
+               /* this IS_FALSE actually means it's a BOOL type */
+               case IS_FALSE:
+                       ZVAL_BOOL(rv, retint);
                        break;
                case IS_LONG:
-                       ZVAL_LONG(*retval, retint);
+                       ZVAL_LONG(rv, retint);
                        break;
                default:
-                       ZVAL_NULL(*retval);
+                       ZVAL_NULL(rv);
        }
 
        return SUCCESS;
@@ -113,73 +112,71 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl
 /* }}} */
 
 /* {{{ xmlreader_get_property_ptr_ptr */
-zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
+zval *xmlreader_get_property_ptr_ptr(zval *object, zval *member, int type, zend_uint cache_slot TSRMLS_DC)
 {
        xmlreader_object *obj;
        zval tmp_member;
-       zval **retval = NULL;
-       xmlreader_prop_handler *hnd;
+       zval *retval = NULL;
+       xmlreader_prop_handler *hnd = NULL;
        zend_object_handlers *std_hnd;
-       int ret = FAILURE;
 
-       if (member->type != IS_STRING) {
+       if (Z_TYPE_P(member) != IS_STRING) {
                tmp_member = *member;
                zval_copy_ctor(&tmp_member);
                convert_to_string(&tmp_member);
                member = &tmp_member;
        }
 
-       obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
+       obj = Z_XMLREADER_P(object);
 
        if (obj->prop_handler != NULL) {
-               ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+               hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
        }
-       if (ret == FAILURE) {
+
+       if (hnd == NULL) {
                std_hnd = zend_get_std_object_handlers();
-               retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
+               retval = std_hnd->get_property_ptr_ptr(object, member, type, cache_slot TSRMLS_CC);
        }
 
        if (member == &tmp_member) {
                zval_dtor(member);
        }
+
        return retval;
 }
 /* }}} */
 
 /* {{{ xmlreader_read_property */
-zval *xmlreader_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
+zval *xmlreader_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC)
 {
        xmlreader_object *obj;
        zval tmp_member;
-       zval *retval;
-       xmlreader_prop_handler *hnd;
+       zval *retval = NULL;
+       xmlreader_prop_handler *hnd = NULL;
        zend_object_handlers *std_hnd;
-       int ret;
 
-       if (member->type != IS_STRING) {
+       if (Z_TYPE_P(member) != IS_STRING) {
                tmp_member = *member;
                zval_copy_ctor(&tmp_member);
                convert_to_string(&tmp_member);
                member = &tmp_member;
        }
 
-       ret = FAILURE;
-       obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
+       obj = Z_XMLREADER_P(object);
 
        if (obj->prop_handler != NULL) {
-               ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+               hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
        }
-       if (ret == SUCCESS) {
-               ret = xmlreader_property_reader(obj, hnd, &retval TSRMLS_CC);
-               if (ret == SUCCESS) {
-                       /* ensure we're creating a temporary variable */
-                       Z_SET_REFCOUNT_P(retval, 0);
+
+       if (hnd != NULL) {
+               if (xmlreader_property_reader(obj, hnd, rv TSRMLS_CC) == FAILURE) {
+                       retval = &EG(uninitialized_zval);
                } else {
-                       retval = EG(uninitialized_zval_ptr);
+                       retval = rv;
                }
        } else {
                std_hnd = zend_get_std_object_handlers();
-               retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
+               retval = std_hnd->read_property(object, member, type, cache_slot, rv TSRMLS_CC);
        }
 
        if (member == &tmp_member) {
@@ -190,32 +187,30 @@ zval *xmlreader_read_property(zval *object, zval *member, int type, const zend_l
 /* }}} */
 
 /* {{{ xmlreader_write_property */
-void xmlreader_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
+void xmlreader_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC)
 {
        xmlreader_object *obj;
        zval tmp_member;
-       xmlreader_prop_handler *hnd;
+       xmlreader_prop_handler *hnd = NULL;
        zend_object_handlers *std_hnd;
-       int ret;
 
-       if (member->type != IS_STRING) {
+       if (Z_TYPE_P(member) != IS_STRING) {
                tmp_member = *member;
                zval_copy_ctor(&tmp_member);
                convert_to_string(&tmp_member);
                member = &tmp_member;
        }
 
-       ret = FAILURE;
-       obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
+       obj = Z_XMLREADER_P(object);
 
        if (obj->prop_handler != NULL) {
-               ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+               hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
        }
-       if (ret == SUCCESS) {
+       if (hnd != NULL) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write to read-only property");
        } else {
                std_hnd = zend_get_std_object_handlers();
-               std_hnd->write_property(object, member, value, key TSRMLS_CC);
+               std_hnd->write_property(object, member, value, cache_slot TSRMLS_CC);
        }
 
        if (member == &tmp_member) {
@@ -375,37 +370,28 @@ static void xmlreader_free_resources(xmlreader_object *intern) {
 /* }}} */
 
 /* {{{ xmlreader_objects_free_storage */
-void xmlreader_objects_free_storage(void *object TSRMLS_DC)
+void xmlreader_objects_free_storage(zend_object *object TSRMLS_DC)
 {
-       xmlreader_object *intern = (xmlreader_object *)object;
+       xmlreader_object *intern = php_xmlreader_fetch_object(object);
 
        zend_object_std_dtor(&intern->std TSRMLS_CC);
 
        xmlreader_free_resources(intern);
-
-       efree(object);
 }
 /* }}} */
 
 /* {{{ xmlreader_objects_new */
-zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC)
+zend_object *xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC)
 {
-       zend_object_value retval;
        xmlreader_object *intern;
 
-       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;
-
+       intern = ecalloc(1, sizeof(xmlreader_object) + sizeof(zval) * (class_type->default_properties_count - 1));
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
-       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;
-       retval.handlers = &xmlreader_object_handlers;
-       return retval;
+       intern->prop_handler = &xmlreader_prop_handlers;
+       intern->std.handlers = &xmlreader_object_handlers;
+
+       return &intern->std;
 }
 /* }}} */
 
@@ -428,12 +414,12 @@ static void php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_rea
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retchar = (char *)internal_function(intern->ptr, (const unsigned char *)name);
        }
        if (retchar) {
-               RETVAL_STRING(retchar, 1);
+               RETVAL_STRING(retchar);
                xmlFree(retchar);
                return;
        } else {
@@ -450,7 +436,7 @@ static void php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_in
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = internal_function(intern->ptr);
                if (retval == 1) {
@@ -471,12 +457,12 @@ static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retchar = (char *)internal_function(intern->ptr);
        }
        if (retchar) {
-               RETVAL_STRING(retchar, 1);
+               RETVAL_STRING(retchar);
                xmlFree(retchar);
                return;
        } else {
@@ -506,7 +492,7 @@ static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int t
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                if (source) {
                        schema =  _xmlreader_get_relaxNG(source, source_len, type, NULL, NULL TSRMLS_CC);
@@ -548,7 +534,7 @@ PHP_METHOD(xmlreader, close)
        xmlreader_object *intern;
 
        id = getThis();
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        /* libxml is segfaulting in versions up to 2.6.8 using xmlTextReaderClose so for
        now we will free the whole reader when close is called as it would get rebuilt on
        a new load anyways */
@@ -581,12 +567,12 @@ PHP_METHOD(xmlreader, getAttributeNo)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retchar = (char *)xmlTextReaderGetAttributeNo(intern->ptr, attr_pos);
        }
        if (retchar) {
-               RETVAL_STRING(retchar, 1);
+               RETVAL_STRING(retchar);
                xmlFree(retchar);
        }
 }
@@ -612,12 +598,12 @@ PHP_METHOD(xmlreader, getAttributeNs)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retchar = (char *)xmlTextReaderGetAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
        }
        if (retchar) {
-               RETVAL_STRING(retchar, 1);
+               RETVAL_STRING(retchar);
                xmlFree(retchar);
        }
 }
@@ -638,7 +624,7 @@ PHP_METHOD(xmlreader, getParserProperty)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = xmlTextReaderGetParserProp(intern->ptr,property);
        }
@@ -689,7 +675,7 @@ PHP_METHOD(xmlreader, moveToAttribute)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = xmlTextReaderMoveToAttribute(intern->ptr, (xmlChar *)name);
                if (retval == 1) {
@@ -717,7 +703,7 @@ PHP_METHOD(xmlreader, moveToAttributeNo)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = xmlTextReaderMoveToAttributeNo(intern->ptr, attr_pos);
                if (retval == 1) {
@@ -750,7 +736,7 @@ PHP_METHOD(xmlreader, moveToAttributeNs)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = xmlTextReaderMoveToAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
                if (retval == 1) {
@@ -795,7 +781,7 @@ PHP_METHOD(xmlreader, read)
        xmlreader_object *intern;
 
        id = getThis();
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern != NULL && intern->ptr != NULL) {
                retval = xmlTextReaderRead(intern->ptr);
                if (retval == -1) {
@@ -824,7 +810,7 @@ PHP_METHOD(xmlreader, next)
        }
 
        id = getThis();
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern != NULL && intern->ptr != NULL) {
 #if LIBXML_VERSION <= 20617
                /* Bug in libxml prevents a next in certain cases when positioned on end of element */
@@ -873,7 +859,7 @@ PHP_METHOD(xmlreader, open)
                if (! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
                        id = NULL;
                } else {
-                       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+                       intern = Z_XMLREADER_P(id);
                        xmlreader_free_resources(intern);
                }
        }
@@ -896,7 +882,7 @@ PHP_METHOD(xmlreader, open)
 
        if (id == NULL) {
                object_init_ex(return_value, xmlreader_class_entry);
-               intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
+               intern = Z_XMLREADER_P(return_value);
                intern->ptr = reader;
                return;
        }
@@ -961,7 +947,7 @@ PHP_METHOD(xmlreader, setSchema)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = xmlTextReaderSchemaValidate(intern->ptr, source);
 
@@ -999,7 +985,7 @@ PHP_METHOD(xmlreader, setParserProperty)
 
        id = getThis();
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
        if (intern && intern->ptr) {
                retval = xmlTextReaderSetParserProp(intern->ptr,property, value);
        }
@@ -1057,7 +1043,7 @@ PHP_METHOD(xmlreader, XML)
                id = NULL;
        }
        if (id != NULL) {
-               intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+               intern = Z_XMLREADER_P(id);
                xmlreader_free_resources(intern);
        }
 
@@ -1092,7 +1078,7 @@ PHP_METHOD(xmlreader, XML)
                        if (ret == 0) {
                                if (id == NULL) {
                                        object_init_ex(return_value, xmlreader_class_entry);
-                                       intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
+                                       intern = Z_XMLREADER_P(return_value);
                                } else {
                                        RETVAL_TRUE;
                                }
@@ -1141,7 +1127,7 @@ PHP_METHOD(xmlreader, expand)
                docp = node->doc;
        }
 
-       intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
+       intern = Z_XMLREADER_P(id);
 
        if (intern && intern->ptr) {
                node = xmlTextReaderExpand(intern->ptr);
@@ -1309,6 +1295,9 @@ PHP_MINIT_FUNCTION(xmlreader)
        zend_class_entry ce;
 
        memcpy(&xmlreader_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+       xmlreader_object_handlers.offset = XtOffsetOf(xmlreader_object, std);
+       xmlreader_object_handlers.dtor_obj = zend_objects_destroy_object;
+       xmlreader_object_handlers.free_obj = xmlreader_objects_free_storage;
        xmlreader_object_handlers.read_property = xmlreader_read_property;
        xmlreader_object_handlers.write_property = xmlreader_write_property;
        xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
@@ -1322,10 +1311,10 @@ PHP_MINIT_FUNCTION(xmlreader)
        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG 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, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_FALSE TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_FALSE TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_FALSE TSRMLS_CC);
+       xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_FALSE 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);
index f559bd18d4848ecec11ed6fe5ac299314f91d11a..63653213fe3ef8f5d0856ee841d6f4bed79682a6 100644 (file)
@@ -32,15 +32,20 @@ extern zend_module_entry xmlreader_module_entry;
 #include <libxml/xmlreader.h>
 
 typedef struct _xmlreader_object {
-       zend_object  std;
        xmlTextReaderPtr ptr;
        /* strings must be set in input buffer as copy is required */
        xmlParserInputBufferPtr input;
        void *schema;
        HashTable *prop_handler;
-       zend_object_handle handle;
+       zend_object  std;
 } xmlreader_object;
 
+static inline xmlreader_object *php_xmlreader_fetch_object(zend_object *obj) {
+       return (xmlreader_object *)((char*)(obj) - XtOffsetOf(xmlreader_object, std));
+}
+
+#define Z_XMLREADER_P(zv) php_xmlreader_fetch_object(Z_OBJ_P((zv)))
+
 PHP_MINIT_FUNCTION(xmlreader);
 PHP_MSHUTDOWN_FUNCTION(xmlreader);
 PHP_MINFO_FUNCTION(xmlreader);