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