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