0023392: Memory leak in OCAF in debug mode
[occt.git] / src / TDF / TDF_LabelNode.cxx
1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1997-1999 Matra Datavision
3 // Copyright (c) 1999-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 #include <TDF_LabelNode.hxx>
21
22 #include <TDF_Data.hxx>
23 #include <TDF_Label.hxx>
24
25 //=======================================================================
26 //function : TDF_LabelNode
27 //purpose  : Constructor with TDF_Data*, only used for root node.
28 //=======================================================================
29
30 TDF_LabelNode::TDF_LabelNode
31 (TDF_Data* aDataPtr)
32 : myFather          (NULL), // The sign it is the root.
33 #ifdef KEEP_LOCAL_ROOT
34   myBrother         (NULL),
35 #else
36   myBrother         ((TDF_LabelNode *)aDataPtr),
37 #endif
38   myFirstChild      (NULL),
39   myLastFoundChild  (NULL), //jfa 10.01.2003
40   myTag             (0), // Always 0 for root.
41   myFlags           (0),
42 #ifdef KEEP_LOCAL_ROOT
43   myData            (aDataPtr)
44 #endif
45 {
46 #ifdef DEB
47   myDebugEntry = '0';
48 #endif
49 }
50
51
52 //=======================================================================
53 //function : TDF_LabelNode
54 //purpose  : Constructor
55 //=======================================================================
56
57 TDF_LabelNode::TDF_LabelNode
58 (const Standard_Integer aTag, TDF_LabelNode* aFather)
59 : myFather          (aFather),
60   myBrother         (NULL),
61   myFirstChild      (NULL),
62   myLastFoundChild  (NULL), //jfa 10.01.2003
63   myTag             (aTag),
64   myFlags           (0),
65 #ifdef KEEP_LOCAL_ROOT
66   myData            (NULL)
67 #endif
68 {
69   if (aFather != NULL) {
70     Depth(aFather->Depth() + 1);
71 #ifdef KEEP_LOCAL_ROOT
72     myData = aFather -> Data();
73 #endif
74   }
75 #ifdef DEB
76   myDebugEntry = myFather->myDebugEntry;
77   myDebugEntry += ':';
78   myDebugEntry += aTag;
79 #endif
80 }
81
82 //=======================================================================
83 //function : Destroy
84 //purpose  : 
85 //=======================================================================
86
87 void TDF_LabelNode::Destroy (const TDF_HAllocator& theAllocator)
88 {
89   // MSV 21.03.2003: do not delete brother, rather delete all children in a loop
90   //                 to avoid stack overflow
91   while (myFirstChild != NULL) {
92     TDF_LabelNode* aSecondChild = myFirstChild->Brother();
93     myFirstChild->Destroy (theAllocator);
94     myFirstChild = aSecondChild;
95   }
96   this->~TDF_LabelNode();
97   myFather = myBrother = myFirstChild = myLastFoundChild = NULL;
98   myTag = myFlags = 0;
99
100   // deallocate memory (does nothing for IncAllocator)
101   theAllocator->Free (this);
102 }
103
104 //=======================================================================
105 //function : AddAttribute
106 //purpose  : Adds an attribute at the first or the specified position.
107 //=======================================================================
108
109 void TDF_LabelNode::AddAttribute
110 (const Handle(TDF_Attribute)& afterAtt,
111  const Handle(TDF_Attribute)& newAtt)
112 {
113   newAtt->myFlags = 1; // Valid.
114   newAtt->myLabelNode  = this;
115   if (afterAtt.IsNull()) { // Inserts at beginning.
116     newAtt->myNext   = myFirstAttribute;
117     myFirstAttribute = newAtt;
118   }
119   else { // Inserts at specified place.
120     newAtt->myNext   = afterAtt->myNext;
121     afterAtt->myNext = newAtt;
122   }
123 }
124
125
126 //=======================================================================
127 //function : RemoveAttribute
128 //purpose  : Removes an attribute from the first or the specified position.
129 //=======================================================================
130
131 void TDF_LabelNode::RemoveAttribute
132 (const Handle(TDF_Attribute)& afterAtt,
133  const Handle(TDF_Attribute)& oldAtt)
134 {
135   oldAtt->myFlags = 0; // Unvalid.
136   oldAtt->myLabelNode  = NULL;
137   if (afterAtt.IsNull()) { // Removes from beginning.
138     myFirstAttribute = oldAtt->myNext;
139   }
140   else { // Removes from specified place.
141     afterAtt->myNext = oldAtt->myNext;
142   }
143   // Nullifier le next induit l'iterateur d'attribut en erreur.
144   //oldAtt->myNext.Nullify();
145 }
146
147
148 //=======================================================================
149 //function : RootNode
150 //purpose  : used for non const object.
151 //=======================================================================
152
153 TDF_LabelNode* TDF_LabelNode::RootNode ()
154 {
155 #ifdef KEEP_LOCAL_ROOT
156   return myData? myData -> myRoot: 0L;
157 #else
158   TDF_LabelNode* lp = this;
159   while (lp->myFather != NULL) lp = lp->myFather;
160   return lp;
161 #endif
162 }
163
164
165 //=======================================================================
166 //function : RootNode
167 //purpose  : used for const object.
168 //=======================================================================
169
170 const TDF_LabelNode* TDF_LabelNode::RootNode () const
171 {
172 #ifdef KEEP_LOCAL_ROOT
173   return myData? myData -> myRoot: 0L;
174 #else
175   const TDF_LabelNode* lp = this;
176   while (lp->myFather != NULL) lp = lp->myFather;
177   return lp;
178 #endif
179 }
180
181
182 //=======================================================================
183 //function : Data
184 //purpose  : 
185 //=======================================================================
186
187 TDF_Data * TDF_LabelNode::Data () const
188 {
189 #ifdef KEEP_LOCAL_ROOT
190   return myData;
191 #else
192   const TDF_LabelNode* ln = RootNode()->myBrother;
193   return ((TDF_Data*) ln);
194 #endif
195 }
196
197
198 //=======================================================================
199 //function : AllMayBeModified
200 //purpose  : 
201 //=======================================================================
202
203 void TDF_LabelNode::AllMayBeModified()
204 {
205   MayBeModified(Standard_True);
206   if (myFather && !myFather->MayBeModified()) myFather->AllMayBeModified();
207 }