sxe.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Marcus Boerger <helly@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #ifdef HAVE_CONFIG_H
  20. # include "config.h"
  21. #endif
  22. #include "php.h"
  23. #include "php_ini.h"
  24. #include "ext/standard/info.h"
  25. #include "zend_interfaces.h"
  26. #include "ext/spl/php_spl.h"
  27. #include "ext/spl/spl_iterators.h"
  28. #include "sxe.h"
  29. zend_class_entry *ce_SimpleXMLIterator = NULL;
  30. zend_class_entry *ce_SimpleXMLElement;
  31. #include "php_simplexml_exports.h"
  32. /* {{{ proto void SimpleXMLIterator::rewind()
  33. Rewind to first element */
  34. PHP_METHOD(ce_SimpleXMLIterator, rewind)
  35. {
  36. php_sxe_iterator iter;
  37. if (zend_parse_parameters_none() == FAILURE) {
  38. return;
  39. }
  40. iter.sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  41. ce_SimpleXMLElement->iterator_funcs.funcs->rewind((zend_object_iterator*)&iter TSRMLS_CC);
  42. }
  43. /* }}} */
  44. /* {{{ proto bool SimpleXMLIterator::valid()
  45. Check whether iteration is valid */
  46. PHP_METHOD(ce_SimpleXMLIterator, valid)
  47. {
  48. php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  49. if (zend_parse_parameters_none() == FAILURE) {
  50. return;
  51. }
  52. RETURN_BOOL(sxe->iter.data);
  53. }
  54. /* }}} */
  55. /* {{{ proto SimpleXMLIterator SimpleXMLIterator::current()
  56. Get current element */
  57. PHP_METHOD(ce_SimpleXMLIterator, current)
  58. {
  59. php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  60. if (zend_parse_parameters_none() == FAILURE) {
  61. return;
  62. }
  63. if (!sxe->iter.data) {
  64. return; /* return NULL */
  65. }
  66. RETURN_ZVAL(sxe->iter.data, 1, 0);
  67. }
  68. /* }}} */
  69. /* {{{ proto string SimpleXMLIterator::key()
  70. Get name of current child element */
  71. PHP_METHOD(ce_SimpleXMLIterator, key)
  72. {
  73. xmlNodePtr curnode;
  74. php_sxe_object *intern;
  75. php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  76. if (zend_parse_parameters_none() == FAILURE) {
  77. return;
  78. }
  79. if (!sxe->iter.data) {
  80. RETURN_FALSE;
  81. }
  82. intern = (php_sxe_object *)zend_object_store_get_object(sxe->iter.data TSRMLS_CC);
  83. if (intern != NULL && intern->node != NULL) {
  84. curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
  85. RETURN_STRINGL((char*)curnode->name, xmlStrlen(curnode->name), 1);
  86. }
  87. RETURN_FALSE;
  88. }
  89. /* }}} */
  90. /* {{{ proto void SimpleXMLIterator::next()
  91. Move to next element */
  92. PHP_METHOD(ce_SimpleXMLIterator, next)
  93. {
  94. php_sxe_iterator iter;
  95. if (zend_parse_parameters_none() == FAILURE) {
  96. return;
  97. }
  98. iter.sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  99. ce_SimpleXMLElement->iterator_funcs.funcs->move_forward((zend_object_iterator*)&iter TSRMLS_CC);
  100. }
  101. /* }}} */
  102. /* {{{ proto bool SimpleXMLIterator::hasChildren()
  103. Check whether element has children (elements) */
  104. PHP_METHOD(ce_SimpleXMLIterator, hasChildren)
  105. {
  106. php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  107. php_sxe_object *child;
  108. xmlNodePtr node;
  109. if (zend_parse_parameters_none() == FAILURE) {
  110. return;
  111. }
  112. if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) {
  113. RETURN_FALSE;
  114. }
  115. child = php_sxe_fetch_object(sxe->iter.data TSRMLS_CC);
  116. GET_NODE(child, node);
  117. if (node) {
  118. node = node->children;
  119. }
  120. while (node && node->type != XML_ELEMENT_NODE) {
  121. node = node->next;
  122. }
  123. RETURN_BOOL(node ? 1 : 0);
  124. }
  125. /* }}} */
  126. /* {{{ proto SimpleXMLIterator SimpleXMLIterator::getChildren()
  127. Get child element iterator */
  128. PHP_METHOD(ce_SimpleXMLIterator, getChildren)
  129. {
  130. php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
  131. if (zend_parse_parameters_none() == FAILURE) {
  132. return;
  133. }
  134. if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) {
  135. return; /* return NULL */
  136. }
  137. RETURN_ZVAL(sxe->iter.data, 1, 0);
  138. }
  139. /* {{{ arginfo */
  140. ZEND_BEGIN_ARG_INFO(arginfo_simplexmliterator__void, 0)
  141. ZEND_END_ARG_INFO()
  142. /* }}} */
  143. static const zend_function_entry funcs_SimpleXMLIterator[] = {
  144. PHP_ME(ce_SimpleXMLIterator, rewind, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  145. PHP_ME(ce_SimpleXMLIterator, valid, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  146. PHP_ME(ce_SimpleXMLIterator, current, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  147. PHP_ME(ce_SimpleXMLIterator, key, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  148. PHP_ME(ce_SimpleXMLIterator, next, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  149. PHP_ME(ce_SimpleXMLIterator, hasChildren, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  150. PHP_ME(ce_SimpleXMLIterator, getChildren, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
  151. {NULL, NULL, NULL}
  152. };
  153. /* }}} */
  154. PHP_MINIT_FUNCTION(sxe) /* {{{ */
  155. {
  156. zend_class_entry **pce;
  157. zend_class_entry sxi;
  158. if (zend_hash_find(CG(class_table), "simplexmlelement", sizeof("SimpleXMLElement"), (void **) &pce) == FAILURE) {
  159. ce_SimpleXMLElement = NULL;
  160. ce_SimpleXMLIterator = NULL;
  161. return SUCCESS; /* SimpleXML must be initialized before */
  162. }
  163. ce_SimpleXMLElement = *pce;
  164. INIT_CLASS_ENTRY_EX(sxi, "SimpleXMLIterator", strlen("SimpleXMLIterator"), funcs_SimpleXMLIterator);
  165. ce_SimpleXMLIterator = zend_register_internal_class_ex(&sxi, ce_SimpleXMLElement, NULL TSRMLS_CC);
  166. ce_SimpleXMLIterator->create_object = ce_SimpleXMLElement->create_object;
  167. zend_class_implements(ce_SimpleXMLIterator TSRMLS_CC, 1, spl_ce_RecursiveIterator);
  168. zend_class_implements(ce_SimpleXMLIterator TSRMLS_CC, 1, spl_ce_Countable);
  169. return SUCCESS;
  170. }
  171. /* }}} */
  172. /*
  173. * Local variables:
  174. * tab-width: 4
  175. * c-basic-offset: 4
  176. * End:
  177. * vim600: fdm=marker
  178. * vim: noet sw=4 ts=4
  179. */