1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2014 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 */
32 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_substring_data, 0, 0, 2)
33 ZEND_ARG_INFO(0, offset)
34 ZEND_ARG_INFO(0, count)
35 ZEND_END_ARG_INFO();
36
37 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_append_data, 0, 0, 1)
38 ZEND_ARG_INFO(0, arg)
39 ZEND_END_ARG_INFO();
40
41 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_insert_data, 0, 0, 2)
42 ZEND_ARG_INFO(0, offset)
43 ZEND_ARG_INFO(0, arg)
44 ZEND_END_ARG_INFO();
45
46 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_delete_data, 0, 0, 2)
47 ZEND_ARG_INFO(0, offset)
48 ZEND_ARG_INFO(0, count)
49 ZEND_END_ARG_INFO();
50
51 ZEND_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)
55 ZEND_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
65 const 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
75 readonly=no
76 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359
77 Since:
78 */
dom_characterdata_data_read(dom_object * obj,zval ** retval TSRMLS_DC)79 int 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
dom_characterdata_data_write(dom_object * obj,zval * newval TSRMLS_DC)103 int 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
136 readonly=yes
137 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
138 Since:
139 */
dom_characterdata_length_read(dom_object * obj,zval ** retval TSRMLS_DC)140 int 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);
170 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
171 Since:
172 */
PHP_FUNCTION(dom_characterdata_substring_data)173 PHP_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);
219 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
220 Since:
221 */
PHP_FUNCTION(dom_characterdata_append_data)222 PHP_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);
253 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
254 Since:
255 */
PHP_FUNCTION(dom_characterdata_insert_data)256 PHP_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);
301 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
302 Since:
303 */
PHP_FUNCTION(dom_characterdata_delete_data)304 PHP_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);
356 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
357 Since:
358 */
PHP_FUNCTION(dom_characterdata_replace_data)359 PHP_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