characterdata.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Christian Stocker <chregu@php.net> |
  14. | Rob Richards <rrichards@php.net> |
  15. +----------------------------------------------------------------------+
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include "php.h"
  21. #if defined(HAVE_LIBXML) && defined(HAVE_DOM)
  22. #include "php_dom.h"
  23. /*
  24. * class DOMCharacterData extends DOMNode
  25. *
  26. * URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306
  27. * Since:
  28. */
  29. /* {{{ data string
  30. readonly=no
  31. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359
  32. Since:
  33. */
  34. int dom_characterdata_data_read(dom_object *obj, zval *retval)
  35. {
  36. xmlNodePtr nodep = dom_object_get_node(obj);
  37. xmlChar *content;
  38. if (nodep == NULL) {
  39. php_dom_throw_error(INVALID_STATE_ERR, 1);
  40. return FAILURE;
  41. }
  42. if ((content = xmlNodeGetContent(nodep)) != NULL) {
  43. ZVAL_STRING(retval, (char *) content);
  44. xmlFree(content);
  45. } else {
  46. ZVAL_EMPTY_STRING(retval);
  47. }
  48. return SUCCESS;
  49. }
  50. int dom_characterdata_data_write(dom_object *obj, zval *newval)
  51. {
  52. xmlNode *nodep = dom_object_get_node(obj);
  53. zend_string *str;
  54. if (nodep == NULL) {
  55. php_dom_throw_error(INVALID_STATE_ERR, 1);
  56. return FAILURE;
  57. }
  58. str = zval_try_get_string(newval);
  59. if (UNEXPECTED(!str)) {
  60. return FAILURE;
  61. }
  62. xmlNodeSetContentLen(nodep, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str) + 1);
  63. zend_string_release_ex(str, 0);
  64. return SUCCESS;
  65. }
  66. /* }}} */
  67. /* {{{ length long
  68. readonly=yes
  69. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
  70. Since:
  71. */
  72. int dom_characterdata_length_read(dom_object *obj, zval *retval)
  73. {
  74. xmlNodePtr nodep = dom_object_get_node(obj);
  75. xmlChar *content;
  76. long length = 0;
  77. if (nodep == NULL) {
  78. php_dom_throw_error(INVALID_STATE_ERR, 1);
  79. return FAILURE;
  80. }
  81. content = xmlNodeGetContent(nodep);
  82. if (content) {
  83. length = xmlUTF8Strlen(content);
  84. xmlFree(content);
  85. }
  86. ZVAL_LONG(retval, length);
  87. return SUCCESS;
  88. }
  89. /* }}} */
  90. /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
  91. Since:
  92. */
  93. PHP_METHOD(DOMCharacterData, substringData)
  94. {
  95. zval *id;
  96. xmlChar *cur;
  97. xmlChar *substring;
  98. xmlNodePtr node;
  99. zend_long offset, count;
  100. int length;
  101. dom_object *intern;
  102. id = ZEND_THIS;
  103. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
  104. RETURN_THROWS();
  105. }
  106. DOM_GET_OBJ(node, id, xmlNodePtr, intern);
  107. cur = xmlNodeGetContent(node);
  108. if (cur == NULL) {
  109. RETURN_FALSE;
  110. }
  111. length = xmlUTF8Strlen(cur);
  112. if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
  113. xmlFree(cur);
  114. php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
  115. RETURN_FALSE;
  116. }
  117. if ((offset + count) > length) {
  118. count = length - offset;
  119. }
  120. substring = xmlUTF8Strsub(cur, (int)offset, (int)count);
  121. xmlFree(cur);
  122. if (substring) {
  123. RETVAL_STRING((char *) substring);
  124. xmlFree(substring);
  125. } else {
  126. RETVAL_EMPTY_STRING();
  127. }
  128. }
  129. /* }}} end dom_characterdata_substring_data */
  130. /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
  131. Since:
  132. */
  133. PHP_METHOD(DOMCharacterData, appendData)
  134. {
  135. zval *id;
  136. xmlNode *nodep;
  137. dom_object *intern;
  138. char *arg;
  139. size_t arg_len;
  140. id = ZEND_THIS;
  141. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
  142. RETURN_THROWS();
  143. }
  144. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  145. xmlTextConcat(nodep, (xmlChar *) arg, arg_len);
  146. RETURN_TRUE;
  147. }
  148. /* }}} end dom_characterdata_append_data */
  149. /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
  150. Since:
  151. */
  152. PHP_METHOD(DOMCharacterData, insertData)
  153. {
  154. zval *id;
  155. xmlChar *cur, *first, *second;
  156. xmlNodePtr node;
  157. char *arg;
  158. zend_long offset;
  159. int length;
  160. size_t arg_len;
  161. dom_object *intern;
  162. id = ZEND_THIS;
  163. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &offset, &arg, &arg_len) == FAILURE) {
  164. RETURN_THROWS();
  165. }
  166. DOM_GET_OBJ(node, id, xmlNodePtr, intern);
  167. cur = xmlNodeGetContent(node);
  168. if (cur == NULL) {
  169. RETURN_FALSE;
  170. }
  171. length = xmlUTF8Strlen(cur);
  172. if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
  173. xmlFree(cur);
  174. php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
  175. RETURN_FALSE;
  176. }
  177. first = xmlUTF8Strndup(cur, (int)offset);
  178. second = xmlUTF8Strsub(cur, (int)offset, length - (int)offset);
  179. xmlFree(cur);
  180. xmlNodeSetContent(node, first);
  181. xmlNodeAddContent(node, (xmlChar *) arg);
  182. xmlNodeAddContent(node, second);
  183. xmlFree(first);
  184. xmlFree(second);
  185. RETURN_TRUE;
  186. }
  187. /* }}} end dom_characterdata_insert_data */
  188. /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
  189. Since:
  190. */
  191. PHP_METHOD(DOMCharacterData, deleteData)
  192. {
  193. zval *id;
  194. xmlChar *cur, *substring, *second;
  195. xmlNodePtr node;
  196. zend_long offset, count;
  197. int length;
  198. dom_object *intern;
  199. id = ZEND_THIS;
  200. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
  201. RETURN_THROWS();
  202. }
  203. DOM_GET_OBJ(node, id, xmlNodePtr, intern);
  204. cur = xmlNodeGetContent(node);
  205. if (cur == NULL) {
  206. RETURN_FALSE;
  207. }
  208. length = xmlUTF8Strlen(cur);
  209. if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
  210. xmlFree(cur);
  211. php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
  212. RETURN_FALSE;
  213. }
  214. if (offset > 0) {
  215. substring = xmlUTF8Strsub(cur, 0, (int)offset);
  216. } else {
  217. substring = NULL;
  218. }
  219. if ((offset + count) > length) {
  220. count = length - offset;
  221. }
  222. second = xmlUTF8Strsub(cur, (int)offset + (int)count, length - (int)offset);
  223. substring = xmlStrcat(substring, second);
  224. xmlNodeSetContent(node, substring);
  225. xmlFree(cur);
  226. xmlFree(second);
  227. xmlFree(substring);
  228. RETURN_TRUE;
  229. }
  230. /* }}} end dom_characterdata_delete_data */
  231. /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
  232. Since:
  233. */
  234. PHP_METHOD(DOMCharacterData, replaceData)
  235. {
  236. zval *id;
  237. xmlChar *cur, *substring, *second = NULL;
  238. xmlNodePtr node;
  239. char *arg;
  240. zend_long offset, count;
  241. int length;
  242. size_t arg_len;
  243. dom_object *intern;
  244. id = ZEND_THIS;
  245. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lls", &offset, &count, &arg, &arg_len) == FAILURE) {
  246. RETURN_THROWS();
  247. }
  248. DOM_GET_OBJ(node, id, xmlNodePtr, intern);
  249. cur = xmlNodeGetContent(node);
  250. if (cur == NULL) {
  251. RETURN_FALSE;
  252. }
  253. length = xmlUTF8Strlen(cur);
  254. if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
  255. xmlFree(cur);
  256. php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
  257. RETURN_FALSE;
  258. }
  259. if (offset > 0) {
  260. substring = xmlUTF8Strsub(cur, 0, (int)offset);
  261. } else {
  262. substring = NULL;
  263. }
  264. if ((offset + count) > length) {
  265. count = length - offset;
  266. }
  267. if (offset < length) {
  268. second = xmlUTF8Strsub(cur, (int)offset + count, length - (int)offset);
  269. }
  270. substring = xmlStrcat(substring, (xmlChar *) arg);
  271. substring = xmlStrcat(substring, second);
  272. xmlNodeSetContent(node, substring);
  273. xmlFree(cur);
  274. if (second) {
  275. xmlFree(second);
  276. }
  277. xmlFree(substring);
  278. RETURN_TRUE;
  279. }
  280. /* }}} end dom_characterdata_replace_data */
  281. PHP_METHOD(DOMCharacterData, remove)
  282. {
  283. zval *id = ZEND_THIS;
  284. xmlNodePtr child;
  285. dom_object *intern;
  286. if (zend_parse_parameters_none() == FAILURE) {
  287. RETURN_THROWS();
  288. }
  289. DOM_GET_OBJ(child, id, xmlNodePtr, intern);
  290. dom_child_node_remove(intern);
  291. RETURN_NULL();
  292. }
  293. PHP_METHOD(DOMCharacterData, after)
  294. {
  295. int argc;
  296. zval *args, *id;
  297. dom_object *intern;
  298. xmlNode *context;
  299. if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
  300. RETURN_THROWS();
  301. }
  302. id = ZEND_THIS;
  303. DOM_GET_OBJ(context, id, xmlNodePtr, intern);
  304. dom_parent_node_after(intern, args, argc);
  305. }
  306. PHP_METHOD(DOMCharacterData, before)
  307. {
  308. int argc;
  309. zval *args, *id;
  310. dom_object *intern;
  311. xmlNode *context;
  312. if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
  313. RETURN_THROWS();
  314. }
  315. id = ZEND_THIS;
  316. DOM_GET_OBJ(context, id, xmlNodePtr, intern);
  317. dom_parent_node_before(intern, args, argc);
  318. }
  319. PHP_METHOD(DOMCharacterData, replaceWith)
  320. {
  321. int argc;
  322. zval *args, *id;
  323. dom_object *intern;
  324. xmlNode *context;
  325. if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
  326. RETURN_THROWS();
  327. }
  328. id = ZEND_THIS;
  329. DOM_GET_OBJ(context, id, xmlNodePtr, intern);
  330. dom_parent_node_after(intern, args, argc);
  331. dom_child_node_remove(intern);
  332. }
  333. #endif