1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
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 281094 2009-05-25 14:32:15Z felipe $ */
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 : {NULL, NULL, NULL}
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 : */
79 : int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC)
80 9 : {
81 : xmlNodePtr nodep;
82 : xmlChar *content;
83 :
84 9 : nodep = dom_object_get_node(obj);
85 :
86 9 : if (nodep == NULL) {
87 1 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
88 1 : return FAILURE;
89 : }
90 :
91 8 : ALLOC_ZVAL(*retval);
92 :
93 8 : if ((content = xmlNodeGetContent(nodep)) != NULL) {
94 8 : ZVAL_XML_STRING(*retval, content, ZSTR_DUPLICATE);
95 8 : xmlFree(content);
96 : } else {
97 0 : ZVAL_EMPTY_UNICODE(*retval);
98 : }
99 :
100 8 : return SUCCESS;
101 : }
102 :
103 : int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC)
104 3 : {
105 : zval value_copy;
106 : xmlNode *nodep;
107 :
108 3 : nodep = dom_object_get_node(obj);
109 :
110 3 : if (nodep == NULL) {
111 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
112 0 : return FAILURE;
113 : }
114 :
115 3 : if (newval->type != IS_STRING) {
116 3 : if(Z_REFCOUNT_P(newval) > 1) {
117 0 : value_copy = *newval;
118 0 : zval_copy_ctor(&value_copy);
119 0 : newval = &value_copy;
120 : }
121 3 : convert_to_string_with_converter(newval, UG(utf8_conv));
122 : }
123 :
124 3 : xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
125 :
126 3 : if (newval == &value_copy) {
127 0 : zval_dtor(newval);
128 : }
129 :
130 3 : 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 : */
140 : int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC)
141 9 : {
142 : xmlNodePtr nodep;
143 : xmlChar *content;
144 9 : long length = 0;
145 :
146 9 : nodep = dom_object_get_node(obj);
147 :
148 9 : if (nodep == NULL) {
149 1 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
150 1 : return FAILURE;
151 : }
152 :
153 8 : ALLOC_ZVAL(*retval);
154 :
155 8 : content = xmlNodeGetContent(nodep);
156 :
157 8 : if (content) {
158 8 : length = xmlUTF8Strlen(content);
159 8 : xmlFree(content);
160 : }
161 :
162 8 : ZVAL_LONG(*retval, length);
163 :
164 8 : return SUCCESS;
165 : }
166 :
167 : /* }}} */
168 :
169 : /* {{{ proto string dom_characterdata_substring_data(int offset, int count) U
170 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
171 : Since:
172 : */
173 : PHP_FUNCTION(dom_characterdata_substring_data)
174 3 : {
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 3 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
184 0 : return;
185 : }
186 :
187 3 : DOM_GET_OBJ(node, id, xmlNodePtr, intern);
188 :
189 3 : cur = xmlNodeGetContent(node);
190 3 : if (cur == NULL) {
191 0 : RETURN_FALSE;
192 : }
193 :
194 3 : length = xmlUTF8Strlen(cur);
195 :
196 3 : if (offset < 0 || count < 0 || offset > length) {
197 0 : xmlFree(cur);
198 0 : php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
199 0 : RETURN_FALSE;
200 : }
201 :
202 3 : if ((offset + count) > length) {
203 0 : count = length - offset;
204 : }
205 :
206 3 : substring = xmlUTF8Strsub(cur, offset, count);
207 3 : xmlFree(cur);
208 :
209 3 : if (substring) {
210 3 : RETVAL_XML_STRING(substring, ZSTR_DUPLICATE);
211 3 : xmlFree(substring);
212 : } else {
213 0 : RETVAL_EMPTY_UNICODE();
214 : }
215 : }
216 : /* }}} end dom_characterdata_substring_data */
217 :
218 : /* {{{ proto void dom_characterdata_append_data(string arg) U
219 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
220 : Since:
221 : */
222 : PHP_FUNCTION(dom_characterdata_append_data)
223 8 : {
224 : zval *id;
225 : xmlNode *nodep;
226 : dom_object *intern;
227 : char *arg;
228 : int arg_len;
229 :
230 8 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&", &id, dom_characterdata_class_entry, &arg, &arg_len, UG(utf8_conv)) == FAILURE) {
231 1 : return;
232 : }
233 :
234 7 : 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 7 : if ((nodep->content == (xmlChar *) &(nodep->properties)) ||
238 : ((nodep->doc != NULL) && (nodep->doc->dict != NULL) &&
239 : xmlDictOwns(nodep->doc->dict, nodep->content))) {
240 0 : nodep->content = xmlStrncatNew(nodep->content, arg, arg_len);
241 : } else {
242 7 : nodep->content = xmlStrncat(nodep->content, arg, arg_len);
243 : }
244 7 : nodep->properties = NULL;
245 : #else
246 : xmlTextConcat(nodep, arg, arg_len);
247 : #endif
248 7 : RETURN_TRUE;
249 : }
250 : /* }}} end dom_characterdata_append_data */
251 :
252 : /* {{{ proto void dom_characterdata_insert_data(int offset, string arg) U
253 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
254 : Since:
255 : */
256 : PHP_FUNCTION(dom_characterdata_insert_data)
257 7 : {
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 7 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols&", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len, UG(utf8_conv)) == FAILURE) {
267 1 : return;
268 : }
269 :
270 6 : DOM_GET_OBJ(node, id, xmlNodePtr, intern);
271 :
272 6 : cur = xmlNodeGetContent(node);
273 6 : if (cur == NULL) {
274 0 : RETURN_FALSE;
275 : }
276 :
277 6 : length = xmlUTF8Strlen(cur);
278 :
279 6 : if (offset < 0 || offset > length) {
280 2 : xmlFree(cur);
281 2 : php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
282 2 : RETURN_FALSE;
283 : }
284 :
285 4 : first = xmlUTF8Strndup(cur, offset);
286 4 : second = xmlUTF8Strsub(cur, offset, length - offset);
287 4 : xmlFree(cur);
288 :
289 4 : xmlNodeSetContent(node, first);
290 4 : xmlNodeAddContent(node, arg);
291 4 : xmlNodeAddContent(node, second);
292 :
293 4 : xmlFree(first);
294 4 : xmlFree(second);
295 :
296 4 : RETURN_TRUE;
297 : }
298 : /* }}} end dom_characterdata_insert_data */
299 :
300 : /* {{{ proto void dom_characterdata_delete_data(int offset, int count) U
301 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
302 : Since:
303 : */
304 : PHP_FUNCTION(dom_characterdata_delete_data)
305 5 : {
306 : zval *id;
307 : xmlChar *cur, *substring, *second;
308 : xmlNodePtr node;
309 : long offset, count;
310 : int length;
311 : dom_object *intern;
312 :
313 5 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
314 1 : return;
315 : }
316 :
317 4 : DOM_GET_OBJ(node, id, xmlNodePtr, intern);
318 :
319 4 : cur = xmlNodeGetContent(node);
320 4 : if (cur == NULL) {
321 0 : RETURN_FALSE;
322 : }
323 :
324 4 : length = xmlUTF8Strlen(cur);
325 :
326 4 : if (offset < 0 || count < 0 || offset > length) {
327 1 : xmlFree(cur);
328 1 : php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
329 1 : RETURN_FALSE;
330 : }
331 :
332 3 : if (offset > 0) {
333 3 : substring = xmlUTF8Strsub(cur, 0, offset);
334 : } else {
335 0 : substring = NULL;
336 : }
337 :
338 3 : if ((offset + count) > length) {
339 1 : count = length - offset;
340 : }
341 :
342 3 : second = xmlUTF8Strsub(cur, offset + count, length - offset);
343 3 : substring = xmlStrcat(substring, second);
344 :
345 3 : xmlNodeSetContent(node, substring);
346 :
347 3 : xmlFree(cur);
348 3 : xmlFree(second);
349 3 : xmlFree(substring);
350 :
351 3 : RETURN_TRUE;
352 : }
353 : /* }}} end dom_characterdata_delete_data */
354 :
355 : /* {{{ proto void dom_characterdata_replace_data(int offset, int count, string arg) U
356 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
357 : Since:
358 : */
359 : PHP_FUNCTION(dom_characterdata_replace_data)
360 7 : {
361 : zval *id;
362 7 : 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 7 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olls&", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len, UG(utf8_conv)) == FAILURE) {
370 1 : return;
371 : }
372 :
373 6 : DOM_GET_OBJ(node, id, xmlNodePtr, intern);
374 :
375 6 : cur = xmlNodeGetContent(node);
376 6 : if (cur == NULL) {
377 0 : RETURN_FALSE;
378 : }
379 :
380 6 : length = xmlUTF8Strlen(cur);
381 :
382 6 : if (offset < 0 || count < 0 || offset > length) {
383 2 : xmlFree(cur);
384 2 : php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
385 2 : RETURN_FALSE;
386 : }
387 :
388 4 : if (offset > 0) {
389 3 : substring = xmlUTF8Strsub(cur, 0, offset);
390 : } else {
391 1 : substring = NULL;
392 : }
393 :
394 4 : if ((offset + count) > length) {
395 1 : count = length - offset;
396 : }
397 :
398 4 : if (offset < length) {
399 4 : second = xmlUTF8Strsub(cur, offset + count, length - offset);
400 : }
401 :
402 4 : substring = xmlStrcat(substring, arg);
403 4 : substring = xmlStrcat(substring, second);
404 :
405 4 : xmlNodeSetContent(node, substring);
406 :
407 4 : xmlFree(cur);
408 4 : if (second) {
409 4 : xmlFree(second);
410 : }
411 4 : xmlFree(substring);
412 :
413 4 : 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 : */
|