123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733 |
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Sterling Hughes <sterling@php.net> |
- | Marcus Boerger <helly@php.net> |
- | Rob Richards <rrichards@php.net> |
- +----------------------------------------------------------------------+
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "php.h"
- #if defined(HAVE_LIBXML) && defined(HAVE_SIMPLEXML)
- #include "php_ini.h"
- #include "ext/standard/info.h"
- #include "ext/standard/php_string.h"
- #include "php_simplexml.h"
- #include "php_simplexml_exports.h"
- #include "simplexml_arginfo.h"
- #include "zend_exceptions.h"
- #include "zend_interfaces.h"
- #include "ext/spl/spl_iterators.h"
- zend_class_entry *sxe_class_entry = NULL;
- PHP_SXE_API zend_class_entry *ce_SimpleXMLIterator;
- PHP_SXE_API zend_class_entry *ce_SimpleXMLElement;
- PHP_SXE_API zend_class_entry *sxe_get_element_class_entry(void) /* {{{ */
- {
- return sxe_class_entry;
- }
- /* }}} */
- static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, zend_function *fptr_count);
- static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data);
- static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data);
- static void php_sxe_iterator_dtor(zend_object_iterator *iter);
- static int php_sxe_iterator_valid(zend_object_iterator *iter);
- static zval *php_sxe_iterator_current_data(zend_object_iterator *iter);
- static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key);
- static void php_sxe_iterator_move_forward(zend_object_iterator *iter);
- static void php_sxe_iterator_rewind(zend_object_iterator *iter);
- static int sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int type);
- /* {{{ _node_as_zval() */
- static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE_ITER itertype, char *name, const xmlChar *nsprefix, int isprefix)
- {
- php_sxe_object *subnode;
- subnode = php_sxe_object_new(sxe->zo.ce, sxe->fptr_count);
- subnode->document = sxe->document;
- subnode->document->refcount++;
- subnode->iter.type = itertype;
- if (name) {
- subnode->iter.name = (xmlChar*)estrdup(name);
- }
- if (nsprefix && *nsprefix) {
- subnode->iter.nsprefix = (xmlChar*)estrdup((char*)nsprefix);
- subnode->iter.isprefix = isprefix;
- }
- php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL);
- ZVAL_OBJ(value, &subnode->zo);
- }
- /* }}} */
- static xmlNodePtr php_sxe_get_first_node(php_sxe_object *sxe, xmlNodePtr node) /* {{{ */
- {
- php_sxe_object *intern;
- xmlNodePtr retnode = NULL;
- if (sxe && sxe->iter.type != SXE_ITER_NONE) {
- php_sxe_reset_iterator(sxe, 1);
- if (!Z_ISUNDEF(sxe->iter.data)) {
- intern = Z_SXEOBJ_P(&sxe->iter.data);
- GET_NODE(intern, retnode)
- }
- return retnode;
- } else {
- return node;
- }
- }
- /* }}} */
- static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name, int prefix) /* {{{ */
- {
- if (name == NULL && (node->ns == NULL || node->ns->prefix == NULL)) {
- return 1;
- }
- if (node->ns && !xmlStrcmp(prefix ? node->ns->prefix : node->ns->href, name)) {
- return 1;
- }
- return 0;
- }
- /* }}} */
- static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, zend_long offset, xmlNodePtr node, zend_long *cnt) /* {{{ */
- {
- zend_long nodendx = 0;
- if (sxe->iter.type == SXE_ITER_NONE) {
- if (offset == 0) {
- if (cnt) {
- *cnt = 0;
- }
- return node;
- } else {
- return NULL;
- }
- }
- while (node && nodendx <= offset) {
- SKIP_TEXT(node)
- if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (sxe->iter.type == SXE_ITER_CHILD || (
- sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name))) {
- if (nodendx == offset) {
- break;
- }
- nodendx++;
- }
- }
- next_iter:
- node = node->next;
- }
- if (cnt) {
- *cnt = nodendx;
- }
- return node;
- }
- /* }}} */
- static xmlNodePtr sxe_find_element_by_name(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name) /* {{{ */
- {
- while (node) {
- SKIP_TEXT(node)
- if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (!xmlStrcmp(node->name, name)) {
- return node;
- }
- }
- next_iter:
- node = node->next;
- }
- return NULL;
- } /* }}} */
- static xmlNodePtr sxe_get_element_by_name(php_sxe_object *sxe, xmlNodePtr node, char **name, SXE_ITER *type) /* {{{ */
- {
- int orgtype;
- xmlNodePtr orgnode = node;
- xmlNodePtr retnode = NULL;
- if (sxe->iter.type != SXE_ITER_ATTRLIST)
- {
- orgtype = sxe->iter.type;
- if (sxe->iter.type == SXE_ITER_NONE) {
- sxe->iter.type = SXE_ITER_CHILD;
- }
- node = php_sxe_get_first_node(sxe, node);
- sxe->iter.type = orgtype;
- }
- if (sxe->iter.type == SXE_ITER_ELEMENT) {
- orgnode = sxe_find_element_by_name(sxe, node, sxe->iter.name);
- if (!orgnode) {
- return NULL;
- }
- node = orgnode->children;
- }
- while (node) {
- SKIP_TEXT(node)
- if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (!xmlStrcmp(node->name, (xmlChar *)*name)) {
- if (1||retnode)
- {
- *type = SXE_ITER_ELEMENT;
- return orgnode;
- }
- retnode = node;
- }
- }
- next_iter:
- node = node->next;
- }
- if (retnode)
- {
- *type = SXE_ITER_NONE;
- *name = NULL;
- return retnode;
- }
- return NULL;
- }
- /* }}} */
- /* {{{ sxe_prop_dim_read() */
- static zval *sxe_prop_dim_read(zend_object *object, zval *member, bool elements, bool attribs, int type, zval *rv)
- {
- php_sxe_object *sxe;
- char *name;
- xmlNodePtr node;
- xmlAttrPtr attr = NULL;
- zval tmp_zv;
- int nodendx = 0;
- int test = 0;
- sxe = php_sxe_fetch_object(object);
- if (!member) {
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- /* This happens when the user did: $sxe[]->foo = $value */
- zend_throw_error(NULL, "Cannot create unnamed attribute");
- return &EG(uninitialized_zval);
- }
- goto long_dim;
- } else {
- ZVAL_DEREF(member);
- if (Z_TYPE_P(member) == IS_LONG) {
- if (sxe->iter.type != SXE_ITER_ATTRLIST) {
- long_dim:
- attribs = 0;
- elements = 1;
- }
- name = NULL;
- } else {
- if (Z_TYPE_P(member) != IS_STRING) {
- zend_string *str = zval_try_get_string_func(member);
- if (UNEXPECTED(!str)) {
- return &EG(uninitialized_zval);
- }
- ZVAL_STR(&tmp_zv, str);
- member = &tmp_zv;
- }
- name = Z_STRVAL_P(member);
- }
- }
- GET_NODE(sxe, node);
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- attribs = 1;
- elements = 0;
- node = php_sxe_get_first_node(sxe, node);
- attr = (xmlAttrPtr)node;
- test = sxe->iter.name != NULL;
- } else if (sxe->iter.type != SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- attr = node ? node->properties : NULL;
- test = 0;
- if (!member && node && node->parent &&
- node->parent->type == XML_DOCUMENT_NODE) {
- /* This happens when the user did: $sxe[]->foo = $value */
- zend_throw_error(NULL, "Cannot create unnamed attribute");
- return &EG(uninitialized_zval);
- }
- }
- ZVAL_UNDEF(rv);
- if (node) {
- if (attribs) {
- if (Z_TYPE_P(member) != IS_LONG || sxe->iter.type == SXE_ITER_ATTRLIST) {
- if (Z_TYPE_P(member) == IS_LONG) {
- while (attr && nodendx <= Z_LVAL_P(member)) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (nodendx == Z_LVAL_P(member)) {
- _node_as_zval(sxe, (xmlNodePtr) attr, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix);
- break;
- }
- nodendx++;
- }
- attr = attr->next;
- }
- } else {
- while (attr) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- _node_as_zval(sxe, (xmlNodePtr) attr, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix);
- break;
- }
- attr = attr->next;
- }
- }
- }
- }
- if (elements) {
- if (!sxe->node) {
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL);
- }
- if (!member || Z_TYPE_P(member) == IS_LONG) {
- zend_long cnt = 0;
- xmlNodePtr mynode = node;
- if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- }
- if (sxe->iter.type == SXE_ITER_NONE) {
- if (member && Z_LVAL_P(member) > 0) {
- php_error_docref(NULL, E_WARNING, "Cannot add element %s number " ZEND_LONG_FMT " when only 0 such elements exist", mynode->name, Z_LVAL_P(member));
- }
- } else if (member) {
- node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
- } else {
- node = NULL;
- }
- if (node) {
- _node_as_zval(sxe, node, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix);
- } else if (type == BP_VAR_W || type == BP_VAR_RW) {
- if (member && cnt < Z_LVAL_P(member)) {
- php_error_docref(NULL, E_WARNING, "Cannot add element %s number " ZEND_LONG_FMT " when only " ZEND_LONG_FMT " such elements exist", mynode->name, Z_LVAL_P(member), cnt);
- }
- node = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, NULL);
- _node_as_zval(sxe, node, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix);
- }
- } else {
- /* In BP_VAR_IS mode only return a proper node if it actually exists. */
- if (type != BP_VAR_IS || sxe_find_element_by_name(sxe, node->children, (xmlChar *) name)) {
- _node_as_zval(sxe, node, rv, SXE_ITER_ELEMENT, name, sxe->iter.nsprefix, sxe->iter.isprefix);
- }
- }
- }
- }
- if (member == &tmp_zv) {
- zval_ptr_dtor_str(&tmp_zv);
- }
- if (Z_ISUNDEF_P(rv)) {
- ZVAL_NULL(rv);
- }
- return rv;
- }
- /* }}} */
- /* {{{ sxe_property_read() */
- static zval *sxe_property_read(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
- {
- zval member;
- ZVAL_STR(&member, name);
- return sxe_prop_dim_read(object, &member, 1, 0, type, rv);
- }
- /* }}} */
- /* {{{ sxe_dimension_read() */
- static zval *sxe_dimension_read(zend_object *object, zval *offset, int type, zval *rv)
- {
- return sxe_prop_dim_read(object, offset, 0, 1, type, rv);
- }
- /* }}} */
- /* {{{ change_node_zval() */
- static void change_node_zval(xmlNodePtr node, zend_string *value)
- {
- xmlChar *buffer = xmlEncodeEntitiesReentrant(node->doc, (xmlChar *)ZSTR_VAL(value));
- /* check for NULL buffer in case of memory error in xmlEncodeEntitiesReentrant */
- if (buffer) {
- xmlNodeSetContent(node, buffer);
- xmlFree(buffer);
- }
- }
- /* }}} */
- /* {{{ sxe_property_write() */
- static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, bool elements, bool attribs, xmlNodePtr *pnewnode)
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- xmlNodePtr newnode = NULL;
- xmlNodePtr mynode;
- xmlNodePtr tempnode;
- xmlAttrPtr attr = NULL;
- int counter = 0;
- int is_attr = 0;
- int nodendx = 0;
- int test = 0;
- zend_long cnt = 0;
- zval tmp_zv;
- zend_string *trim_str;
- zend_string *value_str = NULL;
- sxe = php_sxe_fetch_object(object);
- if (!member) {
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- /* This happens when the user did: $sxe[] = $value
- * and could also be E_PARSE, but we use this only during parsing
- * and this is during runtime.
- */
- zend_throw_error(NULL, "Cannot append to an attribute list");
- return &EG(error_zval);
- }
- goto long_dim;
- } else {
- ZVAL_DEREF(member);
- if (Z_TYPE_P(member) == IS_LONG) {
- if (sxe->iter.type != SXE_ITER_ATTRLIST) {
- long_dim:
- attribs = 0;
- elements = 1;
- }
- } else {
- if (Z_TYPE_P(member) != IS_STRING) {
- trim_str = zval_try_get_string_func(member);
- if (UNEXPECTED(!trim_str)) {
- return &EG(error_zval);
- }
- ZVAL_STR(&tmp_zv, php_trim(trim_str, NULL, 0, 3));
- zend_string_release_ex(trim_str, 0);
- member = &tmp_zv;
- }
- if (!Z_STRLEN_P(member)) {
- zend_value_error("Cannot create %s with an empty name", attribs ? "attribute" : "element");
- if (member == &tmp_zv) {
- zval_ptr_dtor_str(&tmp_zv);
- }
- return &EG(error_zval);
- }
- }
- }
- GET_NODE(sxe, node);
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- attribs = 1;
- elements = 0;
- node = php_sxe_get_first_node(sxe, node);
- attr = (xmlAttrPtr)node;
- test = sxe->iter.name != NULL;
- } else if (sxe->iter.type != SXE_ITER_CHILD) {
- mynode = node;
- node = php_sxe_get_first_node(sxe, node);
- attr = node ? node->properties : NULL;
- test = 0;
- if (!member && node && node->parent &&
- node->parent->type == XML_DOCUMENT_NODE) {
- /* This happens when the user did: $sxe[] = $value
- * and could also be E_PARSE, but we use this only during parsing
- * and this is during runtime.
- */
- zend_value_error("Cannot append to an attribute list");
- return &EG(error_zval);
- }
- if (attribs && !node && sxe->iter.type == SXE_ITER_ELEMENT) {
- node = xmlNewChild(mynode, mynode->ns, sxe->iter.name, NULL);
- attr = node->properties;
- }
- }
- mynode = node;
- if (value) {
- switch (Z_TYPE_P(value)) {
- case IS_LONG:
- case IS_FALSE:
- case IS_TRUE:
- case IS_DOUBLE:
- case IS_NULL:
- case IS_STRING:
- value_str = zval_get_string(value);
- break;
- case IS_OBJECT:
- if (Z_OBJCE_P(value) == sxe_class_entry) {
- zval zval_copy;
- if (sxe_object_cast_ex(Z_OBJ_P(value), &zval_copy, IS_STRING) == FAILURE) {
- zend_throw_error(NULL, "Unable to cast node to string");
- return &EG(error_zval);
- }
- value_str = Z_STR(zval_copy);
- break;
- }
- ZEND_FALLTHROUGH;
- default:
- if (member == &tmp_zv) {
- zval_ptr_dtor_str(&tmp_zv);
- }
- zend_type_error("It's not possible to assign a complex type to %s, %s given", attribs ? "attributes" : "properties", zend_zval_type_name(value));
- return &EG(error_zval);
- }
- }
- if (node) {
- if (attribs) {
- if (Z_TYPE_P(member) == IS_LONG) {
- while (attr && nodendx <= Z_LVAL_P(member)) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (nodendx == Z_LVAL_P(member)) {
- is_attr = 1;
- ++counter;
- break;
- }
- nodendx++;
- }
- attr = attr->next;
- }
- } else {
- while (attr) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- is_attr = 1;
- ++counter;
- break;
- }
- attr = attr->next;
- }
- }
- }
- if (elements) {
- if (!member || Z_TYPE_P(member) == IS_LONG) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- zend_throw_error(NULL, "Cannot create duplicate attribute");
- if (value_str) {
- zend_string_release(value_str);
- }
- return &EG(error_zval);
- }
- if (sxe->iter.type == SXE_ITER_NONE) {
- newnode = node;
- ++counter;
- if (member && Z_LVAL_P(member) > 0) {
- php_error_docref(NULL, E_WARNING, "Cannot add element %s number " ZEND_LONG_FMT " when only 0 such elements exist", mynode->name, Z_LVAL_P(member));
- value = &EG(error_zval);
- }
- } else if (member) {
- newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
- if (newnode) {
- ++counter;
- }
- }
- } else {
- node = node->children;
- while (node) {
- SKIP_TEXT(node);
- if (!xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- newnode = node;
- ++counter;
- }
- next_iter:
- node = node->next;
- }
- }
- }
- if (counter == 1) {
- if (is_attr) {
- newnode = (xmlNodePtr) attr;
- }
- if (value_str) {
- while ((tempnode = (xmlNodePtr) newnode->children)) {
- xmlUnlinkNode(tempnode);
- php_libxml_node_free_resource((xmlNodePtr) tempnode);
- }
- change_node_zval(newnode, value_str);
- }
- } else if (counter > 1) {
- php_error_docref(NULL, E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)");
- value = &EG(error_zval);
- } else if (elements) {
- if (!node) {
- if (!member || Z_TYPE_P(member) == IS_LONG) {
- newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value_str ? (xmlChar *)ZSTR_VAL(value_str) : NULL);
- } else {
- newnode = xmlNewTextChild(mynode, mynode->ns, (xmlChar *)Z_STRVAL_P(member), value_str ? (xmlChar *)ZSTR_VAL(value_str) : NULL);
- }
- } else if (!member || Z_TYPE_P(member) == IS_LONG) {
- if (member && cnt < Z_LVAL_P(member)) {
- php_error_docref(NULL, E_WARNING, "Cannot add element %s number " ZEND_LONG_FMT " when only " ZEND_LONG_FMT " such elements exist", mynode->name, Z_LVAL_P(member), cnt);
- }
- newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value_str ? (xmlChar *)ZSTR_VAL(value_str) : NULL);
- }
- } else if (attribs) {
- if (Z_TYPE_P(member) == IS_LONG) {
- php_error_docref(NULL, E_WARNING, "Cannot change attribute number " ZEND_LONG_FMT " when only %d attributes exist", Z_LVAL_P(member), nodendx);
- } else {
- newnode = (xmlNodePtr)xmlNewProp(node, (xmlChar *)Z_STRVAL_P(member), value_str ? (xmlChar *)ZSTR_VAL(value_str) : NULL);
- }
- }
- }
- if (member == &tmp_zv) {
- zval_ptr_dtor_str(&tmp_zv);
- }
- if (pnewnode) {
- *pnewnode = newnode;
- }
- if (value_str) {
- zend_string_release(value_str);
- }
- return value;
- }
- /* }}} */
- /* {{{ sxe_property_write() */
- static zval *sxe_property_write(zend_object *object, zend_string *name, zval *value, void **cache_slot)
- {
- zval member;
- ZVAL_STR(&member, name);
- zval *retval = sxe_prop_dim_write(object, &member, value, 1, 0, NULL);
- return retval == &EG(error_zval) ? &EG(uninitialized_zval) : retval;
- }
- /* }}} */
- /* {{{ sxe_dimension_write() */
- static void sxe_dimension_write(zend_object *object, zval *offset, zval *value)
- {
- sxe_prop_dim_write(object, offset, value, 0, 1, NULL);
- }
- /* }}} */
- static zval *sxe_property_get_adr(zend_object *object, zend_string *zname, int fetch_type, void **cache_slot) /* {{{ */
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- zval ret;
- char *name;
- SXE_ITER type;
- zval member;
- sxe = php_sxe_fetch_object(object);
- GET_NODE(sxe, node);
- name = ZSTR_VAL(zname);
- node = sxe_get_element_by_name(sxe, node, &name, &type);
- if (node) {
- return NULL;
- }
- ZVAL_STR(&member, zname);
- if (sxe_prop_dim_write(object, &member, NULL, 1, 0, &node) == &EG(error_zval)) {
- return &EG(error_zval);
- }
- type = SXE_ITER_NONE;
- name = NULL;
- _node_as_zval(sxe, node, &ret, type, name, sxe->iter.nsprefix, sxe->iter.isprefix);
- if (!Z_ISUNDEF(sxe->tmp)) {
- zval_ptr_dtor(&sxe->tmp);
- }
- ZVAL_COPY_VALUE(&sxe->tmp, &ret);
- return &sxe->tmp;
- }
- /* }}} */
- /* {{{ sxe_prop_dim_exists() */
- static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empty, bool elements, bool attribs)
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- xmlAttrPtr attr = NULL;
- int exists = 0;
- int test = 0;
- zval tmp_zv;
- if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) {
- zend_string *str = zval_try_get_string_func(member);
- if (UNEXPECTED(!str)) {
- return 0;
- }
- ZVAL_STR(&tmp_zv, str);
- member = &tmp_zv;
- }
- sxe = php_sxe_fetch_object(object);
- GET_NODE(sxe, node);
- if (Z_TYPE_P(member) == IS_LONG) {
- if (sxe->iter.type != SXE_ITER_ATTRLIST) {
- attribs = 0;
- elements = 1;
- if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- }
- }
- }
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- attribs = 1;
- elements = 0;
- node = php_sxe_get_first_node(sxe, node);
- attr = (xmlAttrPtr)node;
- test = sxe->iter.name != NULL;
- } else if (sxe->iter.type != SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- attr = node ? node->properties : NULL;
- test = 0;
- }
- if (node) {
- if (attribs) {
- if (Z_TYPE_P(member) == IS_LONG) {
- int nodendx = 0;
- while (attr && nodendx <= Z_LVAL_P(member)) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (nodendx == Z_LVAL_P(member)) {
- exists = 1;
- break;
- }
- nodendx++;
- }
- attr = attr->next;
- }
- } else {
- while (attr) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- exists = 1;
- break;
- }
- attr = attr->next;
- }
- }
- if (exists && check_empty == 1 &&
- (!attr->children || !attr->children->content || !attr->children->content[0] || !xmlStrcmp(attr->children->content, (const xmlChar *) "0")) ) {
- /* Attribute with no content in it's text node */
- exists = 0;
- }
- }
- if (elements) {
- if (Z_TYPE_P(member) == IS_LONG) {
- if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- }
- node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
- } else {
- node = sxe_find_element_by_name(sxe, node->children, (xmlChar *)Z_STRVAL_P(member));
- }
- if (node) {
- exists = 1;
- if (check_empty == 1 &&
- (!node->children || (node->children->type == XML_TEXT_NODE && !node->children->next &&
- (!node->children->content || !node->children->content[0] || !xmlStrcmp(node->children->content, (const xmlChar *) "0")))) ) {
- exists = 0;
- }
- }
- }
- }
- if (member == &tmp_zv) {
- zval_ptr_dtor_str(&tmp_zv);
- }
- return exists;
- }
- /* }}} */
- /* {{{ sxe_property_exists() */
- static int sxe_property_exists(zend_object *object, zend_string *name, int check_empty, void **cache_slot)
- {
- zval member;
- ZVAL_STR(&member, name);
- return sxe_prop_dim_exists(object, &member, check_empty, 1, 0);
- }
- /* }}} */
- /* {{{ sxe_dimension_exists() */
- static int sxe_dimension_exists(zend_object *object, zval *member, int check_empty)
- {
- return sxe_prop_dim_exists(object, member, check_empty, 0, 1);
- }
- /* }}} */
- /* {{{ sxe_prop_dim_delete() */
- static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements, bool attribs)
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- xmlNodePtr nnext;
- xmlAttrPtr attr = NULL;
- xmlAttrPtr anext;
- zval tmp_zv;
- int test = 0;
- if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) {
- zend_string *str = zval_try_get_string_func(member);
- if (UNEXPECTED(!str)) {
- return;
- }
- ZVAL_STR(&tmp_zv, str);
- member = &tmp_zv;
- }
- sxe = php_sxe_fetch_object(object);
- GET_NODE(sxe, node);
- if (Z_TYPE_P(member) == IS_LONG) {
- if (sxe->iter.type != SXE_ITER_ATTRLIST) {
- attribs = 0;
- elements = 1;
- if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- }
- }
- }
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- attribs = 1;
- elements = 0;
- node = php_sxe_get_first_node(sxe, node);
- attr = (xmlAttrPtr)node;
- test = sxe->iter.name != NULL;
- } else if (sxe->iter.type != SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- attr = node ? node->properties : NULL;
- test = 0;
- }
- if (node) {
- if (attribs) {
- if (Z_TYPE_P(member) == IS_LONG) {
- int nodendx = 0;
- while (attr && nodendx <= Z_LVAL_P(member)) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- if (nodendx == Z_LVAL_P(member)) {
- xmlUnlinkNode((xmlNodePtr) attr);
- php_libxml_node_free_resource((xmlNodePtr) attr);
- break;
- }
- nodendx++;
- }
- attr = attr->next;
- }
- } else {
- while (attr) {
- anext = attr->next;
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- xmlUnlinkNode((xmlNodePtr) attr);
- php_libxml_node_free_resource((xmlNodePtr) attr);
- break;
- }
- attr = anext;
- }
- }
- }
- if (elements) {
- if (Z_TYPE_P(member) == IS_LONG) {
- if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node(sxe, node);
- }
- node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
- if (node) {
- xmlUnlinkNode(node);
- php_libxml_node_free_resource(node);
- }
- } else {
- node = node->children;
- while (node) {
- nnext = node->next;
- SKIP_TEXT(node);
- if (!xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- xmlUnlinkNode(node);
- php_libxml_node_free_resource(node);
- }
- next_iter:
- node = nnext;
- }
- }
- }
- }
- if (member == &tmp_zv) {
- zval_ptr_dtor_str(&tmp_zv);
- }
- }
- /* }}} */
- /* {{{ sxe_property_delete() */
- static void sxe_property_delete(zend_object *object, zend_string *name, void **cache_slot)
- {
- zval member;
- ZVAL_STR(&member, name);
- sxe_prop_dim_delete(object, &member, 1, 0);
- }
- /* }}} */
- /* {{{ sxe_dimension_unset() */
- static void sxe_dimension_delete(zend_object *object, zval *offset)
- {
- sxe_prop_dim_delete(object, offset, 0, 1);
- }
- /* }}} */
- static inline zend_string *sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) /* {{{ */
- {
- xmlChar *tmp = xmlNodeListGetString(doc, list, inLine);
- zend_string *res;
- if (tmp) {
- res = zend_string_init((char*)tmp, strlen((char *)tmp), 0);
- xmlFree(tmp);
- } else {
- res = ZSTR_EMPTY_ALLOC();
- }
- return res;
- }
- /* }}} */
- /* {{{ _get_base_node_value() */
- static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval *value, xmlChar *nsprefix, int isprefix)
- {
- php_sxe_object *subnode;
- xmlChar *contents;
- if (node->children && node->children->type == XML_TEXT_NODE && !xmlIsBlankNode(node->children)) {
- contents = xmlNodeListGetString(node->doc, node->children, 1);
- if (contents) {
- ZVAL_STRING(value, (char *)contents);
- xmlFree(contents);
- }
- } else {
- subnode = php_sxe_object_new(sxe_ref->zo.ce, sxe_ref->fptr_count);
- subnode->document = sxe_ref->document;
- subnode->document->refcount++;
- if (nsprefix && *nsprefix) {
- subnode->iter.nsprefix = (xmlChar*)estrdup((char *)nsprefix);
- subnode->iter.isprefix = isprefix;
- }
- php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL);
- ZVAL_OBJ(value, &subnode->zo);
- /*zval_add_ref(value);*/
- }
- }
- /* }}} */
- static void sxe_properties_add(HashTable *rv, char *name, int namelen, zval *value) /* {{{ */
- {
- zend_string *key;
- zval *data_ptr;
- zval newptr;
- key = zend_string_init(name, namelen, 0);
- if ((data_ptr = zend_hash_find(rv, key)) != NULL) {
- if (Z_TYPE_P(data_ptr) == IS_ARRAY) {
- zend_hash_next_index_insert_new(Z_ARRVAL_P(data_ptr), value);
- } else {
- array_init(&newptr);
- zend_hash_next_index_insert_new(Z_ARRVAL(newptr), data_ptr);
- zend_hash_next_index_insert_new(Z_ARRVAL(newptr), value);
- ZVAL_ARR(data_ptr, Z_ARR(newptr));
- }
- } else {
- zend_hash_add_new(rv, key, value);
- }
- zend_string_release_ex(key, 0);
- }
- /* }}} */
- static int sxe_prop_is_empty(zend_object *object) /* {{{ */
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- xmlAttrPtr attr;
- zval iter_data;
- int test;
- int is_empty;
- int use_iter = 0;
- sxe = php_sxe_fetch_object(object);
- GET_NODE(sxe, node);
- if (!node) {
- return 1;
- }
- if (sxe->iter.type == SXE_ITER_ELEMENT) {
- node = php_sxe_get_first_node(sxe, node);
- }
- if (!node || node->type != XML_ENTITY_DECL) {
- attr = node ? (xmlAttrPtr)node->properties : NULL;
- test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST;
- while (attr) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- return 0;
- }
- attr = attr->next;
- }
- }
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- is_empty = 1;
- ZVAL_UNDEF(&iter_data);
- if (node && sxe->iter.type != SXE_ITER_ATTRLIST) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- return 0;
- } else if (sxe->iter.type != SXE_ITER_CHILD) {
- if (sxe->iter.type == SXE_ITER_NONE || !node->children || !node->parent || node->children->next || node->children->children || node->parent->children == node->parent->last) {
- node = node->children;
- } else {
- ZVAL_COPY_VALUE(&iter_data, &sxe->iter.data);
- ZVAL_UNDEF(&sxe->iter.data);
- node = php_sxe_reset_iterator(sxe, 0);
- use_iter = 1;
- }
- }
- while (node) {
- if (node->children != NULL || node->prev != NULL || node->next != NULL) {
- SKIP_TEXT(node);
- } else {
- if (node->type == XML_TEXT_NODE) {
- const xmlChar *cur = node->content;
- if (*cur != 0) {
- is_empty = 0;
- break;
- }
- goto next_iter;
- }
- }
- if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) {
- goto next_iter;
- }
- if (!node->name) {
- goto next_iter;
- }
- is_empty = 0;
- break;
- next_iter:
- if (use_iter) {
- node = php_sxe_iterator_fetch(sxe, node->next, 0);
- } else {
- node = node->next;
- }
- }
- }
- if (use_iter) {
- if (!Z_ISUNDEF(sxe->iter.data)) {
- zval_ptr_dtor(&sxe->iter.data);
- }
- ZVAL_COPY_VALUE(&sxe->iter.data, &iter_data);
- }
- return is_empty;
- }
- /* }}} */
- static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */
- {
- zval value;
- zval zattr;
- HashTable *rv;
- php_sxe_object *sxe;
- char *name;
- xmlNodePtr node;
- xmlAttrPtr attr;
- int namelen;
- int test;
- char use_iter;
- zval iter_data;
- use_iter = 0;
- sxe = php_sxe_fetch_object(object);
- if (is_debug) {
- rv = zend_new_array(0);
- } else if (sxe->properties) {
- zend_hash_clean(sxe->properties);
- rv = sxe->properties;
- } else {
- rv = zend_new_array(0);
- sxe->properties = rv;
- }
- GET_NODE(sxe, node);
- if (!node) {
- return rv;
- }
- if (is_debug || sxe->iter.type != SXE_ITER_CHILD) {
- if (sxe->iter.type == SXE_ITER_ELEMENT) {
- node = php_sxe_get_first_node(sxe, node);
- }
- if (!node || node->type != XML_ENTITY_DECL) {
- attr = node ? (xmlAttrPtr)node->properties : NULL;
- ZVAL_UNDEF(&zattr);
- test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST;
- while (attr) {
- if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
- ZVAL_STR(&value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1));
- namelen = xmlStrlen(attr->name);
- if (Z_ISUNDEF(zattr)) {
- array_init(&zattr);
- sxe_properties_add(rv, "@attributes", sizeof("@attributes") - 1, &zattr);
- }
- add_assoc_zval_ex(&zattr, (char*)attr->name, namelen, &value);
- }
- attr = attr->next;
- }
- }
- }
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (node && sxe->iter.type != SXE_ITER_ATTRLIST) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- ZVAL_STR(&value, sxe_xmlNodeListGetString(node->doc, node->children, 1));
- zend_hash_next_index_insert(rv, &value);
- node = NULL;
- } else if (sxe->iter.type != SXE_ITER_CHILD) {
- if ( sxe->iter.type == SXE_ITER_NONE || !node->children || !node->parent || !node->next || node->children->next || node->children->children || node->parent->children == node->parent->last ) {
- node = node->children;
- } else {
- ZVAL_COPY_VALUE(&iter_data, &sxe->iter.data);
- ZVAL_UNDEF(&sxe->iter.data);
- node = php_sxe_reset_iterator(sxe, 0);
- use_iter = 1;
- }
- }
- while (node) {
- if (node->children != NULL || node->prev != NULL || node->next != NULL || xmlIsBlankNode(node)) {
- SKIP_TEXT(node);
- } else {
- if (node->type == XML_TEXT_NODE) {
- const xmlChar *cur = node->content;
- if (*cur != 0) {
- ZVAL_STR(&value, sxe_xmlNodeListGetString(node->doc, node, 1));
- zend_hash_next_index_insert(rv, &value);
- }
- goto next_iter;
- }
- }
- if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) {
- goto next_iter;
- }
- name = (char *) node->name;
- if (!name) {
- goto next_iter;
- } else {
- namelen = xmlStrlen(node->name);
- }
- _get_base_node_value(sxe, node, &value, sxe->iter.nsprefix, sxe->iter.isprefix);
- if ( use_iter ) {
- zend_hash_next_index_insert(rv, &value);
- } else {
- sxe_properties_add(rv, name, namelen, &value);
- }
- next_iter:
- if (use_iter) {
- node = php_sxe_iterator_fetch(sxe, node->next, 0);
- } else {
- node = node->next;
- }
- }
- }
- if (use_iter) {
- if (!Z_ISUNDEF(sxe->iter.data)) {
- zval_ptr_dtor(&sxe->iter.data);
- }
- ZVAL_COPY_VALUE(&sxe->iter.data, &iter_data);
- }
- return rv;
- }
- /* }}} */
- static HashTable *sxe_get_gc(zend_object *object, zval **table, int *n) /* {{{ */ {
- php_sxe_object *sxe;
- sxe = php_sxe_fetch_object(object);
- *table = NULL;
- *n = 0;
- return sxe->properties;
- }
- /* }}} */
- static HashTable *sxe_get_properties(zend_object *object) /* {{{ */
- {
- return sxe_get_prop_hash(object, 0);
- }
- /* }}} */
- static HashTable * sxe_get_debug_info(zend_object *object, int *is_temp) /* {{{ */
- {
- *is_temp = 1;
- return sxe_get_prop_hash(object, 1);
- }
- /* }}} */
- static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */
- {
- php_sxe_object *sxe1;
- php_sxe_object *sxe2;
- ZEND_COMPARE_OBJECTS_FALLBACK(object1, object2);
- sxe1 = Z_SXEOBJ_P(object1);
- sxe2 = Z_SXEOBJ_P(object2);
- if (sxe1->node != NULL && sxe2->node != NULL) {
- /* Both nodes set: Only support equality comparison between nodes. */
- if (sxe1->node == sxe2->node) {
- return 0;
- }
- return ZEND_UNCOMPARABLE;
- }
- if (sxe1->node == NULL && sxe2->node == NULL) {
- /* Both nodes not set: Only support equality comparison between documents. */
- if (sxe1->document->ptr == sxe2->document->ptr) {
- return 0;
- }
- return ZEND_UNCOMPARABLE;
- }
- /* Only one of the nodes set: Cannot compare. */
- return ZEND_UNCOMPARABLE;
- }
- /* }}} */
- /* {{{ Runs XPath query on the XML data */
- PHP_METHOD(SimpleXMLElement, xpath)
- {
- php_sxe_object *sxe;
- zval value;
- char *query;
- size_t query_len;
- int i;
- int nsnbr = 0;
- xmlNsPtr *ns = NULL;
- xmlXPathObjectPtr retval;
- xmlNodeSetPtr result;
- xmlNodePtr nodeptr;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query, &query_len) == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- return; /* attributes don't have attributes */
- }
- GET_NODE(sxe, nodeptr);
- nodeptr = php_sxe_get_first_node(sxe, nodeptr);
- if (!nodeptr) {
- return;
- }
- if (!sxe->xpath) {
- sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr);
- }
- sxe->xpath->node = nodeptr;
- ns = xmlGetNsList((xmlDocPtr) sxe->document->ptr, nodeptr);
- if (ns != NULL) {
- while (ns[nsnbr] != NULL) {
- nsnbr++;
- }
- }
- sxe->xpath->namespaces = ns;
- sxe->xpath->nsNr = nsnbr;
- retval = xmlXPathEval((xmlChar *)query, sxe->xpath);
- if (ns != NULL) {
- xmlFree(ns);
- sxe->xpath->namespaces = NULL;
- sxe->xpath->nsNr = 0;
- }
- if (!retval) {
- RETURN_FALSE;
- }
- result = retval->nodesetval;
- if (result != NULL) {
- array_init(return_value);
- for (i = 0; i < result->nodeNr; ++i) {
- nodeptr = result->nodeTab[i];
- if (nodeptr->type == XML_TEXT_NODE || nodeptr->type == XML_ELEMENT_NODE || nodeptr->type == XML_ATTRIBUTE_NODE) {
- /**
- * Detect the case where the last selector is text(), simplexml
- * always accesses the text() child by default, therefore we assign
- * to the parent node.
- */
- if (nodeptr->type == XML_TEXT_NODE) {
- _node_as_zval(sxe, nodeptr->parent, &value, SXE_ITER_NONE, NULL, NULL, 0);
- } else if (nodeptr->type == XML_ATTRIBUTE_NODE) {
- _node_as_zval(sxe, nodeptr->parent, &value, SXE_ITER_ATTRLIST, (char*)nodeptr->name, nodeptr->ns ? (xmlChar *)nodeptr->ns->href : NULL, 0);
- } else {
- _node_as_zval(sxe, nodeptr, &value, SXE_ITER_NONE, NULL, NULL, 0);
- }
- add_next_index_zval(return_value, &value);
- }
- }
- } else {
- RETVAL_EMPTY_ARRAY();
- }
- xmlXPathFreeObject(retval);
- }
- /* }}} */
- /* {{{ Creates a prefix/ns context for the next XPath query */
- PHP_METHOD(SimpleXMLElement, registerXPathNamespace)
- {
- php_sxe_object *sxe;
- size_t prefix_len, ns_uri_len;
- char *prefix, *ns_uri;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (!sxe->document) {
- zend_throw_error(NULL, "SimpleXMLElement is not properly initialized");
- RETURN_THROWS();
- }
- if (!sxe->xpath) {
- sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr);
- }
- if (xmlXPathRegisterNs(sxe->xpath, (xmlChar *)prefix, (xmlChar *)ns_uri) != 0) {
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ Return a well-formed XML string based on SimpleXML element */
- PHP_METHOD(SimpleXMLElement, asXML)
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- xmlOutputBufferPtr outbuf;
- xmlChar *strval;
- int strval_len;
- char *filename = NULL;
- size_t filename_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p!", &filename, &filename_len) == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (!node) {
- RETURN_FALSE;
- }
- if (filename) {
- if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
- int bytes;
- bytes = xmlSaveFile(filename, (xmlDocPtr) sxe->document->ptr);
- if (bytes == -1) {
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
- } else {
- outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0);
- if (outbuf == NULL) {
- RETURN_FALSE;
- }
- xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, NULL);
- xmlOutputBufferClose(outbuf);
- RETURN_TRUE;
- }
- }
- if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
- xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, (const char *) ((xmlDocPtr) sxe->document->ptr)->encoding);
- if (!strval) {
- RETVAL_FALSE;
- } else {
- RETVAL_STRINGL((char *)strval, strval_len);
- }
- xmlFree(strval);
- } else {
- char *return_content;
- size_t return_len;
- /* Should we be passing encoding information instead of NULL? */
- outbuf = xmlAllocOutputBuffer(NULL);
- if (outbuf == NULL) {
- RETURN_FALSE;
- }
- xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, (const char *) ((xmlDocPtr) sxe->document->ptr)->encoding);
- xmlOutputBufferFlush(outbuf);
- #ifdef LIBXML2_NEW_BUFFER
- return_content = (char *)xmlOutputBufferGetContent(outbuf);
- return_len = xmlOutputBufferGetSize(outbuf);
- #else
- return_content = (char *)outbuf->buffer->content;
- return_len = outbuf->buffer->use;
- #endif
- if (!return_content) {
- RETVAL_FALSE;
- } else {
- RETVAL_STRINGL(return_content, return_len);
- }
- xmlOutputBufferClose(outbuf);
- }
- }
- /* }}} */
- #define SXE_NS_PREFIX(ns) (ns->prefix ? (char*)ns->prefix : "")
- static inline void sxe_add_namespace_name(zval *return_value, xmlNsPtr ns) /* {{{ */
- {
- char *prefix = SXE_NS_PREFIX(ns);
- zend_string *key = zend_string_init(prefix, strlen(prefix), 0);
- zval zv;
- if (!zend_hash_exists(Z_ARRVAL_P(return_value), key)) {
- ZVAL_STRING(&zv, (char*)ns->href);
- zend_hash_add_new(Z_ARRVAL_P(return_value), key, &zv);
- }
- zend_string_release_ex(key, 0);
- }
- /* }}} */
- static void sxe_add_namespaces(php_sxe_object *sxe, xmlNodePtr node, bool recursive, zval *return_value) /* {{{ */
- {
- xmlAttrPtr attr;
- if (node->ns) {
- sxe_add_namespace_name(return_value, node->ns);
- }
- attr = node->properties;
- while (attr) {
- if (attr->ns) {
- sxe_add_namespace_name(return_value, attr->ns);
- }
- attr = attr->next;
- }
- if (recursive) {
- node = node->children;
- while (node) {
- if (node->type == XML_ELEMENT_NODE) {
- sxe_add_namespaces(sxe, node, recursive, return_value);
- }
- node = node->next;
- }
- }
- } /* }}} */
- /* {{{ Return all namespaces in use */
- PHP_METHOD(SimpleXMLElement, getNamespaces)
- {
- bool recursive = 0;
- php_sxe_object *sxe;
- xmlNodePtr node;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &recursive) == FAILURE) {
- RETURN_THROWS();
- }
- array_init(return_value);
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (node) {
- if (node->type == XML_ELEMENT_NODE) {
- sxe_add_namespaces(sxe, node, recursive, return_value);
- } else if (node->type == XML_ATTRIBUTE_NODE && node->ns) {
- sxe_add_namespace_name(return_value, node->ns);
- }
- }
- }
- /* }}} */
- static void sxe_add_registered_namespaces(php_sxe_object *sxe, xmlNodePtr node, bool recursive, zval *return_value) /* {{{ */
- {
- xmlNsPtr ns;
- if (node->type == XML_ELEMENT_NODE) {
- ns = node->nsDef;
- while (ns != NULL) {
- sxe_add_namespace_name(return_value, ns);
- ns = ns->next;
- }
- if (recursive) {
- node = node->children;
- while (node) {
- sxe_add_registered_namespaces(sxe, node, recursive, return_value);
- node = node->next;
- }
- }
- }
- }
- /* }}} */
- /* {{{ Return all namespaces registered with document */
- PHP_METHOD(SimpleXMLElement, getDocNamespaces)
- {
- bool recursive = 0, from_root = 1;
- php_sxe_object *sxe;
- xmlNodePtr node;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|bb", &recursive, &from_root) == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (from_root) {
- if (!sxe->document) {
- zend_throw_error(NULL, "SimpleXMLElement is not properly initialized");
- RETURN_THROWS();
- }
- node = xmlDocGetRootElement((xmlDocPtr)sxe->document->ptr);
- } else {
- GET_NODE(sxe, node);
- }
- if (node == NULL) {
- RETURN_FALSE;
- }
- array_init(return_value);
- sxe_add_registered_namespaces(sxe, node, recursive, return_value);
- }
- /* }}} */
- /* {{{ Finds children of given node */
- PHP_METHOD(SimpleXMLElement, children)
- {
- php_sxe_object *sxe;
- char *nsprefix = NULL;
- size_t nsprefix_len = 0;
- xmlNodePtr node;
- bool isprefix = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!b", &nsprefix, &nsprefix_len, &isprefix) == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- return; /* attributes don't have attributes */
- }
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (!node) {
- return;
- }
- _node_as_zval(sxe, node, return_value, SXE_ITER_CHILD, NULL, (xmlChar *)nsprefix, isprefix);
- }
- /* }}} */
- /* {{{ Finds children of given node */
- PHP_METHOD(SimpleXMLElement, getName)
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- int namelen;
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (node) {
- namelen = xmlStrlen(node->name);
- RETURN_STRINGL((char*)node->name, namelen);
- } else {
- RETURN_EMPTY_STRING();
- }
- }
- /* }}} */
- /* {{{ Identifies an element's attributes */
- PHP_METHOD(SimpleXMLElement, attributes)
- {
- php_sxe_object *sxe;
- char *nsprefix = NULL;
- size_t nsprefix_len = 0;
- xmlNodePtr node;
- bool isprefix = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!b", &nsprefix, &nsprefix_len, &isprefix) == FAILURE) {
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (!node) {
- return;
- }
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- return; /* attributes don't have attributes */
- }
- _node_as_zval(sxe, node, return_value, SXE_ITER_ATTRLIST, NULL, (xmlChar *)nsprefix, isprefix);
- }
- /* }}} */
- /* {{{ Add Element with optional namespace information */
- PHP_METHOD(SimpleXMLElement, addChild)
- {
- php_sxe_object *sxe;
- char *qname, *value = NULL, *nsuri = NULL;
- size_t qname_len, value_len = 0, nsuri_len = 0;
- xmlNodePtr node, newnode;
- xmlNsPtr nsptr = NULL;
- xmlChar *localname, *prefix = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s!s!",
- &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) {
- RETURN_THROWS();
- }
- if (qname_len == 0) {
- zend_argument_value_error(1, "cannot be empty");
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- GET_NODE(sxe, node);
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- php_error_docref(NULL, E_WARNING, "Cannot add element to attributes");
- return;
- }
- node = php_sxe_get_first_node(sxe, node);
- if (node == NULL) {
- php_error_docref(NULL, E_WARNING, "Cannot add child. Parent is not a permanent member of the XML tree");
- return;
- }
- localname = xmlSplitQName2((xmlChar *)qname, &prefix);
- if (localname == NULL) {
- localname = xmlStrdup((xmlChar *)qname);
- }
- newnode = xmlNewChild(node, NULL, localname, (xmlChar *)value);
- if (nsuri != NULL) {
- if (nsuri_len == 0) {
- newnode->ns = NULL;
- nsptr = xmlNewNs(newnode, (xmlChar *)nsuri, prefix);
- } else {
- nsptr = xmlSearchNsByHref(node->doc, node, (xmlChar *)nsuri);
- if (nsptr == NULL) {
- nsptr = xmlNewNs(newnode, (xmlChar *)nsuri, prefix);
- }
- newnode->ns = nsptr;
- }
- }
- _node_as_zval(sxe, newnode, return_value, SXE_ITER_NONE, (char *)localname, prefix, 0);
- xmlFree(localname);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
- }
- /* }}} */
- /* {{{ Add Attribute with optional namespace information */
- PHP_METHOD(SimpleXMLElement, addAttribute)
- {
- php_sxe_object *sxe;
- char *qname, *value = NULL, *nsuri = NULL;
- size_t qname_len, value_len = 0, nsuri_len = 0;
- xmlNodePtr node;
- xmlAttrPtr attrp = NULL;
- xmlNsPtr nsptr = NULL;
- xmlChar *localname, *prefix = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|s!",
- &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) {
- RETURN_THROWS();
- }
- if (qname_len == 0) {
- zend_argument_value_error(1, "cannot be empty");
- RETURN_THROWS();
- }
- sxe = Z_SXEOBJ_P(ZEND_THIS);
- GET_NODE(sxe, node);
- node = php_sxe_get_first_node(sxe, node);
- if (node && node->type != XML_ELEMENT_NODE) {
- node = node->parent;
- }
- if (node == NULL) {
- php_error_docref(NULL, E_WARNING, "Unable to locate parent Element");
- return;
- }
- localname = xmlSplitQName2((xmlChar *)qname, &prefix);
- if (localname == NULL) {
- if (nsuri_len > 0) {
- if (prefix != NULL) {
- xmlFree(prefix);
- }
- php_error_docref(NULL, E_WARNING, "Attribute requires prefix for namespace");
- return;
- }
- localname = xmlStrdup((xmlChar *)qname);
- }
- attrp = xmlHasNsProp(node, localname, (xmlChar *)nsuri);
- if (attrp != NULL && attrp->type != XML_ATTRIBUTE_DECL) {
- xmlFree(localname);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
- php_error_docref(NULL, E_WARNING, "Attribute already exists");
- return;
- }
- if (nsuri != NULL) {
- nsptr = xmlSearchNsByHref(node->doc, node, (xmlChar *)nsuri);
- if (nsptr == NULL) {
- nsptr = xmlNewNs(node, (xmlChar *)nsuri, prefix);
- }
- }
- attrp = xmlNewNsProp(node, nsptr, localname, (xmlChar *)value);
- xmlFree(localname);
- if (prefix != NULL) {
- xmlFree(prefix);
- }
- }
- /* }}} */
- /* {{{ cast_object() */
- static int cast_object(zval *object, int type, char *contents)
- {
- if (contents) {
- ZVAL_STRINGL(object, contents, strlen(contents));
- } else {
- ZVAL_NULL(object);
- }
- switch (type) {
- case IS_STRING:
- convert_to_string(object);
- break;
- case _IS_BOOL:
- convert_to_boolean(object);
- break;
- case IS_LONG:
- convert_to_long(object);
- break;
- case IS_DOUBLE:
- convert_to_double(object);
- break;
- case _IS_NUMBER:
- convert_scalar_to_number(object);
- break;
- default:
- return FAILURE;
- }
- return SUCCESS;
- }
- /* }}} */
- /* {{{ sxe_object_cast() */
- static int sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int type)
- {
- php_sxe_object *sxe;
- xmlChar *contents = NULL;
- xmlNodePtr node;
- int rv;
- sxe = php_sxe_fetch_object(readobj);
- if (type == _IS_BOOL) {
- node = php_sxe_get_first_node(sxe, NULL);
- if (node) {
- ZVAL_TRUE(writeobj);
- } else {
- ZVAL_BOOL(writeobj, !sxe_prop_is_empty(readobj));
- }
- return SUCCESS;
- }
- if (sxe->iter.type != SXE_ITER_NONE) {
- node = php_sxe_get_first_node(sxe, NULL);
- if (node) {
- contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, node->children, 1);
- }
- } else {
- if (!sxe->node) {
- if (sxe->document) {
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL);
- }
- }
- if (sxe->node && sxe->node->node) {
- if (sxe->node->node->children) {
- contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, sxe->node->node->children, 1);
- }
- }
- }
- rv = cast_object(writeobj, type, (char *)contents);
- if (contents) {
- xmlFree(contents);
- }
- return rv;
- }
- /* }}} */
- /* {{{ Variant of sxe_object_cast_ex that handles overwritten __toString() method */
- static int sxe_object_cast(zend_object *readobj, zval *writeobj, int type)
- {
- if (type == IS_STRING
- && zend_std_cast_object_tostring(readobj, writeobj, IS_STRING) == SUCCESS
- ) {
- return SUCCESS;
- }
- return sxe_object_cast_ex(readobj, writeobj, type);
- }
- /* }}} */
- /* {{{ Returns the string content */
- PHP_METHOD(SimpleXMLElement, __toString)
- {
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- if (sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING) != SUCCESS) {
- zval_ptr_dtor(return_value);
- RETURN_EMPTY_STRING();
- }
- }
- /* }}} */
- static int php_sxe_count_elements_helper(php_sxe_object *sxe, zend_long *count) /* {{{ */
- {
- xmlNodePtr node;
- zval data;
- *count = 0;
- ZVAL_COPY_VALUE(&data, &sxe->iter.data);
- ZVAL_UNDEF(&sxe->iter.data);
- node = php_sxe_reset_iterator(sxe, 0);
- while (node)
- {
- (*count)++;
- node = php_sxe_iterator_fetch(sxe, node->next, 0);
- }
- if (!Z_ISUNDEF(sxe->iter.data)) {
- zval_ptr_dtor(&sxe->iter.data);
- }
- ZVAL_COPY_VALUE(&sxe->iter.data, &data);
- return SUCCESS;
- }
- /* }}} */
- static int sxe_count_elements(zend_object *object, zend_long *count) /* {{{ */
- {
- php_sxe_object *intern;
- intern = php_sxe_fetch_object(object);
- if (intern->fptr_count) {
- zval rv;
- zend_call_method_with_0_params(object, intern->zo.ce, &intern->fptr_count, "count", &rv);
- if (!Z_ISUNDEF(rv)) {
- *count = zval_get_long(&rv);
- zval_ptr_dtor(&rv);
- return SUCCESS;
- }
- return FAILURE;
- }
- return php_sxe_count_elements_helper(intern, count);
- }
- /* }}} */
- /* {{{ Get number of child elements */
- PHP_METHOD(SimpleXMLElement, count)
- {
- zend_long count = 0;
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- php_sxe_count_elements_helper(sxe, &count);
- RETURN_LONG(count);
- }
- /* }}} */
- /* {{{ Rewind to first element */
- PHP_METHOD(SimpleXMLElement, rewind)
- {
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- php_sxe_rewind_iterator(Z_SXEOBJ_P(ZEND_THIS));
- }
- /* }}} */
- /* {{{ Check whether iteration is valid */
- PHP_METHOD(SimpleXMLElement, valid)
- {
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- RETURN_BOOL(!Z_ISUNDEF(sxe->iter.data));
- }
- /* }}} */
- /* {{{ Get current element */
- PHP_METHOD(SimpleXMLElement, current)
- {
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- if (Z_ISUNDEF(sxe->iter.data)) {
- zend_throw_error(NULL, "Iterator not initialized or already consumed");
- RETURN_THROWS();
- }
- RETURN_COPY_DEREF(&sxe->iter.data);
- }
- /* }}} */
- /* {{{ Get name of current child element */
- PHP_METHOD(SimpleXMLElement, key)
- {
- xmlNodePtr curnode;
- php_sxe_object *intern;
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- if (Z_ISUNDEF(sxe->iter.data)) {
- zend_throw_error(NULL, "Iterator not initialized or already consumed");
- RETURN_THROWS();
- }
- intern = Z_SXEOBJ_P(&sxe->iter.data);
- if (intern == NULL || intern->node == NULL) {
- zend_throw_error(NULL, "Iterator not initialized or already consumed");
- RETURN_THROWS();
- }
- curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
- RETURN_STRINGL((char*)curnode->name, xmlStrlen(curnode->name));
- }
- /* }}} */
- /* {{{ Move to next element */
- PHP_METHOD(SimpleXMLElement, next)
- {
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- php_sxe_move_forward_iterator(Z_SXEOBJ_P(ZEND_THIS));
- }
- /* }}} */
- /* {{{ Check whether element has children (elements) */
- PHP_METHOD(SimpleXMLElement, hasChildren)
- {
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- php_sxe_object *child;
- xmlNodePtr node;
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) {
- RETURN_FALSE;
- }
- child = Z_SXEOBJ_P(&sxe->iter.data);
- GET_NODE(child, node);
- if (node) {
- node = node->children;
- }
- while (node && node->type != XML_ELEMENT_NODE) {
- node = node->next;
- }
- RETURN_BOOL(node ? 1 : 0);
- }
- /* }}} */
- /* {{{ Get child element iterator */
- PHP_METHOD(SimpleXMLElement, getChildren)
- {
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- if (zend_parse_parameters_none() == FAILURE) {
- RETURN_THROWS();
- }
- if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) {
- return; /* return NULL */
- }
- RETURN_COPY_DEREF(&sxe->iter.data);
- }
- static zend_object_handlers sxe_object_handlers;
- /* {{{ sxe_object_clone() */
- static zend_object *
- sxe_object_clone(zend_object *object)
- {
- php_sxe_object *sxe = php_sxe_fetch_object(object);
- php_sxe_object *clone;
- xmlNodePtr nodep = NULL;
- xmlDocPtr docp = NULL;
- bool is_root_element = sxe->node && sxe->node->node && sxe->node->node->parent
- && (sxe->node->node->parent->type == XML_DOCUMENT_NODE || sxe->node->node->parent->type == XML_HTML_DOCUMENT_NODE);
- clone = php_sxe_object_new(sxe->zo.ce, sxe->fptr_count);
- if (is_root_element) {
- docp = xmlCopyDoc(sxe->document->ptr, 1);
- php_libxml_increment_doc_ref((php_libxml_node_object *)clone, docp);
- } else {
- clone->document = sxe->document;
- if (clone->document) {
- clone->document->refcount++;
- docp = clone->document->ptr;
- }
- }
- clone->iter.isprefix = sxe->iter.isprefix;
- if (sxe->iter.name != NULL) {
- clone->iter.name = (xmlChar*)estrdup((char*)sxe->iter.name);
- }
- if (sxe->iter.nsprefix != NULL) {
- clone->iter.nsprefix = (xmlChar*)estrdup((char*)sxe->iter.nsprefix);
- }
- clone->iter.type = sxe->iter.type;
- if (sxe->node) {
- if (is_root_element) {
- nodep = xmlDocGetRootElement(docp);
- } else {
- nodep = xmlDocCopyNode(sxe->node->node, docp, 1);
- }
- }
- php_libxml_increment_node_ptr((php_libxml_node_object *)clone, nodep, NULL);
- return &clone->zo;
- }
- /* }}} */
- /* {{{ sxe_object_free_storage() */
- static void sxe_object_free_storage(zend_object *object)
- {
- php_sxe_object *sxe;
- sxe = php_sxe_fetch_object(object);
- zend_object_std_dtor(&sxe->zo);
- if (!Z_ISUNDEF(sxe->iter.data)) {
- zval_ptr_dtor(&sxe->iter.data);
- ZVAL_UNDEF(&sxe->iter.data);
- }
- if (sxe->iter.name) {
- efree(sxe->iter.name);
- sxe->iter.name = NULL;
- }
- if (sxe->iter.nsprefix) {
- efree(sxe->iter.nsprefix);
- sxe->iter.nsprefix = NULL;
- }
- if (!Z_ISUNDEF(sxe->tmp)) {
- zval_ptr_dtor(&sxe->tmp);
- ZVAL_UNDEF(&sxe->tmp);
- }
- php_libxml_node_decrement_resource((php_libxml_node_object *)sxe);
- if (sxe->xpath) {
- xmlXPathFreeContext(sxe->xpath);
- }
- if (sxe->properties) {
- zend_hash_destroy(sxe->properties);
- FREE_HASHTABLE(sxe->properties);
- }
- }
- /* }}} */
- /* {{{ php_sxe_find_fptr_count() */
- static zend_function* php_sxe_find_fptr_count(zend_class_entry *ce)
- {
- zend_function *fptr_count = NULL;
- zend_class_entry *parent = ce;
- int inherited = 0;
- while (parent) {
- if (parent == sxe_class_entry) {
- break;
- }
- parent = parent->parent;
- inherited = 1;
- }
- if (inherited) {
- fptr_count = zend_hash_str_find_ptr(&ce->function_table, "count", sizeof("count") - 1);
- if (fptr_count->common.scope == parent) {
- fptr_count = NULL;
- }
- }
- return fptr_count;
- }
- /* }}} */
- /* {{{ php_sxe_object_new() */
- static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, zend_function *fptr_count)
- {
- php_sxe_object *intern;
- intern = zend_object_alloc(sizeof(php_sxe_object), ce);
- intern->iter.type = SXE_ITER_NONE;
- intern->iter.nsprefix = NULL;
- intern->iter.name = NULL;
- intern->fptr_count = fptr_count;
- zend_object_std_init(&intern->zo, ce);
- object_properties_init(&intern->zo, ce);
- intern->zo.handlers = &sxe_object_handlers;
- return intern;
- }
- /* }}} */
- /* {{{ sxe_object_new() */
- PHP_SXE_API zend_object *
- sxe_object_new(zend_class_entry *ce)
- {
- php_sxe_object *intern;
- intern = php_sxe_object_new(ce, php_sxe_find_fptr_count(ce));
- return &intern->zo;
- }
- /* }}} */
- /* {{{ Load a filename and return a simplexml_element object to allow for processing */
- PHP_FUNCTION(simplexml_load_file)
- {
- php_sxe_object *sxe;
- char *filename;
- size_t filename_len;
- xmlDocPtr docp;
- char *ns = NULL;
- size_t ns_len = 0;
- zend_long options = 0;
- zend_class_entry *ce= sxe_class_entry;
- zend_function *fptr_count;
- bool isprefix = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|C!lsb", &filename, &filename_len, &ce, &options, &ns, &ns_len, &isprefix) == FAILURE) {
- RETURN_THROWS();
- }
- if (ZEND_LONG_EXCEEDS_INT(options)) {
- zend_argument_value_error(3, "is too large");
- RETURN_THROWS();
- }
- docp = xmlReadFile(filename, NULL, (int)options);
- if (!docp) {
- RETURN_FALSE;
- }
- if (!ce) {
- ce = sxe_class_entry;
- fptr_count = NULL;
- } else {
- fptr_count = php_sxe_find_fptr_count(ce);
- }
- sxe = php_sxe_object_new(ce, fptr_count);
- sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
- sxe->iter.isprefix = isprefix;
- php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL);
- RETURN_OBJ(&sxe->zo);
- }
- /* }}} */
- /* {{{ Load a string and return a simplexml_element object to allow for processing */
- PHP_FUNCTION(simplexml_load_string)
- {
- php_sxe_object *sxe;
- char *data;
- size_t data_len;
- xmlDocPtr docp;
- char *ns = NULL;
- size_t ns_len = 0;
- zend_long options = 0;
- zend_class_entry *ce= sxe_class_entry;
- zend_function *fptr_count;
- bool isprefix = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|C!lsb", &data, &data_len, &ce, &options, &ns, &ns_len, &isprefix) == FAILURE) {
- RETURN_THROWS();
- }
- if (ZEND_SIZE_T_INT_OVFL(data_len)) {
- zend_argument_value_error(1, "is too long");
- RETURN_THROWS();
- }
- if (ZEND_SIZE_T_INT_OVFL(ns_len)) {
- zend_argument_value_error(4, "is too long");
- RETURN_THROWS();
- }
- if (ZEND_LONG_EXCEEDS_INT(options)) {
- zend_argument_value_error(3, "is too large");
- RETURN_THROWS();
- }
- docp = xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options);
- if (!docp) {
- RETURN_FALSE;
- }
- if (!ce) {
- ce = sxe_class_entry;
- fptr_count = NULL;
- } else {
- fptr_count = php_sxe_find_fptr_count(ce);
- }
- sxe = php_sxe_object_new(ce, fptr_count);
- sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
- sxe->iter.isprefix = isprefix;
- php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL);
- RETURN_OBJ(&sxe->zo);
- }
- /* }}} */
- /* {{{ SimpleXMLElement constructor */
- PHP_METHOD(SimpleXMLElement, __construct)
- {
- php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS);
- char *data, *ns = NULL;
- size_t data_len, ns_len = 0;
- xmlDocPtr docp;
- zend_long options = 0;
- bool is_url = 0, isprefix = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lbsb", &data, &data_len, &options, &is_url, &ns, &ns_len, &isprefix) == FAILURE) {
- RETURN_THROWS();
- }
- if (ZEND_SIZE_T_INT_OVFL(data_len)) {
- zend_argument_error(zend_ce_exception, 1, "is too long");
- RETURN_THROWS();
- }
- if (ZEND_SIZE_T_INT_OVFL(ns_len)) {
- zend_argument_error(zend_ce_exception, 4, "is too long");
- RETURN_THROWS();
- }
- if (ZEND_LONG_EXCEEDS_INT(options)) {
- zend_argument_error(zend_ce_exception, 2, "is invalid");
- RETURN_THROWS();
- }
- docp = is_url ? xmlReadFile(data, NULL, (int)options) : xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options);
- if (!docp) {
- ((php_libxml_node_object *)sxe)->document = NULL;
- zend_throw_exception(zend_ce_exception, "String could not be parsed as XML", 0);
- RETURN_THROWS();
- }
- sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
- sxe->iter.isprefix = isprefix;
- php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL);
- }
- /* }}} */
- static const zend_object_iterator_funcs php_sxe_iterator_funcs = { /* {{{ */
- php_sxe_iterator_dtor,
- php_sxe_iterator_valid,
- php_sxe_iterator_current_data,
- php_sxe_iterator_current_key,
- php_sxe_iterator_move_forward,
- php_sxe_iterator_rewind,
- NULL,
- NULL, /* get_gc */
- };
- /* }}} */
- static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data) /* {{{ */
- {
- xmlChar *prefix = sxe->iter.nsprefix;
- int isprefix = sxe->iter.isprefix;
- if (sxe->iter.type == SXE_ITER_ATTRLIST) {
- if (sxe->iter.name) {
- while (node) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix, isprefix)) {
- break;
- }
- }
- node = node->next;
- }
- } else {
- while (node) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- if (match_ns(sxe, node, prefix, isprefix)) {
- break;
- }
- }
- node = node->next;
- }
- }
- } else if (sxe->iter.type == SXE_ITER_ELEMENT && sxe->iter.name) {
- while (node) {
- if (node->type == XML_ELEMENT_NODE) {
- if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix, isprefix)) {
- break;
- }
- }
- node = node->next;
- }
- } else {
- while (node) {
- if (node->type == XML_ELEMENT_NODE) {
- if (match_ns(sxe, node, prefix, isprefix)) {
- break;
- }
- }
- node = node->next;
- }
- }
- if (node && use_data) {
- _node_as_zval(sxe, node, &sxe->iter.data, SXE_ITER_NONE, NULL, prefix, isprefix);
- }
- return node;
- }
- /* }}} */
- static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data) /* {{{ */
- {
- xmlNodePtr node;
- if (!Z_ISUNDEF(sxe->iter.data)) {
- zval_ptr_dtor(&sxe->iter.data);
- ZVAL_UNDEF(&sxe->iter.data);
- }
- GET_NODE(sxe, node)
- if (node) {
- switch (sxe->iter.type) {
- case SXE_ITER_ELEMENT:
- case SXE_ITER_CHILD:
- case SXE_ITER_NONE:
- node = node->children;
- break;
- case SXE_ITER_ATTRLIST:
- node = (xmlNodePtr) node->properties;
- }
- return php_sxe_iterator_fetch(sxe, node, use_data);
- }
- return NULL;
- }
- /* }}} */
- zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object, int by_ref) /* {{{ */
- {
- php_sxe_iterator *iterator;
- if (by_ref) {
- zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
- return NULL;
- }
- iterator = emalloc(sizeof(php_sxe_iterator));
- zend_iterator_init(&iterator->intern);
- ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object));
- iterator->intern.funcs = &php_sxe_iterator_funcs;
- iterator->sxe = Z_SXEOBJ_P(object);
- return (zend_object_iterator*)iterator;
- }
- /* }}} */
- static void php_sxe_iterator_dtor(zend_object_iterator *iter) /* {{{ */
- {
- php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- /* cleanup handled in sxe_object_dtor as we don't always have an iterator wrapper */
- if (!Z_ISUNDEF(iterator->intern.data)) {
- zval_ptr_dtor(&iterator->intern.data);
- }
- }
- /* }}} */
- static int php_sxe_iterator_valid(zend_object_iterator *iter) /* {{{ */
- {
- php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- return Z_ISUNDEF(iterator->sxe->iter.data) ? FAILURE : SUCCESS;
- }
- /* }}} */
- static zval *php_sxe_iterator_current_data(zend_object_iterator *iter) /* {{{ */
- {
- php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- return &iterator->sxe->iter.data;
- }
- /* }}} */
- static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key) /* {{{ */
- {
- php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- zval *curobj = &iterator->sxe->iter.data;
- php_sxe_object *intern = Z_SXEOBJ_P(curobj);
- xmlNodePtr curnode = NULL;
- if (intern != NULL && intern->node != NULL) {
- curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
- }
- if (curnode) {
- ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name));
- } else {
- ZVAL_NULL(key);
- }
- }
- /* }}} */
- PHP_SXE_API void php_sxe_move_forward_iterator(php_sxe_object *sxe) /* {{{ */
- {
- xmlNodePtr node = NULL;
- php_sxe_object *intern;
- if (!Z_ISUNDEF(sxe->iter.data)) {
- intern = Z_SXEOBJ_P(&sxe->iter.data);
- GET_NODE(intern, node)
- zval_ptr_dtor(&sxe->iter.data);
- ZVAL_UNDEF(&sxe->iter.data);
- }
- if (node) {
- php_sxe_iterator_fetch(sxe, node->next, 1);
- }
- }
- /* }}} */
- static void php_sxe_iterator_move_forward(zend_object_iterator *iter) /* {{{ */
- {
- php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- php_sxe_move_forward_iterator(iterator->sxe);
- }
- /* }}} */
- PHP_SXE_API void php_sxe_rewind_iterator(php_sxe_object *sxe) /* {{{ */
- {
- php_sxe_reset_iterator(sxe, 1);
- }
- /* }}} */
- static void php_sxe_iterator_rewind(zend_object_iterator *iter) /* {{{ */
- {
- php_sxe_object *sxe;
- php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- sxe = iterator->sxe;
- php_sxe_reset_iterator(sxe, 1);
- }
- /* }}} */
- void *simplexml_export_node(zval *object) /* {{{ */
- {
- php_sxe_object *sxe;
- xmlNodePtr node;
- sxe = Z_SXEOBJ_P(object);
- GET_NODE(sxe, node);
- return php_sxe_get_first_node(sxe, node);
- }
- /* }}} */
- /* {{{ Get a simplexml_element object from dom to allow for processing */
- PHP_FUNCTION(simplexml_import_dom)
- {
- php_sxe_object *sxe;
- zval *node;
- php_libxml_node_object *object;
- xmlNodePtr nodep = NULL;
- zend_class_entry *ce = sxe_class_entry;
- zend_function *fptr_count;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "o|C!", &node, &ce) == FAILURE) {
- RETURN_THROWS();
- }
- nodep = php_libxml_import_node(node);
- if (!nodep) {
- zend_argument_type_error(1, "must be of type SimpleXMLElement|DOMNode, %s given", zend_zval_type_name(node));
- RETURN_THROWS();
- }
- if (nodep->doc == NULL) {
- php_error_docref(NULL, E_WARNING, "Imported Node must have associated Document");
- RETURN_NULL();
- }
- if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
- nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
- }
- if (nodep && nodep->type == XML_ELEMENT_NODE) {
- if (!ce) {
- ce = sxe_class_entry;
- fptr_count = NULL;
- } else {
- fptr_count = php_sxe_find_fptr_count(ce);
- }
- object = Z_LIBXML_NODE_P(node);
- sxe = php_sxe_object_new(ce, fptr_count);
- sxe->document = object->document;
- php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, nodep->doc);
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, nodep, NULL);
- RETURN_OBJ(&sxe->zo);
- } else {
- php_error_docref(NULL, E_WARNING, "Invalid Nodetype to import");
- RETVAL_NULL();
- }
- }
- /* }}} */
- static const zend_module_dep simplexml_deps[] = { /* {{{ */
- ZEND_MOD_REQUIRED("libxml")
- ZEND_MOD_REQUIRED("spl")
- ZEND_MOD_END
- };
- /* }}} */
- zend_module_entry simplexml_module_entry = { /* {{{ */
- STANDARD_MODULE_HEADER_EX, NULL,
- simplexml_deps,
- "SimpleXML",
- ext_functions,
- PHP_MINIT(simplexml),
- PHP_MSHUTDOWN(simplexml),
- NULL,
- NULL,
- PHP_MINFO(simplexml),
- PHP_SIMPLEXML_VERSION,
- STANDARD_MODULE_PROPERTIES
- };
- /* }}} */
- #ifdef COMPILE_DL_SIMPLEXML
- ZEND_GET_MODULE(simplexml)
- #endif
- /* {{{ PHP_MINIT_FUNCTION(simplexml) */
- PHP_MINIT_FUNCTION(simplexml)
- {
- sxe_class_entry = register_class_SimpleXMLElement(zend_ce_stringable, zend_ce_countable, spl_ce_RecursiveIterator);
- sxe_class_entry->create_object = sxe_object_new;
- sxe_class_entry->get_iterator = php_sxe_get_iterator;
- memcpy(&sxe_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
- sxe_object_handlers.offset = XtOffsetOf(php_sxe_object, zo);
- sxe_object_handlers.free_obj = sxe_object_free_storage;
- sxe_object_handlers.clone_obj = sxe_object_clone;
- sxe_object_handlers.read_property = sxe_property_read;
- sxe_object_handlers.write_property = sxe_property_write;
- sxe_object_handlers.read_dimension = sxe_dimension_read;
- sxe_object_handlers.write_dimension = sxe_dimension_write;
- sxe_object_handlers.get_property_ptr_ptr = sxe_property_get_adr;
- sxe_object_handlers.has_property = sxe_property_exists;
- sxe_object_handlers.unset_property = sxe_property_delete;
- sxe_object_handlers.has_dimension = sxe_dimension_exists;
- sxe_object_handlers.unset_dimension = sxe_dimension_delete;
- sxe_object_handlers.get_properties = sxe_get_properties;
- sxe_object_handlers.compare = sxe_objects_compare;
- sxe_object_handlers.cast_object = sxe_object_cast;
- sxe_object_handlers.count_elements = sxe_count_elements;
- sxe_object_handlers.get_debug_info = sxe_get_debug_info;
- sxe_object_handlers.get_closure = NULL;
- sxe_object_handlers.get_gc = sxe_get_gc;
- /* TODO: Why do we have two variables for this? */
- ce_SimpleXMLElement = sxe_class_entry;
- ce_SimpleXMLIterator = register_class_SimpleXMLIterator(ce_SimpleXMLElement);
- php_libxml_register_export(sxe_class_entry, simplexml_export_node);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_MSHUTDOWN_FUNCTION(simplexml) */
- PHP_MSHUTDOWN_FUNCTION(simplexml)
- {
- sxe_class_entry = NULL;
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_MINFO_FUNCTION(simplexml) */
- PHP_MINFO_FUNCTION(simplexml)
- {
- php_info_print_table_start();
- php_info_print_table_row(2, "SimpleXML support", "enabled");
- php_info_print_table_row(2, "Schema support",
- #ifdef LIBXML_SCHEMAS_ENABLED
- "enabled");
- #else
- "not available");
- #endif
- php_info_print_table_end();
- }
- /* }}} */
- #endif
|