1/*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2015 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#include "dom_ce.h"
30
31/* {{{ arginfo */
32ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_split_text, 0, 0, 1)
33    ZEND_ARG_INFO(0, offset)
34ZEND_END_ARG_INFO();
35
36ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_is_whitespace_in_element_content, 0, 0, 0)
37ZEND_END_ARG_INFO();
38
39ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_replace_whole_text, 0, 0, 1)
40    ZEND_ARG_INFO(0, content)
41ZEND_END_ARG_INFO();
42
43ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_construct, 0, 0, 0)
44    ZEND_ARG_INFO(0, value)
45ZEND_END_ARG_INFO();
46/* }}} */
47
48/*
49* class DOMText extends DOMCharacterData
50*
51* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1312295772
52* Since:
53*/
54
55const zend_function_entry php_dom_text_class_functions[] = {
56    PHP_FALIAS(splitText, dom_text_split_text, arginfo_dom_text_split_text)
57    PHP_FALIAS(isWhitespaceInElementContent, dom_text_is_whitespace_in_element_content, arginfo_dom_text_is_whitespace_in_element_content)
58    PHP_FALIAS(isElementContentWhitespace, dom_text_is_whitespace_in_element_content, arginfo_dom_text_is_whitespace_in_element_content)
59    PHP_FALIAS(replaceWholeText, dom_text_replace_whole_text, arginfo_dom_text_replace_whole_text)
60    PHP_ME(domtext, __construct, arginfo_dom_text_construct, ZEND_ACC_PUBLIC)
61    PHP_FE_END
62};
63
64/* {{{ proto void DOMText::__construct([string value]); */
65PHP_METHOD(domtext, __construct)
66{
67
68    zval *id = getThis();
69    xmlNodePtr nodep = NULL, oldnode = NULL;
70    dom_object *intern;
71    char *value = NULL;
72    size_t value_len;
73
74    if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|s", &value, &value_len) == FAILURE) {
75        return;
76    }
77
78    nodep = xmlNewText((xmlChar *) value);
79
80    if (!nodep) {
81        php_dom_throw_error(INVALID_STATE_ERR, 1);
82        RETURN_FALSE;
83    }
84
85    intern = Z_DOMOBJ_P(id);
86    if (intern != NULL) {
87        oldnode = dom_object_get_node(intern);
88        if (oldnode != NULL) {
89            php_libxml_node_free_resource(oldnode );
90        }
91        php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern);
92    }
93}
94/* }}} end DOMText::__construct */
95
96/* {{{ wholeText    string
97readonly=yes
98URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-wholeText
99Since: DOM Level 3
100*/
101int dom_text_whole_text_read(dom_object *obj, zval *retval)
102{
103    xmlNodePtr node;
104    xmlChar *wholetext = NULL;
105
106    node = dom_object_get_node(obj);
107
108    if (node == NULL) {
109        php_dom_throw_error(INVALID_STATE_ERR, 0);
110        return FAILURE;
111    }
112
113    /* Find starting text node */
114    while (node->prev && ((node->prev->type == XML_TEXT_NODE) || (node->prev->type == XML_CDATA_SECTION_NODE))) {
115        node = node->prev;
116    }
117
118    /* concatenate all adjacent text and cdata nodes */
119    while (node && ((node->type == XML_TEXT_NODE) || (node->type == XML_CDATA_SECTION_NODE))) {
120        wholetext = xmlStrcat(wholetext, node->content);
121        node = node->next;
122    }
123
124    if (wholetext != NULL) {
125        ZVAL_STRING(retval, (char *) wholetext);
126        xmlFree(wholetext);
127    } else {
128        ZVAL_EMPTY_STRING(retval);
129    }
130
131    return SUCCESS;
132}
133
134/* }}} */
135
136/* {{{ proto DOMText dom_text_split_text(int offset)
137URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D
138Since:
139*/
140PHP_FUNCTION(dom_text_split_text)
141{
142    zval       *id;
143    xmlChar    *cur;
144    xmlChar    *first;
145    xmlChar    *second;
146    xmlNodePtr  node;
147    xmlNodePtr  nnode;
148    zend_long        offset;
149    int         length;
150    dom_object  *intern;
151
152    if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &id, dom_text_class_entry, &offset) == FAILURE) {
153        return;
154    }
155    DOM_GET_OBJ(node, id, xmlNodePtr, intern);
156
157    if (node->type != XML_TEXT_NODE && node->type != XML_CDATA_SECTION_NODE) {
158        RETURN_FALSE;
159    }
160
161    cur = xmlNodeGetContent(node);
162    if (cur == NULL) {
163        RETURN_FALSE;
164    }
165    length = xmlUTF8Strlen(cur);
166
167    if (offset > length || offset < 0) {
168        xmlFree(cur);
169        RETURN_FALSE;
170    }
171
172    first = xmlUTF8Strndup(cur, offset);
173    second = xmlUTF8Strsub(cur, offset, length - offset);
174
175    xmlFree(cur);
176
177    xmlNodeSetContent(node, first);
178    nnode = xmlNewDocText(node->doc, second);
179
180    xmlFree(first);
181    xmlFree(second);
182
183    if (nnode == NULL) {
184        RETURN_FALSE;
185    }
186
187    if (node->parent != NULL) {
188        nnode->type = XML_ELEMENT_NODE;
189        xmlAddNextSibling(node, nnode);
190        nnode->type = XML_TEXT_NODE;
191    }
192
193    php_dom_create_object(nnode, return_value, intern);
194}
195/* }}} end dom_text_split_text */
196
197/* {{{ proto boolean dom_text_is_whitespace_in_element_content()
198URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent
199Since: DOM Level 3
200*/
201PHP_FUNCTION(dom_text_is_whitespace_in_element_content)
202{
203    zval       *id;
204    xmlNodePtr  node;
205    dom_object  *intern;
206
207    if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_text_class_entry) == FAILURE) {
208        return;
209    }
210    DOM_GET_OBJ(node, id, xmlNodePtr, intern);
211
212    if (xmlIsBlankNode(node)) {
213        RETURN_TRUE;
214    } else {
215        RETURN_FALSE;
216    }
217}
218/* }}} end dom_text_is_whitespace_in_element_content */
219
220/* {{{ proto DOMText dom_text_replace_whole_text(string content)
221URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText
222Since: DOM Level 3
223*/
224PHP_FUNCTION(dom_text_replace_whole_text)
225{
226 DOM_NOT_IMPLEMENTED();
227}
228/* }}} end dom_text_replace_whole_text */
229
230#endif
231
232/*
233 * Local variables:
234 * tab-width: 4
235 * c-basic-offset: 4
236 * End:
237 * vim600: noet sw=4 ts=4 fdm=marker
238 * vim<600: noet sw=4 ts=4
239 */
240