0022815: Missing delete operator for placement new
[occt.git] / src / LDOM / LDOM_BasicElement.cxx
CommitLineData
7fd59977 1// File: LDOM_BasicElement.cxx
2// Created: 26.06.01 21:22:14
3// Author: Alexander GRIGORIEV
4// Copyright: OpenCascade 2001
5// History: AGV 140202: Replace(const char *) for (LDOMBasicString)=>myTagName
6
7#include <LDOM_BasicElement.hxx>
8#include <LDOM_BasicAttribute.hxx>
9#include <LDOM_BasicText.hxx>
10#include <LDOM_MemManager.hxx>
11
7fd59977 12//=======================================================================
13//function : Create
14//purpose : construction in the Document's data pool
15//=======================================================================
16
17LDOM_BasicElement& LDOM_BasicElement::Create
18 (const char * aName,
19 const Standard_Integer aLen,
20 const Handle(LDOM_MemManager)& aDoc)
21{
22 if (aName == NULL) {
23 static LDOM_BasicElement aVoidElement;
24 aVoidElement = LDOM_BasicElement();
25 return aVoidElement;
26 }
27 void * aMem = aDoc -> Allocate (sizeof(LDOM_BasicElement));
28 LDOM_BasicElement * aNewElem = new (aMem) LDOM_BasicElement;
29
30 Standard_Integer aHash;
31// aDoc -> HashedAllocate (aString, strlen(aString), aNewElem -> myTagName);
32 aNewElem -> myTagName = aDoc -> HashedAllocate (aName, aLen, aHash);
33
34 aNewElem -> myNodeType = LDOM_Node::ELEMENT_NODE;
35 return * aNewElem;
36}
37
38//=======================================================================
39//function : RemoveNodes
40//purpose :
41//=======================================================================
42
43void LDOM_BasicElement::RemoveNodes ()
44{
45 const LDOM_BasicNode * aNode = (const LDOM_BasicNode *) myFirstChild;
46 while (aNode) {
47 const LDOM_BasicNode * aNext = aNode -> GetSibling();
48 switch (aNode -> getNodeType ()) {
49 case LDOM_Node::ELEMENT_NODE:
50 {
51 LDOM_BasicElement& anElement = * (LDOM_BasicElement *) aNode;
52 anElement = NULL;
53 break;
54 }
55 case LDOM_Node::ATTRIBUTE_NODE:
56 {
57 LDOM_BasicAttribute& anAttr = * (LDOM_BasicAttribute *) aNode;
58 anAttr = NULL;
59 break;
60 }
61 case LDOM_Node::TEXT_NODE:
62 case LDOM_Node::COMMENT_NODE:
63 case LDOM_Node::CDATA_SECTION_NODE:
64 {
65 LDOM_BasicText& aTxt = * (LDOM_BasicText *) aNode;
66 aTxt = NULL;
67 break;
68 }
69 default: ;
70 }
71 aNode = aNext;
72 }
73 myFirstChild = NULL;
74}
75
76//=======================================================================
77//function : operator =
78//purpose : Nullify
79//=======================================================================
80
81LDOM_BasicElement& LDOM_BasicElement:: operator = (const LDOM_NullPtr * aNull)
82{
83 myTagName = NULL;
84 RemoveNodes ();
85 LDOM_BasicNode::operator= (aNull);
86 return * this;
87}
88
89//=======================================================================
90//function : LDOM_BasicElement
91//purpose : Constructor
92//=======================================================================
93/*
94LDOM_BasicElement::LDOM_BasicElement (const LDOM_Element& anElement)
95 : LDOM_BasicNode (LDOM_Node::ELEMENT_NODE),
96 myAttributeMask (0),
97 myFirstChild (NULL)
98{
99// LDOMString aNewTagName (anElement.getTagName(), anElement.myDocument);
100// myTagName = aNewTagName;
101 const LDOM_BasicElement& anOther =
102 (const LDOM_BasicElement&) anElement.Origin();
103 myTagName = anOther.GetTagName();
104}
105*/
106//=======================================================================
107//function : ~LDOM_BasicElement
108//purpose : Destructor
109//=======================================================================
110
111LDOM_BasicElement::~LDOM_BasicElement ()
112{
113 myTagName = NULL;
114 RemoveNodes ();
115}
116
117//=======================================================================
118//function : GetLastChild
119//purpose :
120//=======================================================================
121
122const LDOM_BasicNode * LDOM_BasicElement::GetLastChild () const
123{
124 const LDOM_BasicNode * aNode = myFirstChild;
125 if (aNode) {
126 if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
127 aNode = NULL;
128 else
129 while (aNode -> mySibling) {
130 if (aNode -> mySibling -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
131 break;
132 aNode = aNode -> mySibling;
133 }
134 }
135 return aNode;
136}
137
138//=======================================================================
139//function : GetAttribute
140//purpose :
141//=======================================================================
142
143const LDOM_BasicAttribute& LDOM_BasicElement::GetAttribute
144 (const LDOMBasicString& aName,
145 const LDOM_BasicNode * aLastCh) const
146{
147 const LDOM_BasicNode * aNode;
148 if (aLastCh)
149 aNode = aLastCh -> GetSibling ();
150 else
151 aNode = myFirstChild;
152 const char * aNameStr = aName.GetString();
153 while (aNode) {
154 if (aNode -> getNodeType () == LDOM_Node::ATTRIBUTE_NODE) {
155 const LDOM_BasicAttribute * anAttr = (const LDOM_BasicAttribute *) aNode;
156 if (!strcmp (aNameStr, anAttr -> GetName()))
157 return * anAttr;
158 }
159 aNode = aNode -> mySibling;
160 }
161static const LDOM_BasicAttribute aNullAttribute;
162 return aNullAttribute;
163}
164
165//=======================================================================
166//function : GetFirstAttribute
167//purpose : private method
168//=======================================================================
169
170const LDOM_BasicAttribute * LDOM_BasicElement::GetFirstAttribute
171 (const LDOM_BasicNode *& theLastCh,
172 const LDOM_BasicNode **& thePrevNode) const
173{
174 // Find the First Attribute as well as the Last Child among siblings
175 const LDOM_BasicNode * aFirstAttr;
176 const LDOM_BasicNode ** aPrevNode;
177 if (theLastCh) {
178 aFirstAttr = theLastCh -> mySibling;
179 aPrevNode = (const LDOM_BasicNode **) &(theLastCh -> mySibling);
180 while (aFirstAttr) {
181 if (aFirstAttr -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE) break;
182 aPrevNode = (const LDOM_BasicNode **) & (aFirstAttr -> mySibling);
183 aFirstAttr = aFirstAttr -> mySibling;
184 }
185 } else {
186 aFirstAttr = myFirstChild;
187 aPrevNode = (const LDOM_BasicNode **) &myFirstChild;
188 while (aFirstAttr) {
189 if (aFirstAttr -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE) break;
190 if (aFirstAttr -> isNull() == Standard_False) theLastCh = aFirstAttr;
191 aPrevNode = (const LDOM_BasicNode **) & (aFirstAttr -> mySibling);
192 aFirstAttr = aFirstAttr -> mySibling;
193 }
194 }
195 thePrevNode = aPrevNode;
196 return (LDOM_BasicAttribute *) aFirstAttr;
197}
198
199//=======================================================================
200//function : AddAttribute
201//purpose : Add or replace an attribute
202//=======================================================================
203
204const LDOM_BasicNode * LDOM_BasicElement::AddAttribute
205 (const LDOMBasicString& anAttrName,
206 const LDOMBasicString& anAttrValue,
207 const Handle(LDOM_MemManager)& aDocument,
208 const LDOM_BasicNode * aLastCh)
209{
210 // Create attribute
211 Standard_Integer aHash;
212 LDOM_BasicAttribute& anAttr =
213 LDOM_BasicAttribute::Create (anAttrName, aDocument, aHash);
214 anAttr.myValue = anAttrValue;
215
216 // Initialize the loop of attribute name search
217 const LDOM_BasicNode ** aPrNode;
218 const LDOM_BasicAttribute * aFirstAttr = GetFirstAttribute (aLastCh, aPrNode);
219 const char * aNameStr = anAttrName.GetString();
220
221 // Check attribute hash value against the current mask
222 const unsigned int anAttrMaskValue = aHash & (8*sizeof(myAttributeMask) - 1);
223 const unsigned long anAttributeMask = (1 << anAttrMaskValue);
224#ifdef DEBUG_MASK
225 anAttributeMask = 0xffffffff;
226#endif
227 if ((myAttributeMask & anAttributeMask) == 0) {
228 // this is new attribute, OK
229 myAttributeMask |= anAttributeMask;
230 * aPrNode = &anAttr;
231 anAttr.SetSibling (aFirstAttr);
232 } else {
233 // this attribute may have already been installed
234 LDOM_BasicAttribute * aCurrentAttr = (LDOM_BasicAttribute *) aFirstAttr;
235 while (aCurrentAttr) {
236 if (aCurrentAttr -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
237 if (LDOM_MemManager::CompareStrings (aNameStr, aHash,
238 aCurrentAttr -> GetName())) {
239 aCurrentAttr -> SetValue (anAttrValue, aDocument);
240 break;
241 }
242 aCurrentAttr = (LDOM_BasicAttribute *) aCurrentAttr -> mySibling;
243 }
244 if (aCurrentAttr == NULL) {
245 // this is new attribute, OK
246 * aPrNode = &anAttr;
247 anAttr.SetSibling (aFirstAttr);
248 }
249 }
250 return aLastCh;
251}
252
253//=======================================================================
254//function : RemoveAttribute
255//purpose : Find and delete an attribute from list
256//=======================================================================
257
258const LDOM_BasicNode * LDOM_BasicElement::RemoveAttribute
259 (const LDOMBasicString& aName,
260 const LDOM_BasicNode * aLastCh) const
261{
262 // Check attribute hash value against the current mask
263 const char * const aNameStr = aName.GetString();
264 const Standard_Integer aHash =
265 LDOM_MemManager::Hash (aNameStr, strlen(aNameStr));
266 const unsigned int anAttrMaskValue = aHash & (8*sizeof(myAttributeMask) - 1);
267 const unsigned long anAttributeMask = (1 << anAttrMaskValue);
268#ifdef DEBUG_MASK
269 anAttributeMask = 0xffffffff;
270#endif
271 if ((myAttributeMask & anAttributeMask) == 0) {
272 ; // maybe cause for exception
273 } else {
274 const LDOM_BasicNode ** aPrevNode; // dummy
275 const LDOM_BasicAttribute * anAttr = GetFirstAttribute (aLastCh, aPrevNode);
276 while (anAttr) {
277 if (anAttr -> getNodeType () == LDOM_Node::ATTRIBUTE_NODE)
278 if (LDOM_MemManager::CompareStrings(aNameStr,aHash,anAttr->GetName())) {
279 anAttr = NULL;
280 break;
281 }
282 anAttr = (const LDOM_BasicAttribute *) anAttr -> mySibling;
283 }
284 }
285 return aLastCh;
286}
287
288//=======================================================================
289//function : RemoveChild
290//purpose :
291//=======================================================================
292
293void LDOM_BasicElement::RemoveChild (const LDOM_BasicNode * aChild) const
294{
295 const LDOM_BasicNode * aNode = myFirstChild;
296 const LDOM_BasicNode ** aPrevNode = (const LDOM_BasicNode **) &myFirstChild;
297 while (aNode) {
298 if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
299 break;
300 if (aNode == aChild) {
301 * aPrevNode = aNode -> GetSibling();
302 * (LDOM_BasicNode *) aChild = NULL;
303 break;
304 }
305 aPrevNode = (const LDOM_BasicNode **) & (aNode -> mySibling);
306 aNode = aNode -> GetSibling();
307 }
308 // here may be the cause to throw an exception
309}
310
311//=======================================================================
312//function : AppendChild
313//purpose :
314//=======================================================================
315
316void LDOM_BasicElement::AppendChild (const LDOM_BasicNode * aChild,
317 const LDOM_BasicNode *& aLastChild) const
318{
319 if (aLastChild) {
320 (const LDOM_BasicNode *&) aChild -> mySibling = aLastChild -> mySibling;
321 (const LDOM_BasicNode *&) aLastChild -> mySibling = aChild;
322 } else {
323 const LDOM_BasicNode * aNode = myFirstChild;
324 const LDOM_BasicNode ** aPrevNode = (const LDOM_BasicNode **) &myFirstChild;
325 while (aNode) {
326 if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE) {
327 (const LDOM_BasicNode *&) aChild -> mySibling = aNode;
328 break;
329 }
330 aPrevNode = (const LDOM_BasicNode **) & (aNode -> mySibling);
331 aNode = aNode -> mySibling;
332 }
333 * aPrevNode = aChild;
334 }
335 aLastChild = aChild;
336}
337
338//=======================================================================
339//function : AddElementsByTagName
340//purpose : Add to the List all sub-elements with the given name (recursive)
341//=======================================================================
342
343void LDOM_BasicElement::AddElementsByTagName
344 (LDOM_NodeList& aList, const LDOMBasicString& aTagName) const
345{
346 const LDOM_BasicNode * aNode = myFirstChild;
347 const char * aTagString = aTagName.GetString();
348 while (aNode) {
349 if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
350 break;
351 if (aNode -> getNodeType() == LDOM_Node::ELEMENT_NODE) {
352 LDOM_BasicElement& anElement = * (LDOM_BasicElement *) aNode;
353// if (anElement.GetTagName().equals(aTagName))
354 if (strcmp (anElement.GetTagName(), aTagString) == 0)
355 aList.Append (anElement);
356 anElement.AddElementsByTagName (aList, aTagName);
357 }
358 aNode = aNode -> GetSibling();
359 }
360}
361
362//=======================================================================
363//function : AddAttributes
364//purpose :
365//=======================================================================
366
367void LDOM_BasicElement::AddAttributes (LDOM_NodeList& aList,
368 const LDOM_BasicNode * aLastChild) const
369{
370 const LDOM_BasicNode * aBNode;
371 if (aLastChild)
372 aBNode = aLastChild -> GetSibling();
373 else
374 aBNode = GetFirstChild();
375 while (aBNode) {
376 if (aBNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
377 aList.Append (* aBNode);
378 aBNode = aBNode -> GetSibling();
379 }
380}
381
382//=======================================================================
383//function : ReplaceElement
384//purpose : Copy data and children into this node from another one
385// The only preserved data is mySibling
386//=======================================================================
387
388void LDOM_BasicElement::ReplaceElement
389 (const LDOM_BasicElement& anOtherElem,
390 const Handle(LDOM_MemManager)& aDocument)
391{
392 myTagName = anOtherElem.GetTagName();
393 myAttributeMask = anOtherElem.myAttributeMask;
394 myFirstChild = NULL;
395 const LDOM_BasicNode * aBNode = anOtherElem.GetFirstChild ();
396 const LDOM_BasicNode * aLastChild = NULL;
397
398 // Loop on children (non-attributes)
399 for (; aBNode != NULL; aBNode = aBNode -> GetSibling()) {
400 if (aBNode -> isNull())
401 continue;
402 LDOM_BasicNode * aNewBNode;
403 const LDOM_Node::NodeType aNewNodeType = aBNode -> getNodeType();
404 switch (aNewNodeType) {
405 case LDOM_Node::ELEMENT_NODE:
406 {
407 const LDOM_BasicElement& aBNodeElem = *(const LDOM_BasicElement*)aBNode;
408 const char * aTagString = aBNodeElem.GetTagName();
409 LDOM_BasicElement& aNewBNodeElem =
410 LDOM_BasicElement::Create (aTagString, strlen(aTagString), aDocument);
411 aNewBNodeElem.ReplaceElement (aBNodeElem, aDocument); //reccur
412 aNewBNode = &aNewBNodeElem;
413 break;
414 }
415 case LDOM_Node::ATTRIBUTE_NODE:
416 goto loop_attr;
417 case LDOM_Node::TEXT_NODE:
418 case LDOM_Node::COMMENT_NODE:
419 case LDOM_Node::CDATA_SECTION_NODE:
420 {
421 const LDOM_BasicText& aBNodeText = * (const LDOM_BasicText *) aBNode;
422 aNewBNode = &LDOM_BasicText::Create (aNewNodeType,
423 LDOMString(aBNodeText.GetData(),
424 aDocument),
425 aDocument);
426 break;
427 }
428 default: continue;
429 }
430 if (GetFirstChild())
431 (const LDOM_BasicNode *&) aLastChild -> mySibling = aNewBNode;
432 else
433 (const LDOM_BasicNode *&) myFirstChild = aNewBNode;
434 (const LDOM_BasicNode *&) aLastChild = aNewBNode;
435 }
436
437 // Loop on attributes (in the end of the list of children)
438loop_attr:
439 LDOM_BasicNode * aLastAttr = (LDOM_BasicNode *) aLastChild;
440 for (; aBNode != NULL; aBNode = aBNode -> GetSibling()) {
441 Standard_Integer aHash;
442 if (aBNode -> isNull()) continue;
443 const LDOM_BasicAttribute * aBNodeAtt= (const LDOM_BasicAttribute *) aBNode;
444 LDOM_BasicAttribute * aNewAtt =
445 &LDOM_BasicAttribute::Create (aBNodeAtt -> GetName(), aDocument, aHash);
446 aNewAtt -> SetValue (aBNodeAtt->myValue, aDocument);
447 if (aLastAttr)
448 aLastAttr -> SetSibling (aNewAtt);
449 else
450 myFirstChild = aNewAtt;
451 aLastAttr = aNewAtt;
452 }
453}