1/* 2 +----------------------------------------------------------------------+ 3 | PHP Version 5 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2013 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: Christian Stocker <chregu@php.net> | 16 | Rob Richards <rrichards@php.net> | 17 +----------------------------------------------------------------------+ 18*/ 19 20/* $Id$ */ 21 22#ifdef HAVE_CONFIG_H 23#include "config.h" 24#endif 25 26#include "php.h" 27#if HAVE_LIBXML && HAVE_DOM 28#include "php_dom.h" 29 30 31/* {{{ arginfo */ 32ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_substring_data, 0, 0, 2) 33 ZEND_ARG_INFO(0, offset) 34 ZEND_ARG_INFO(0, count) 35ZEND_END_ARG_INFO(); 36 37ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_append_data, 0, 0, 1) 38 ZEND_ARG_INFO(0, arg) 39ZEND_END_ARG_INFO(); 40 41ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_insert_data, 0, 0, 2) 42 ZEND_ARG_INFO(0, offset) 43 ZEND_ARG_INFO(0, arg) 44ZEND_END_ARG_INFO(); 45 46ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_delete_data, 0, 0, 2) 47 ZEND_ARG_INFO(0, offset) 48 ZEND_ARG_INFO(0, count) 49ZEND_END_ARG_INFO(); 50 51ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_replace_data, 0, 0, 3) 52 ZEND_ARG_INFO(0, offset) 53 ZEND_ARG_INFO(0, count) 54 ZEND_ARG_INFO(0, arg) 55ZEND_END_ARG_INFO(); 56/* }}} */ 57 58/* 59* class DOMCharacterData extends DOMNode 60* 61* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306 62* Since: 63*/ 64 65const zend_function_entry php_dom_characterdata_class_functions[] = { 66 PHP_FALIAS(substringData, dom_characterdata_substring_data, arginfo_dom_characterdata_substring_data) 67 PHP_FALIAS(appendData, dom_characterdata_append_data, arginfo_dom_characterdata_append_data) 68 PHP_FALIAS(insertData, dom_characterdata_insert_data, arginfo_dom_characterdata_insert_data) 69 PHP_FALIAS(deleteData, dom_characterdata_delete_data, arginfo_dom_characterdata_delete_data) 70 PHP_FALIAS(replaceData, dom_characterdata_replace_data, arginfo_dom_characterdata_replace_data) 71 PHP_FE_END 72}; 73 74/* {{{ data string 75readonly=no 76URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359 77Since: 78*/ 79int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC) 80{ 81 xmlNodePtr nodep; 82 xmlChar *content; 83 84 nodep = dom_object_get_node(obj); 85 86 if (nodep == NULL) { 87 php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); 88 return FAILURE; 89 } 90 91 ALLOC_ZVAL(*retval); 92 93 if ((content = xmlNodeGetContent(nodep)) != NULL) { 94 ZVAL_STRING(*retval, content, 1); 95 xmlFree(content); 96 } else { 97 ZVAL_EMPTY_STRING(*retval); 98 } 99 100 return SUCCESS; 101} 102 103int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC) 104{ 105 zval value_copy; 106 xmlNode *nodep; 107 108 nodep = dom_object_get_node(obj); 109 110 if (nodep == NULL) { 111 php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); 112 return FAILURE; 113 } 114 115 if (newval->type != IS_STRING) { 116 if(Z_REFCOUNT_P(newval) > 1) { 117 value_copy = *newval; 118 zval_copy_ctor(&value_copy); 119 newval = &value_copy; 120 } 121 convert_to_string(newval); 122 } 123 124 xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); 125 126 if (newval == &value_copy) { 127 zval_dtor(newval); 128 } 129 130 return SUCCESS; 131} 132 133/* }}} */ 134 135/* {{{ length long 136readonly=yes 137URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C 138Since: 139*/ 140int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC) 141{ 142 xmlNodePtr nodep; 143 xmlChar *content; 144 long length = 0; 145 146 nodep = dom_object_get_node(obj); 147 148 if (nodep == NULL) { 149 php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); 150 return FAILURE; 151 } 152 153 ALLOC_ZVAL(*retval); 154 155 content = xmlNodeGetContent(nodep); 156 157 if (content) { 158 length = xmlUTF8Strlen(content); 159 xmlFree(content); 160 } 161 162 ZVAL_LONG(*retval, length); 163 164 return SUCCESS; 165} 166 167/* }}} */ 168 169/* {{{ proto string dom_characterdata_substring_data(int offset, int count); 170URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF 171Since: 172*/ 173PHP_FUNCTION(dom_characterdata_substring_data) 174{ 175 zval *id; 176 xmlChar *cur; 177 xmlChar *substring; 178 xmlNodePtr node; 179 long offset, count; 180 int length; 181 dom_object *intern; 182 183 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) { 184 return; 185 } 186 187 DOM_GET_OBJ(node, id, xmlNodePtr, intern); 188 189 cur = xmlNodeGetContent(node); 190 if (cur == NULL) { 191 RETURN_FALSE; 192 } 193 194 length = xmlUTF8Strlen(cur); 195 196 if (offset < 0 || count < 0 || offset > length) { 197 xmlFree(cur); 198 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); 199 RETURN_FALSE; 200 } 201 202 if ((offset + count) > length) { 203 count = length - offset; 204 } 205 206 substring = xmlUTF8Strsub(cur, offset, count); 207 xmlFree(cur); 208 209 if (substring) { 210 RETVAL_STRING(substring, 1); 211 xmlFree(substring); 212 } else { 213 RETVAL_EMPTY_STRING(); 214 } 215} 216/* }}} end dom_characterdata_substring_data */ 217 218/* {{{ proto void dom_characterdata_append_data(string arg); 219URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F 220Since: 221*/ 222PHP_FUNCTION(dom_characterdata_append_data) 223{ 224 zval *id; 225 xmlNode *nodep; 226 dom_object *intern; 227 char *arg; 228 int arg_len; 229 230 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_characterdata_class_entry, &arg, &arg_len) == FAILURE) { 231 return; 232 } 233 234 DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); 235#if LIBXML_VERSION < 20627 236/* Implement logic from libxml xmlTextConcat to add suport for comments and PI */ 237 if ((nodep->content == (xmlChar *) &(nodep->properties)) || 238 ((nodep->doc != NULL) && (nodep->doc->dict != NULL) && 239 xmlDictOwns(nodep->doc->dict, nodep->content))) { 240 nodep->content = xmlStrncatNew(nodep->content, arg, arg_len); 241 } else { 242 nodep->content = xmlStrncat(nodep->content, arg, arg_len); 243 } 244 nodep->properties = NULL; 245#else 246 xmlTextConcat(nodep, arg, arg_len); 247#endif 248 RETURN_TRUE; 249} 250/* }}} end dom_characterdata_append_data */ 251 252/* {{{ proto void dom_characterdata_insert_data(int offset, string arg); 253URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F 254Since: 255*/ 256PHP_FUNCTION(dom_characterdata_insert_data) 257{ 258 zval *id; 259 xmlChar *cur, *first, *second; 260 xmlNodePtr node; 261 char *arg; 262 long offset; 263 int length, arg_len; 264 dom_object *intern; 265 266 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len) == FAILURE) { 267 return; 268 } 269 270 DOM_GET_OBJ(node, id, xmlNodePtr, intern); 271 272 cur = xmlNodeGetContent(node); 273 if (cur == NULL) { 274 RETURN_FALSE; 275 } 276 277 length = xmlUTF8Strlen(cur); 278 279 if (offset < 0 || offset > length) { 280 xmlFree(cur); 281 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); 282 RETURN_FALSE; 283 } 284 285 first = xmlUTF8Strndup(cur, offset); 286 second = xmlUTF8Strsub(cur, offset, length - offset); 287 xmlFree(cur); 288 289 xmlNodeSetContent(node, first); 290 xmlNodeAddContent(node, arg); 291 xmlNodeAddContent(node, second); 292 293 xmlFree(first); 294 xmlFree(second); 295 296 RETURN_TRUE; 297} 298/* }}} end dom_characterdata_insert_data */ 299 300/* {{{ proto void dom_characterdata_delete_data(int offset, int count); 301URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781 302Since: 303*/ 304PHP_FUNCTION(dom_characterdata_delete_data) 305{ 306 zval *id; 307 xmlChar *cur, *substring, *second; 308 xmlNodePtr node; 309 long offset, count; 310 int length; 311 dom_object *intern; 312 313 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) { 314 return; 315 } 316 317 DOM_GET_OBJ(node, id, xmlNodePtr, intern); 318 319 cur = xmlNodeGetContent(node); 320 if (cur == NULL) { 321 RETURN_FALSE; 322 } 323 324 length = xmlUTF8Strlen(cur); 325 326 if (offset < 0 || count < 0 || offset > length) { 327 xmlFree(cur); 328 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); 329 RETURN_FALSE; 330 } 331 332 if (offset > 0) { 333 substring = xmlUTF8Strsub(cur, 0, offset); 334 } else { 335 substring = NULL; 336 } 337 338 if ((offset + count) > length) { 339 count = length - offset; 340 } 341 342 second = xmlUTF8Strsub(cur, offset + count, length - offset); 343 substring = xmlStrcat(substring, second); 344 345 xmlNodeSetContent(node, substring); 346 347 xmlFree(cur); 348 xmlFree(second); 349 xmlFree(substring); 350 351 RETURN_TRUE; 352} 353/* }}} end dom_characterdata_delete_data */ 354 355/* {{{ proto void dom_characterdata_replace_data(int offset, int count, string arg); 356URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB 357Since: 358*/ 359PHP_FUNCTION(dom_characterdata_replace_data) 360{ 361 zval *id; 362 xmlChar *cur, *substring, *second = NULL; 363 xmlNodePtr node; 364 char *arg; 365 long offset, count; 366 int length, arg_len; 367 dom_object *intern; 368 369 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olls", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len) == FAILURE) { 370 return; 371 } 372 373 DOM_GET_OBJ(node, id, xmlNodePtr, intern); 374 375 cur = xmlNodeGetContent(node); 376 if (cur == NULL) { 377 RETURN_FALSE; 378 } 379 380 length = xmlUTF8Strlen(cur); 381 382 if (offset < 0 || count < 0 || offset > length) { 383 xmlFree(cur); 384 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); 385 RETURN_FALSE; 386 } 387 388 if (offset > 0) { 389 substring = xmlUTF8Strsub(cur, 0, offset); 390 } else { 391 substring = NULL; 392 } 393 394 if ((offset + count) > length) { 395 count = length - offset; 396 } 397 398 if (offset < length) { 399 second = xmlUTF8Strsub(cur, offset + count, length - offset); 400 } 401 402 substring = xmlStrcat(substring, arg); 403 substring = xmlStrcat(substring, second); 404 405 xmlNodeSetContent(node, substring); 406 407 xmlFree(cur); 408 if (second) { 409 xmlFree(second); 410 } 411 xmlFree(substring); 412 413 RETURN_TRUE; 414} 415/* }}} end dom_characterdata_replace_data */ 416 417#endif 418 419/* 420 * Local variables: 421 * tab-width: 4 422 * c-basic-offset: 4 423 * End: 424 * vim600: noet sw=4 ts=4 fdm=marker 425 * vim<600: noet sw=4 ts=4 426 */ 427