0023373: MSVC++ warnings issued during compilation for 64bits, 'Sparse Arrays'
[occt.git] / src / TObj / TObj_TIntSparseArray.cxx
1 // Created on: 2007-03-16
2 // Created by: Michael SAZONOV
3 // Copyright (c) 2007-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 // The original implementation Copyright: (C) RINA S.p.A
21
22 #include <TObj_TIntSparseArray.hxx>
23 #include <Standard_GUID.hxx>
24 #include <Standard_ImmutableObject.hxx>
25 #include <TDF_Data.hxx>
26 #include <TDF_AttributeDelta.hxx>
27 #include <TDF_DeltaOnModification.hxx>
28
29 IMPLEMENT_STANDARD_HANDLE(TObj_TIntSparseArray,TDF_Attribute)
30 IMPLEMENT_STANDARD_RTTIEXT(TObj_TIntSparseArray,TDF_Attribute)
31
32 //=======================================================================
33 //function : TObj_TIntSparseArray
34 //purpose  : Empty constructor
35 //=======================================================================
36
37 TObj_TIntSparseArray::TObj_TIntSparseArray ()
38 : myVector(100), myOldMap(100), myDoBackup (Standard_True)
39 {
40 }
41
42 //=======================================================================
43 //function : GetID
44 //purpose  :
45 //=======================================================================
46
47 const Standard_GUID& TObj_TIntSparseArray::GetID()
48 {
49   static Standard_GUID GInterfaceID ("7016dc0c-b118-4433-8ef3-aecdccc79198");
50   return GInterfaceID;
51 }
52
53 //=======================================================================
54 //function : ID
55 //purpose  :
56 //=======================================================================
57
58 const Standard_GUID& TObj_TIntSparseArray::ID() const
59 {
60   return GetID();
61 }
62
63 //=======================================================================
64 //function : Set
65 //purpose  :
66 //=======================================================================
67
68 Handle(TObj_TIntSparseArray) TObj_TIntSparseArray::Set
69                            (const TDF_Label& theLabel)
70 {
71   Handle(TObj_TIntSparseArray) aTData;
72   if (! theLabel.FindAttribute( GetID(), aTData))
73   {
74     aTData = new TObj_TIntSparseArray;
75     theLabel.AddAttribute(aTData);
76   }
77   return aTData;
78 }
79
80 //=======================================================================
81 //function : SetValue
82 //purpose  : 
83 //=======================================================================
84
85 void TObj_TIntSparseArray::SetValue (const Standard_Size theId,
86                                          const Standard_Integer theValue)
87 {
88   // check that modification is allowed
89   if ( !Label().Data()->IsModificationAllowed() )
90     Standard_ImmutableObject::Raise
91       ("Attribute TObj_TIntSparseArray is changed outside transaction");
92
93   if (theId < 1 || theValue < 1)
94     Standard_OutOfRange::Raise ("TObj_TIntSparseArray::SetValue");
95
96   Standard_Integer anOld = AbsentValue;
97   Standard_Boolean isOld = myVector.HasValue(theId);
98   if (isOld)
99   {
100     Standard_Integer& aData = myVector(theId);
101     if (aData == theValue)
102       // no actual modification
103       return;
104     anOld = aData;
105     // set new value
106     aData = theValue;
107   }
108   else
109   {
110     // set the new value
111     myVector.SetValue (theId, theValue);
112   }
113
114   TDF_Label aLabel = Label();
115   if (!aLabel.IsNull())
116   {
117     Handle(TDF_Data) aData = aLabel.Data();
118     Standard_Integer aCurrentTransaction = aData->Transaction();
119     Standard_Integer aMyTransaction = Transaction();
120
121     if (myDoBackup && aMyTransaction < aCurrentTransaction)
122       backupValue(theId, anOld, theValue);
123   }
124 }
125
126 //=======================================================================
127 //function : UnsetValue
128 //purpose  : 
129 //=======================================================================
130
131 void TObj_TIntSparseArray::UnsetValue (const Standard_Size theId)
132 {
133   // check that modification is allowed
134   if ( !Label().Data()->IsModificationAllowed() )
135     Standard_ImmutableObject::Raise
136       ("Attribute TObj_TIntSparseArray is changed outside transaction");
137
138   if (theId < 1)
139     Standard_OutOfRange::Raise ("TObj_TIntSparseArray::UnsetValue");
140
141   Standard_Integer anOld = AbsentValue;
142   Standard_Boolean isOld = myVector.HasValue(theId);
143   if (isOld)
144   {
145     anOld = myVector(theId);
146     // unset the value
147     myVector.UnsetValue(theId);
148   }
149   else
150     // no actual modification
151     return;
152
153   TDF_Label aLabel = Label();
154   if (!aLabel.IsNull())
155   {
156     Handle(TDF_Data) aData = aLabel.Data();
157     Standard_Integer aCurrentTransaction = aData->Transaction();
158     Standard_Integer aMyTransaction = Transaction();
159
160     if (myDoBackup && aMyTransaction < aCurrentTransaction)
161       backupValue(theId, anOld, AbsentValue);
162   }
163 }
164
165 //=======================================================================
166 //function : Clear
167 //purpose  :
168 //=======================================================================
169
170 void TObj_TIntSparseArray::Clear ()
171 {
172   // backup old values
173   TDF_Label aLabel = Label();
174   if (!aLabel.IsNull())
175   {
176     Handle(TDF_Data) aData = aLabel.Data();
177     Standard_Integer aCurrentTransaction = aData->Transaction();
178     Standard_Integer aMyTransaction = Transaction();
179
180     if (myDoBackup && aMyTransaction < aCurrentTransaction)
181     {
182       TObj_TIntSparseArray_VecOfData::Iterator anIt (myVector);
183       for (; anIt.More(); anIt.Next())
184       {
185         Standard_Size anId = anIt.Key();
186         Standard_Integer aVal = anIt.Value();
187         backupValue(anId, aVal, AbsentValue);
188       }
189     }
190   }
191   myVector.Clear();
192 }
193
194 //=======================================================================
195 //function : backupValue
196 //purpose  :
197 //=======================================================================
198
199 void TObj_TIntSparseArray::backupValue (const Standard_Size theId,
200                                             const Standard_Integer theCurrValue,
201                                             const Standard_Integer theNewValue)
202 {
203   // save the current value if it has not been saved in previous time
204   if ( !myOldMap.IsBound( theId ) )
205     myOldMap.Bind(theId, theCurrValue);
206   else
207   {
208     // if value in Undo is the same as the new one, the item in Undo map may be cleared
209     Standard_Integer aUData = myOldMap.Value(theId);
210     if (aUData == theNewValue)
211       myOldMap.UnBind(theId);
212   }
213 }
214
215 //=======================================================================
216 //function : NewEmpty
217 //purpose  :
218 //=======================================================================
219
220 Handle(TDF_Attribute) TObj_TIntSparseArray::NewEmpty () const
221 {
222   return new TObj_TIntSparseArray;
223 }
224
225 //=======================================================================
226 //function : BackupCopy
227 //purpose  : Moves <this> delta into a new other attribute.
228 //=======================================================================
229
230 Handle(TDF_Attribute) TObj_TIntSparseArray::BackupCopy() const
231 {
232   Handle(TObj_TIntSparseArray) aCopy = 
233     Handle(TObj_TIntSparseArray)::DownCast(NewEmpty());
234
235   // save delta data in a copy
236   if (!myOldMap.IsEmpty())
237     aCopy->myOldMap.Exchange ( (TObj_TIntSparseArray_MapOfData&)myOldMap );
238
239   return aCopy;
240 }
241
242 //=======================================================================
243 //function : Restore
244 //purpose  : Restores contents of this with theDelta
245 //=======================================================================
246
247 void TObj_TIntSparseArray::Restore(const Handle(TDF_Attribute)& theDelta)
248 {
249   Handle(TObj_TIntSparseArray) aDelta = 
250     Handle(TObj_TIntSparseArray)::DownCast(theDelta);
251   if (aDelta.IsNull())
252     return;
253
254   // restore the values from aDelta->myOldMap
255   if (!aDelta->myOldMap.IsEmpty())
256   {
257     TObj_TIntSparseArray_MapOfData::Iterator anIt (aDelta->myOldMap);
258     for (; anIt.More(); anIt.Next())
259     {
260       Standard_Size anId = anIt.Key();
261       Standard_Integer anOld = anIt.Value();
262       if (anOld == AbsentValue)
263         UnsetValue (anId);
264       else
265         SetValue (anId, anOld);
266     }
267   }
268 }
269
270 //=======================================================================
271 //function : Paste
272 //purpose  : copy this
273 //=======================================================================
274
275 void TObj_TIntSparseArray::Paste (const Handle(TDF_Attribute)& theInto,
276                                     const Handle(TDF_RelocationTable)&) const
277 {
278   Handle(TObj_TIntSparseArray) aInto =
279     Handle(TObj_TIntSparseArray)::DownCast(theInto);
280   if(aInto.IsNull())
281     return;
282
283   aInto->myVector.Assign(myVector);
284 }
285
286 //=======================================================================
287 //function : BeforeCommitTransaction
288 //purpose  : It is called just before Commit or Abort transaction
289 //=======================================================================
290
291 void TObj_TIntSparseArray::BeforeCommitTransaction()
292 {
293   if (!myOldMap.IsEmpty())
294   {
295     Backup();
296     ClearDelta();
297   }
298 }
299
300 //=======================================================================
301 //function : DeltaOnModification
302 //purpose  : Applies aDelta to <me>
303 //=======================================================================
304
305 void TObj_TIntSparseArray::DeltaOnModification
306                         (const Handle(TDF_DeltaOnModification)& theDelta)
307 {
308   // we do not call Backup here, because a backup data is formed inside Restore.
309   // Backup is called rather from BeforeCommitTransaction
310   Restore(theDelta->Attribute());
311 }
312
313 //=======================================================================
314 //function : AfterUndo
315 //purpose  : After application of a TDF_Delta.
316 //=======================================================================
317
318 Standard_Boolean TObj_TIntSparseArray::AfterUndo
319                         (const Handle(TDF_AttributeDelta)&,
320                          const Standard_Boolean)
321 {
322   // we must be sure that a delta in <me> is cleared
323   ClearDelta();
324   return Standard_True;
325 }