source: icXML/icXML-devel/src/xercesc/dom/impl/DOMCDATASectionImpl.cpp @ 2777

Last change on this file since 2777 was 2777, checked in by cameron, 7 years ago

Set up to use xercesc/icxercesc root-relative paths for all includes

File size: 15.4 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: DOMCDATASectionImpl.cpp 678709 2008-07-22 10:56:56Z borisk $
20 */
21
22#include <xercesc/dom/impl/DOMCDATASectionImpl.hpp>
23#include <icxercesc/dom/impl/DOMNodeImpl.hpp>
24#include <xercesc/dom/impl/DOMRangeImpl.hpp>
25#include <xercesc/dom/impl/DOMDocumentImpl.hpp>
26#include <xercesc/dom/impl/DOMCasts.hpp>
27#include <xercesc/dom/impl/DOMStringPool.hpp>
28#include <xercesc/dom/DOMException.hpp>
29#include <xercesc/dom/DOMNodeFilter.hpp>
30#include <xercesc/dom/DOMTreeWalker.hpp>
31#include <xercesc/util/XMLUniDefs.hpp>
32
33XERCES_CPP_NAMESPACE_BEGIN
34
35DOMCDATASectionImpl::DOMCDATASectionImpl(DOMDocument *ownerDoc,
36                                   const XMLCh *dat)
37    : fNode(ownerDoc), fCharacterData(ownerDoc, dat)
38{
39    fNode.setIsLeafNode(true);
40}
41
42DOMCDATASectionImpl::
43DOMCDATASectionImpl(DOMDocument *ownerDoc, const XMLCh* data, XMLSize_t n)
44    : fNode(ownerDoc), fCharacterData(ownerDoc, data, n)
45{
46    fNode.setIsLeafNode(true);
47}
48
49DOMCDATASectionImpl::DOMCDATASectionImpl(const DOMCDATASectionImpl &other, bool /*deep*/)
50    : DOMCDATASection(other),
51    fNode(*castToNodeImpl(&other)),
52    fChild(*castToChildImpl(&other)),
53    fCharacterData(other.fCharacterData)
54{
55    // revisit.  Something nees to make "deep" work.
56}
57
58
59DOMCDATASectionImpl::~DOMCDATASectionImpl()
60{
61}
62
63
64DOMNode  *DOMCDATASectionImpl::cloneNode(bool deep) const
65{
66    DOMNode* newNode = new (this->getOwnerDocument(), DOMMemoryManager::CDATA_SECTION_OBJECT) DOMCDATASectionImpl(*this, deep);
67    fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
68    return newNode;
69}
70
71
72const XMLCh * DOMCDATASectionImpl::getNodeName() const {
73    static const XMLCh gcdata_section[] = {chPound, chLatin_c, chLatin_d, chLatin_a, chLatin_t, chLatin_a,
74        chDash, chLatin_s, chLatin_e, chLatin_c, chLatin_t, chLatin_i, chLatin_o, chLatin_n, 0};
75    return gcdata_section;
76}
77
78
79DOMNode::NodeType DOMCDATASectionImpl::getNodeType() const {
80    return DOMNode::CDATA_SECTION_NODE;
81}
82
83
84bool DOMCDATASectionImpl::isIgnorableWhitespace() const
85{
86    return fNode.ignorableWhitespace();
87}
88
89
90//
91//  splitText.   revist - factor into a common function for use
92//                             here and in DOMTextImpl
93//
94DOMText *DOMCDATASectionImpl::splitText(XMLSize_t offset)
95{
96    if (fNode.isReadOnly())
97    {
98        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
99    }
100    XMLSize_t len = fCharacterData.fDataBuf->getLen();
101    if (offset > len)
102        throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMNodeMemoryManager);
103
104    DOMDocumentImpl *doc = (DOMDocumentImpl *)getOwnerDocument();
105    DOMText *newText =
106      doc->createCDATASection(this->substringData(offset, len - offset));
107
108    DOMNode *parent = getParentNode();
109    if (parent != 0)
110        parent->insertBefore(newText, getNextSibling());
111
112    fCharacterData.fDataBuf->chop(offset);
113
114    if (doc != 0) {
115        Ranges* ranges = doc->getRanges();
116        if (ranges != 0) {
117            XMLSize_t sz = ranges->size();
118            if (sz != 0) {
119                for (XMLSize_t i =0; i<sz; i++) {
120                    ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
121                }
122            }
123        }
124    }
125
126    return newText;
127}
128
129
130bool DOMCDATASectionImpl::getIsElementContentWhitespace() const
131{
132    return isIgnorableWhitespace();
133}
134
135const XMLCh* DOMCDATASectionImpl::getWholeText() const
136{
137    DOMDocument *doc = getOwnerDocument();
138    DOMTreeWalker* pWalker=doc->createTreeWalker(doc->getDocumentElement(), DOMNodeFilter::SHOW_ALL, NULL, true);
139    pWalker->setCurrentNode((DOMNode*)this);
140    // Logically-adjacent text nodes are Text or CDATASection nodes that can be visited sequentially in document order or in
141    // reversed document order without entering, exiting, or passing over Element, Comment, or ProcessingInstruction nodes.
142        DOMNode* prevNode;
143    while((prevNode=pWalker->previousNode())!=NULL)
144    {
145        if(prevNode->getNodeType()==ELEMENT_NODE || prevNode->getNodeType()==COMMENT_NODE || prevNode->getNodeType()==PROCESSING_INSTRUCTION_NODE)
146            break;
147    }
148        XMLBuffer buff(1023, GetDOMNodeMemoryManager);
149        DOMNode* nextNode;
150    while((nextNode=pWalker->nextNode())!=NULL)
151    {
152        if(nextNode->getNodeType()==ELEMENT_NODE || nextNode->getNodeType()==COMMENT_NODE || nextNode->getNodeType()==PROCESSING_INSTRUCTION_NODE)
153            break;
154        if(nextNode->getNodeType()==TEXT_NODE || nextNode->getNodeType()==CDATA_SECTION_NODE)
155                buff.append(nextNode->getNodeValue());
156    }
157    pWalker->release();
158
159    XMLCh* wholeString = (XMLCh*) (GetDOMNodeMemoryManager->allocate((buff.getLen()+1)*sizeof(XMLCh)));
160        XMLString::copyString(wholeString, buff.getRawBuffer());
161        return wholeString;
162}
163
164DOMText* DOMCDATASectionImpl::replaceWholeText(const XMLCh* newText)
165{
166    DOMDocument *doc = getOwnerDocument();
167    DOMTreeWalker* pWalker=doc->createTreeWalker(doc->getDocumentElement(), DOMNodeFilter::SHOW_ALL, NULL, true);
168    pWalker->setCurrentNode((DOMNode*)this);
169    // Logically-adjacent text nodes are Text or CDATASection nodes that can be visited sequentially in document order or in
170    // reversed document order without entering, exiting, or passing over Element, Comment, or ProcessingInstruction nodes.
171    DOMNode* pFirstTextNode=this;
172        DOMNode* prevNode;
173    while((prevNode=pWalker->previousNode())!=NULL)
174    {
175        if(prevNode->getNodeType()==ELEMENT_NODE || prevNode->getNodeType()==COMMENT_NODE || prevNode->getNodeType()==PROCESSING_INSTRUCTION_NODE)
176            break;
177        pFirstTextNode=prevNode;
178    }
179    // before doing any change we need to check if we are going to remove an entity reference that doesn't contain just text
180    DOMNode* pCurrentNode=pWalker->getCurrentNode();
181        DOMNode* nextNode;
182    while((nextNode=pWalker->nextNode())!=NULL)
183    {
184        if(nextNode->getNodeType()==ELEMENT_NODE || nextNode->getNodeType()==COMMENT_NODE || nextNode->getNodeType()==PROCESSING_INSTRUCTION_NODE)
185            break;
186        if(nextNode->getNodeType()==ENTITY_REFERENCE_NODE)
187        {
188            DOMTreeWalker* pInnerWalker=doc->createTreeWalker(nextNode, DOMNodeFilter::SHOW_ALL, NULL, true);
189            while(pInnerWalker->nextNode())
190            {
191                short nodeType=pInnerWalker->getCurrentNode()->getNodeType();
192                if(nodeType!=ENTITY_REFERENCE_NODE && nodeType!=TEXT_NODE && nodeType!=CDATA_SECTION_NODE)
193                    throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNodeMemoryManager);
194            }
195            pInnerWalker->release();
196        }
197    }
198    DOMText* retVal=NULL;
199    // if the first node in the chain is a text node, replace its content, otherwise create a new node
200    if(newText && *newText)
201    {
202        if(!castToNodeImpl(pFirstTextNode)->isReadOnly() && (pFirstTextNode->getNodeType()==TEXT_NODE || pFirstTextNode->getNodeType()==CDATA_SECTION_NODE))
203        {
204            pFirstTextNode->setNodeValue(newText);
205            retVal=(DOMText*)pFirstTextNode;
206        }
207        else
208        {
209            if(getNodeType()==TEXT_NODE)
210                retVal=doc->createTextNode(newText);
211            else
212                retVal=doc->createCDATASection(newText);
213            pFirstTextNode->getParentNode()->insertBefore(retVal, pFirstTextNode);
214        }
215    }
216    // now delete all the following text nodes
217    pWalker->setCurrentNode(pCurrentNode);
218    while((nextNode=pWalker->nextNode())!=NULL)
219    {
220        if(nextNode->getNodeType()==ELEMENT_NODE || nextNode->getNodeType()==COMMENT_NODE || nextNode->getNodeType()==PROCESSING_INSTRUCTION_NODE)
221            break;
222        if(nextNode!=retVal)
223        {
224            // keep the tree walker valid
225            pWalker->previousNode();
226            nextNode->getParentNode()->removeChild(nextNode);
227            nextNode->release();
228        }
229    }
230    pWalker->release();
231    return retVal;
232}
233
234
235void DOMCDATASectionImpl::release()
236{
237    if (fNode.isOwned() && !fNode.isToBeReleased())
238        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
239
240    DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
241
242    if (doc) {
243        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
244        fCharacterData.releaseBuffer();
245        doc->release(this, DOMMemoryManager::CDATA_SECTION_OBJECT);
246    }
247    else {
248        // shouldn't reach here
249        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
250    }
251}
252
253
254//
255//  Delegation stubs for other DOM_Node inherited functions.
256//
257           DOMNode*         DOMCDATASectionImpl::appendChild(DOMNode *newChild)          {return fNode.appendChild (newChild); }
258           DOMNamedNodeMap* DOMCDATASectionImpl::getAttributes() const                   {return fNode.getAttributes (); }
259           DOMNodeList*     DOMCDATASectionImpl::getChildNodes() const                   {return fNode.getChildNodes (); }
260           DOMNode*         DOMCDATASectionImpl::getFirstChild() const                   {return fNode.getFirstChild (); }
261           DOMNode*         DOMCDATASectionImpl::getLastChild() const                    {return fNode.getLastChild (); }
262     const XMLCh*           DOMCDATASectionImpl::getLocalName() const                    {return fNode.getLocalName (); }
263     const XMLCh*           DOMCDATASectionImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); }
264           DOMNode*         DOMCDATASectionImpl::getNextSibling() const                  {return fChild.getNextSibling (); }
265     const XMLCh*           DOMCDATASectionImpl::getNodeValue() const                    {return fCharacterData.getNodeValue (); }
266           DOMDocument*     DOMCDATASectionImpl::getOwnerDocument() const                {return fNode.getOwnerDocument(); }
267     const XMLCh*           DOMCDATASectionImpl::getPrefix() const                       {return fNode.getPrefix (); }
268           DOMNode*         DOMCDATASectionImpl::getParentNode() const                   {return fChild.getParentNode (this); }
269           DOMNode*         DOMCDATASectionImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); }
270           bool             DOMCDATASectionImpl::hasChildNodes() const                   {return fNode.hasChildNodes (); }
271           DOMNode*         DOMCDATASectionImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
272                                                                                         {return fNode.insertBefore (newChild, refChild); }
273           void             DOMCDATASectionImpl::normalize()                             {fNode.normalize (); }
274           DOMNode*         DOMCDATASectionImpl::removeChild(DOMNode *oldChild)          {return fNode.removeChild (oldChild); }
275           DOMNode*         DOMCDATASectionImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
276                                                                                         {return fNode.replaceChild (newChild, oldChild); }
277           bool             DOMCDATASectionImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
278                                                                                         {return fNode.isSupported (feature, version); }
279           void             DOMCDATASectionImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); }
280           bool             DOMCDATASectionImpl::hasAttributes() const                   {return fNode.hasAttributes(); }
281           bool             DOMCDATASectionImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); }
282           bool             DOMCDATASectionImpl::isEqualNode(const DOMNode* arg) const   {return fNode.isEqualNode(arg); }
283           void*            DOMCDATASectionImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
284                                                                                         {return fNode.setUserData(key, data, handler); }
285           void*            DOMCDATASectionImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); }
286           const XMLCh*     DOMCDATASectionImpl::getBaseURI() const                      {return fNode.getBaseURI(); }
287           short            DOMCDATASectionImpl::compareDocumentPosition(const DOMNode* other) const {return fNode.compareDocumentPosition(other); }
288           const XMLCh*     DOMCDATASectionImpl::getTextContent() const                  {return fNode.getTextContent(); }
289           void             DOMCDATASectionImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); }
290           const XMLCh*     DOMCDATASectionImpl::lookupPrefix(const XMLCh* namespaceURI) const  {return fNode.lookupPrefix(namespaceURI); }
291           bool             DOMCDATASectionImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); }
292           const XMLCh*     DOMCDATASectionImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); }
293           void*            DOMCDATASectionImpl::getFeature(const XMLCh* feature, const XMLCh* version) const {return fNode.getFeature(feature, version); }
294
295
296
297//
298//   Delegation of CharacerData functions.
299//
300
301
302           const XMLCh*     DOMCDATASectionImpl::getData() const                         {return fCharacterData.getData();}
303           XMLSize_t        DOMCDATASectionImpl::getLength() const                       {return fCharacterData.getLength();}
304           const XMLCh*     DOMCDATASectionImpl::substringData(XMLSize_t offset, XMLSize_t count) const
305                                                                                         {return fCharacterData.substringData(this, offset, count);}
306           void             DOMCDATASectionImpl::appendData(const XMLCh *arg)            {fCharacterData.appendData(this, arg);}
307           void             DOMCDATASectionImpl::insertData(XMLSize_t offset, const  XMLCh *arg)
308                                                                                         {fCharacterData.insertData(this, offset, arg);}
309           void             DOMCDATASectionImpl::deleteData(XMLSize_t offset, XMLSize_t count)
310                                                                                         {fCharacterData.deleteData(this, offset, count);}
311           void             DOMCDATASectionImpl::replaceData(XMLSize_t offset, XMLSize_t count, const XMLCh *arg)
312                                                                                         {fCharacterData.replaceData(this, offset, count, arg);}
313           void             DOMCDATASectionImpl::setData(const XMLCh *data)              {fCharacterData.setData(this, data);}
314           void             DOMCDATASectionImpl::setNodeValue(const XMLCh  *nodeValue)   {fCharacterData.setNodeValue (this, nodeValue); }
315
316XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.