helly           Sun Oct 26 08:11:57 2003 EDT

  Modified files:              
    /php-src/ext/simplexml      simplexml.c 
  Log:
  Add iterator to make foreach work
  
Index: php-src/ext/simplexml/simplexml.c
diff -u php-src/ext/simplexml/simplexml.c:1.71 php-src/ext/simplexml/simplexml.c:1.72
--- php-src/ext/simplexml/simplexml.c:1.71      Sat Oct 25 21:17:50 2003
+++ php-src/ext/simplexml/simplexml.c   Sun Oct 26 08:11:56 2003
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: simplexml.c,v 1.71 2003/10/26 01:17:50 helly Exp $ */
+/* $Id: simplexml.c,v 1.72 2003/10/26 13:11:56 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -583,6 +583,9 @@
                        parser = xmlSchemaNewMemParserCtxt(Z_STRVAL_P(source), 
Z_STRLEN_P(source));
                        sptr = xmlSchemaParse(parser);
                        break;
+               default:
+                       parser = NULL;
+                       sptr = NULL;
        }
 
        if (sptr == NULL) {
@@ -739,9 +742,11 @@
 {
        if (contents) {
                ZVAL_STRINGL(object, contents, strlen(contents), 1);
-               object->refcount = 1;
-               object->is_ref = 0;
+       } else {
+               ZVAL_NULL(object);
        }
+       object->refcount = 1;
+       object->is_ref = 0;
 
        switch (type) {
                case IS_STRING:
@@ -1022,6 +1027,114 @@
 }
 /* }}} */
 
+typedef struct {
+       zend_object_iterator  intern;
+       php_sxe_object        *sxe;
+       xmlNodePtr            node;
+       char                  *name;
+       int                   namelen;
+       zval                  *data;
+} php_sxe_iterator;
+
+static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
+static int php_sxe_iterator_has_more(zend_object_iterator *iter TSRMLS_DC);
+static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data 
TSRMLS_DC);
+static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, 
uint *str_key_len, ulong *int_key TSRMLS_DC);
+static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC);
+
+zend_object_iterator_funcs php_sxe_iterator_funcs = {
+       php_sxe_iterator_dtor,
+       php_sxe_iterator_has_more,
+       php_sxe_iterator_current_data,
+       php_sxe_iterator_current_key,
+       php_sxe_iterator_move_forward,
+       NULL
+};
+
+static void php_sxe_iterator_current(php_sxe_iterator *iterator TSRMLS_DC)
+{
+       while (iterator->node) {
+               SKIP_TEXT(iterator->node);
+       
+               _get_base_node_value(iterator->sxe, iterator->node, &iterator->data 
TSRMLS_CC);
+               
+               iterator->node->name = (char *) iterator->node->name;
+               if (!iterator->node->name) {
+                       iterator->name = "CDATA";
+                       iterator->namelen = sizeof("CDATA");
+               } else {
+                       iterator->namelen = xmlStrlen(iterator->node->name)+1;
+                       iterator->name = iterator->node->name;
+               }
+               break;
+next_iter:
+               iterator->node = iterator->node->next;
+       }
+}
+
+zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object 
TSRMLS_DC)
+{
+       php_sxe_iterator *iterator = emalloc(sizeof(php_sxe_iterator));
+
+       object->refcount++;
+       iterator->intern.data = (void*)object;
+       iterator->intern.funcs = &php_sxe_iterator_funcs;
+       iterator->sxe = php_sxe_fetch_object(object TSRMLS_CC);
+       GET_NODE(iterator->sxe, iterator->node);
+       iterator->node = iterator->node->children;
+       iterator->data = NULL;
+       php_sxe_iterator_current(iterator TSRMLS_CC);
+       
+       return (zend_object_iterator*)iterator;
+}
+
+static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
+{
+       php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
+
+       zval_ptr_dtor((zval**)&iterator->intern.data);
+       
+       if (iterator->data) {
+               zval_ptr_dtor(&iterator->data);
+       }
+       efree(iterator);
+}
+       
+static int php_sxe_iterator_has_more(zend_object_iterator *iter TSRMLS_DC)
+{
+       php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
+
+       return iterator->node ? SUCCESS : FAILURE;
+}
+
+static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data 
TSRMLS_DC)
+{
+       php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
+       
+       *data = &iterator->data;
+}
+
+static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, 
uint *str_key_len, ulong *int_key TSRMLS_DC)
+{
+       php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
+       
+       *str_key = estrndup(iterator->name, iterator->namelen-1);
+       *str_key_len = iterator->namelen;
+       return HASH_KEY_IS_STRING;
+}
+
+static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
+{
+       php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
+       
+       if (iterator->data) {
+               zval_ptr_dtor(&iterator->data);
+               iterator->data = NULL;
+       }
+       iterator->node = iterator->node->next;
+       php_sxe_iterator_current(iterator TSRMLS_CC);
+}
+
 function_entry simplexml_functions[] = {
        PHP_FE(simplexml_load_file, NULL)
        PHP_FE(simplexml_load_string, NULL)
@@ -1054,6 +1167,7 @@
        INIT_CLASS_ENTRY(sxe, "simplexml_element", NULL);
        sxe.create_object = sxe_object_new;
        sxe_class_entry = zend_register_internal_class(&sxe TSRMLS_CC);
+       sxe_class_entry->get_iterator = php_sxe_get_iterator;
 
        php_libxml_initialize();
 
@@ -1093,7 +1207,7 @@
 {
        php_info_print_table_start();
        php_info_print_table_header(2, "Simplexml support", "enabled");
-       php_info_print_table_row(2, "Revision", "$Revision: 1.71 $");
+       php_info_print_table_row(2, "Revision", "$Revision: 1.72 $");
        php_info_print_table_row(2, "Schema support", 
 #ifdef LIBXML_SCHEMAS_ENABLED
                "enabled");

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

Reply via email to