source: icXML/icXML-devel/src/xercesc/dom/impl/DOMNamedNodeMapImpl.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 11.8 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: DOMNamedNodeMapImpl.cpp 678381 2008-07-21 10:15:01Z borisk $
20 */
21
22
23#include <xercesc/dom/DOMAttr.hpp>
24#include <xercesc/dom/DOMException.hpp>
25#include <icxercesc/framework/XMLBuffer.hpp>
26#include <xercesc/util/XMLUniDefs.hpp>
27
28#include "DOMNodeVector.hpp"
29#include "DOMNamedNodeMapImpl.hpp"
30#include "DOMCasts.hpp"
31#include "DOMDocumentImpl.hpp"
32#include "DOMNodeImpl.hpp"
33
34XERCES_CPP_NAMESPACE_BEGIN
35
36DOMNamedNodeMapImpl::DOMNamedNodeMapImpl(DOMNode *ownerNod)
37{
38    fOwnerNode=ownerNod;
39    memset(fBuckets,0,MAP_SIZE*sizeof(DOMNodeVector*));
40}
41
42DOMNamedNodeMapImpl::~DOMNamedNodeMapImpl()
43{
44}
45
46bool DOMNamedNodeMapImpl::readOnly()
47{
48    return castToNodeImpl(fOwnerNode)->isReadOnly();
49}
50
51DOMNamedNodeMapImpl *DOMNamedNodeMapImpl::cloneMap(DOMNode *ownerNod)
52{
53    DOMDocumentImpl *doc = (DOMDocumentImpl *)(castToNodeImpl(ownerNod)->getOwnerDocument());
54    DOMNamedNodeMapImpl *newmap = new (doc) DOMNamedNodeMapImpl(ownerNod);
55
56    for(XMLSize_t index=0;index<MAP_SIZE;index++)
57        if (fBuckets[index] != 0) {
58            XMLSize_t size=fBuckets[index]->size();
59            newmap->fBuckets[index] = new (doc) DOMNodeVector(doc, size);
60            for (XMLSize_t i = 0; i < size; ++i) {
61                DOMNode *s = fBuckets[index]->elementAt(i);
62                DOMNode *n = s->cloneNode(true);
63                            castToNodeImpl(n)->isSpecified(castToNodeImpl(s)->isSpecified());
64                castToNodeImpl(n)->fOwnerNode = ownerNod;
65                castToNodeImpl(n)->isOwned(true);
66                newmap->fBuckets[index]->addElement(n);
67            }
68        }
69
70    return newmap;
71}
72
73
74XMLSize_t DOMNamedNodeMapImpl::getLength() const
75{
76    XMLSize_t count=0;
77    for(XMLSize_t index=0;index<MAP_SIZE;index++)
78        count+=(fBuckets[index]==0?0:fBuckets[index]->size());
79    return count;
80}
81
82DOMNode * DOMNamedNodeMapImpl::item(XMLSize_t index) const
83{
84    XMLSize_t count=0;
85    for(XMLSize_t i=0;i<MAP_SIZE;i++) {
86        if(fBuckets[i]==0)
87            continue;
88        XMLSize_t thisBucket=fBuckets[i]->size();
89        if(index>=count && index<(count+thisBucket))
90            return fBuckets[i]->elementAt(index-count);
91        count+=thisBucket;
92    }
93    return NULL;
94}
95
96
97DOMNode * DOMNamedNodeMapImpl::getNamedItem(const XMLCh *name) const
98{
99    XMLSize_t hash=XMLString::hash(name,MAP_SIZE);
100    if(fBuckets[hash]==0)
101        return 0;
102
103    XMLSize_t i = 0;
104    XMLSize_t size = fBuckets[hash]->size();
105    for (i = 0; i < size; ++i) {
106        DOMNode *n=fBuckets[hash]->elementAt(i);
107        if(XMLString::equals(name,n->getNodeName()))
108            return n;
109    }
110
111    return 0;
112}
113
114
115//
116// removeNamedItem() - Remove the named item, and return it.
117//                      The caller can release the
118//                      returned item if it's not used
119//                      we can't do it here because the caller would
120//                      never see the returned node.
121//
122DOMNode * DOMNamedNodeMapImpl::removeNamedItem(const XMLCh *name)
123{
124    if (this->readOnly())
125        throw DOMException(
126            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
127
128    XMLSize_t hash=XMLString::hash(name,MAP_SIZE);
129    if(fBuckets[hash]==0)
130        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);
131
132    DOMDocument *doc = fOwnerNode->getOwnerDocument();
133
134    XMLSize_t i = 0;
135    XMLSize_t size = fBuckets[hash]->size();
136    for (i = 0; i < size; ++i) {
137        DOMNode *n=fBuckets[hash]->elementAt(i);
138        if(XMLString::equals(name,n->getNodeName())) {
139            fBuckets[hash]->removeElementAt(i);
140            castToNodeImpl(n)->fOwnerNode = doc;
141            castToNodeImpl(n)->isOwned(false);
142            return n;
143        }
144    }
145
146    throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);
147    return 0;
148}
149
150
151
152//
153// setNamedItem()  Put the item into the NamedNodeList by name.
154//                  If an item with the same name already was
155//                  in the list, replace it.  Return the old
156//                  item, if there was one.
157//                  Caller is responsible for arranging for
158//                  deletion of the old item if its ref count is
159//                  zero.
160//
161DOMNode * DOMNamedNodeMapImpl::setNamedItem(DOMNode * arg)
162{
163    DOMDocument *doc = fOwnerNode->getOwnerDocument();
164    DOMNodeImpl *argImpl = castToNodeImpl(arg);
165    if(argImpl->getOwnerDocument() != doc)
166        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0, GetDOMNamedNodeMapMemoryManager);
167    if (this->readOnly())
168        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
169    if ((arg->getNodeType() == DOMNode::ATTRIBUTE_NODE) && argImpl->isOwned() && (argImpl->fOwnerNode != fOwnerNode))
170        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);
171
172    argImpl->fOwnerNode = fOwnerNode;
173    argImpl->isOwned(true);
174
175    const XMLCh* name=arg->getNodeName();
176    XMLSize_t hash=XMLString::hash(name,MAP_SIZE);
177    if(fBuckets[hash]==0)
178        fBuckets[hash] = new (doc) DOMNodeVector(doc, 3);
179
180    XMLSize_t i = 0;
181    XMLSize_t size = fBuckets[hash]->size();
182    for (i = 0; i < size; ++i) {
183        DOMNode *n=fBuckets[hash]->elementAt(i);
184        if(XMLString::equals(name,n->getNodeName())) {
185            fBuckets[hash]->setElementAt(arg,i);
186            castToNodeImpl(n)->fOwnerNode = doc;
187            castToNodeImpl(n)->isOwned(false);
188            return n;
189        }
190    }
191    fBuckets[hash]->addElement(arg);
192    return 0;
193}
194
195
196void DOMNamedNodeMapImpl::setReadOnly(bool readOnl, bool deep)
197{
198    // this->fReadOnly=readOnl;
199    if(deep) {
200        for (XMLSize_t index = 0; index < MAP_SIZE; index++) {
201            if(fBuckets[index]==0)
202                continue;
203            XMLSize_t sz = fBuckets[index]->size();
204            for (XMLSize_t i=0; i<sz; ++i)
205                castToNodeImpl(fBuckets[index]->elementAt(i))->setReadOnly(readOnl, deep);
206        }
207    }
208}
209
210
211//Introduced in DOM Level 2
212
213DOMNode *DOMNamedNodeMapImpl::getNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName) const
214{
215    // the map is indexed using the full name of nodes; to search given a namespace and a local name
216    // we have to do a linear search
217    for (XMLSize_t index = 0; index < MAP_SIZE; index++) {
218        if(fBuckets[index]==0)
219            continue;
220
221        XMLSize_t i = 0;
222        XMLSize_t size = fBuckets[index]->size();
223        for (i = 0; i < size; ++i) {
224            DOMNode *n=fBuckets[index]->elementAt(i);
225            const XMLCh * nNamespaceURI = n->getNamespaceURI();
226            const XMLCh * nLocalName = n->getLocalName();
227            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
228                continue;
229            else {
230                if (XMLString::equals(localName, nLocalName)
231                    ||
232                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName())))
233                    return n;
234            }
235        }
236    }
237    return 0;
238}
239
240
241//
242// setNamedItemNS()  Put the item into the NamedNodeList by name.
243//                  If an item with the same name already was
244//                  in the list, replace it.  Return the old
245//                  item, if there was one.
246//                  Caller is responsible for arranging for
247//                  deletion of the old item if its ref count is
248//                  zero.
249//
250DOMNode * DOMNamedNodeMapImpl::setNamedItemNS(DOMNode *arg)
251{
252    DOMDocument *doc = fOwnerNode->getOwnerDocument();
253    DOMNodeImpl *argImpl = castToNodeImpl(arg);
254    if (argImpl->getOwnerDocument() != doc)
255        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0, GetDOMNamedNodeMapMemoryManager);
256    if (this->readOnly())
257        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
258    if (argImpl->isOwned())
259        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0, GetDOMNamedNodeMapMemoryManager);
260
261    argImpl->fOwnerNode = fOwnerNode;
262    argImpl->isOwned(true);
263
264    const XMLCh* namespaceURI=arg->getNamespaceURI();
265    const XMLCh* localName=arg->getLocalName();
266    // the map is indexed using the full name of nodes; to search given a namespace and a local name
267    // we have to do a linear search
268    for (XMLSize_t index = 0; index < MAP_SIZE; index++) {
269        if(fBuckets[index]==0)
270            continue;
271
272        XMLSize_t i = 0;
273        XMLSize_t size = fBuckets[index]->size();
274        for (i = 0; i < size; ++i) {
275            DOMNode *n=fBuckets[index]->elementAt(i);
276            const XMLCh * nNamespaceURI = n->getNamespaceURI();
277            const XMLCh * nLocalName = n->getLocalName();
278            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
279                continue;
280            else {
281                if (XMLString::equals(localName, nLocalName)
282                    ||
283                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName()))) {
284                    fBuckets[index]->setElementAt(arg,i);
285                    castToNodeImpl(n)->fOwnerNode = doc;
286                    castToNodeImpl(n)->isOwned(false);
287                    return n;
288                }
289            }
290        }
291    }
292    // if not found, add it using the full name as key
293    return setNamedItem(arg);
294}
295
296
297// removeNamedItemNS() - Remove the named item, and return it.
298//                      The caller can release the
299//                      returned item if it's not used
300//                      we can't do it here because the caller would
301//                      never see the returned node.
302DOMNode *DOMNamedNodeMapImpl::removeNamedItemNS(const XMLCh *namespaceURI,
303                                                 const XMLCh *localName)
304{
305    if (this->readOnly())
306        throw DOMException(
307        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMNamedNodeMapMemoryManager);
308
309    // the map is indexed using the full name of nodes; to search given a namespace and a local name
310    // we have to do a linear search
311    for (XMLSize_t index = 0; index < MAP_SIZE; index++) {
312        if(fBuckets[index]==0)
313            continue;
314
315        DOMDocument *doc = fOwnerNode->getOwnerDocument();
316        XMLSize_t i = 0;
317        XMLSize_t size = fBuckets[index]->size();
318        for (i = 0; i < size; ++i) {
319            DOMNode *n=fBuckets[index]->elementAt(i);
320            const XMLCh * nNamespaceURI = n->getNamespaceURI();
321            const XMLCh * nLocalName = n->getLocalName();
322            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
323                continue;
324            else {
325                if (XMLString::equals(localName, nLocalName)
326                    ||
327                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName()))) {
328                    fBuckets[index]->removeElementAt(i);
329                    castToNodeImpl(n)->fOwnerNode = doc;
330                    castToNodeImpl(n)->isOwned(false);
331                    return n;
332                }
333            }
334        }
335    }
336    throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMNamedNodeMapMemoryManager);
337    return 0;
338}
339
340XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.