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