OCC18056 Exception during copying Array attribute with array(0,0)
[occt.git] / src / TDataStd / TDataStd_ReferenceArray.cxx
1 // File:        TDataStd_ReferenceArray.cxx
2 // Created:     May 29 11:40:00 2007
3 // Author:      Vlad Romashko
4 //              <vladislav.romashko@opencascade.com>
5 // Copyright:   Open CASCADE
6
7 #include <TDataStd_ReferenceArray.ixx>
8
9 //=======================================================================
10 //function : GetID
11 //purpose  : 
12 //=======================================================================
13 const Standard_GUID& TDataStd_ReferenceArray::GetID() 
14
15   static Standard_GUID TDataStd_ReferenceArrayID ("7EE745A6-BB50-446c-BB0B-C195B23AB5CA");
16   return TDataStd_ReferenceArrayID; 
17 }
18
19 //=======================================================================
20 //function : TDataStd_ReferenceArray
21 //purpose  : Empty Constructor
22 //=======================================================================
23 TDataStd_ReferenceArray::TDataStd_ReferenceArray() 
24 {
25
26 }
27
28 //=======================================================================
29 //function : Init
30 //purpose  : 
31 //=======================================================================
32 void TDataStd_ReferenceArray::Init(const Standard_Integer lower,
33                                    const Standard_Integer upper)
34 {
35   Standard_RangeError_Raise_if(upper < lower,"TDataStd_ReferenceArray::Init");
36   Backup();
37   myArray = new TDataStd_HLabelArray1(lower, upper);
38 }
39
40 //=======================================================================
41 //function : Set
42 //purpose  : 
43 //=======================================================================
44 Handle(TDataStd_ReferenceArray) TDataStd_ReferenceArray::Set(const TDF_Label&       label,
45                                                              const Standard_Integer lower,
46                                                              const Standard_Integer upper) 
47 {
48   Handle(TDataStd_ReferenceArray) A;
49   if (!label.FindAttribute (TDataStd_ReferenceArray::GetID(), A)) 
50   {
51     A = new TDataStd_ReferenceArray;
52     A->Init (lower, upper); 
53     label.AddAttribute(A);
54   }
55   else if (lower != A->Lower() || upper != A->Upper())
56   {
57     A->Init(lower, upper);
58   }
59   return A;
60 }
61
62 //=======================================================================
63 //function : SetValue
64 //purpose  : 
65 //=======================================================================
66 void TDataStd_ReferenceArray::SetValue (const Standard_Integer index,
67                                         const TDF_Label&       value) 
68 {
69   if (value == myArray->Value(index))
70     return;
71
72   Backup();
73
74   myArray->SetValue(index, value);
75 }
76
77 //=======================================================================
78 //function : Value
79 //purpose  : 
80 //=======================================================================
81 TDF_Label TDataStd_ReferenceArray::Value (const Standard_Integer index) const 
82 {
83   return myArray->Value(index);
84 }
85
86 //=======================================================================
87 //function : Lower
88 //purpose  : 
89 //=======================================================================
90 Standard_Integer TDataStd_ReferenceArray::Lower () const 
91
92   if (myArray.IsNull())
93     return 0;
94   return myArray->Lower();
95 }
96
97 //=======================================================================
98 //function : Upper
99 //purpose  : 
100 //=======================================================================
101 Standard_Integer TDataStd_ReferenceArray::Upper () const 
102
103   if (myArray.IsNull())
104     return -1;
105   return myArray->Upper();
106 }
107
108 //=======================================================================
109 //function : Length
110 //purpose  : 
111 //=======================================================================
112 Standard_Integer TDataStd_ReferenceArray::Length () const 
113 {
114   if (myArray.IsNull())
115     return 0;
116   return myArray->Length();
117 }
118
119 //=======================================================================
120 //function : InternalArray
121 //purpose  : 
122 //=======================================================================
123 const Handle(TDataStd_HLabelArray1)& TDataStd_ReferenceArray::InternalArray () const 
124 {
125   return myArray;
126 }
127
128 //=======================================================================
129 //function : SetInternalArray
130 //purpose  : 
131 //=======================================================================
132 void TDataStd_ReferenceArray::SetInternalArray (const Handle(TDataStd_HLabelArray1)& values,
133                                                 const Standard_Boolean isCheckItem)
134 {
135 //  myArray = values;
136   Standard_Integer aLower    = values->Lower();
137   Standard_Integer anUpper   = values->Upper();
138   Standard_Boolean aDimEqual = Standard_False;
139   Standard_Integer i;
140
141 #ifdef OCC2932
142   if (Lower() == aLower && Upper() == anUpper ) {
143     aDimEqual = Standard_True;
144     Standard_Boolean isEqual = Standard_True;
145     if(isCheckItems) {
146       for(i = aLower; i <= anUpper; i++) {
147         if(myArray->Value(i) != values->Value(i)) {
148           isEqual = Standard_False;
149           break;
150         }
151       }
152       if(isEqual)
153         return;
154     }
155   }
156 #endif
157
158   Backup();
159
160   if(myArray.IsNull() || !aDimEqual) 
161     myArray = new TDataStd_HLabelArray1(aLower, anUpper);
162
163   for(i = aLower; i <= anUpper; i++) 
164     myArray->SetValue(i, values->Value(i));
165 }
166
167 //=======================================================================
168 //function : ID
169 //purpose  : 
170 //=======================================================================
171 const Standard_GUID& TDataStd_ReferenceArray::ID () const 
172
173   return GetID();
174 }
175
176 //=======================================================================
177 //function : NewEmpty
178 //purpose  : 
179 //=======================================================================
180 Handle(TDF_Attribute) TDataStd_ReferenceArray::NewEmpty () const
181 {  
182   return new TDataStd_ReferenceArray(); 
183 }
184
185 //=======================================================================
186 //function : Restore
187 //purpose  : 
188 //=======================================================================
189 void TDataStd_ReferenceArray::Restore(const Handle(TDF_Attribute)& With) 
190 {
191   Handle(TDataStd_ReferenceArray) anArray = Handle(TDataStd_ReferenceArray)::DownCast(With);
192   if (!anArray->myArray.IsNull()) 
193   {
194     const TDataStd_LabelArray1& arr = anArray->myArray->Array1();
195     Standard_Integer lower = arr.Lower(), i = lower, upper = arr.Upper();
196     Init(lower, upper);
197     for (; i <= upper; i++)
198     {
199       myArray->SetValue(i, arr.Value(i));
200     }
201   }
202   else
203   {
204     myArray.Nullify();
205   }
206 }
207
208 //=======================================================================
209 //function : Paste
210 //purpose  : 
211 //=======================================================================
212 void TDataStd_ReferenceArray::Paste (const Handle(TDF_Attribute)& Into,
213                                      const Handle(TDF_RelocationTable)& RT) const
214 {
215   Handle(TDataStd_ReferenceArray) anArray = Handle(TDataStd_ReferenceArray)::DownCast(Into);
216   if (myArray.IsNull())
217   {
218     anArray->myArray.Nullify();
219     return;
220   }
221   const TDataStd_LabelArray1& arr = myArray->Array1();
222   Standard_Integer lower = arr.Lower(), i = lower, upper = arr.Upper();
223   if (lower != anArray->Lower() || upper != anArray->Upper())
224     anArray->Init(lower, upper);
225   for (; i <= upper; i++)
226   {
227     TDF_Label L = arr.Value(i), rL;
228     if (!L.IsNull())
229     {
230       if (!RT->HasRelocation(L, rL))
231         rL = L;
232       anArray->myArray->SetValue(i, rL);
233     }
234   }
235 }
236
237 //=======================================================================
238 //function : References
239 //purpose  : Adds the referenced attributes or labels.
240 //=======================================================================
241 void TDataStd_ReferenceArray::References(const Handle(TDF_DataSet)& aDataSet) const
242 {
243   if (!Label().IsImported() && !myArray.IsNull()) 
244   {
245     const TDataStd_LabelArray1& arr = myArray->Array1();
246     Standard_Integer lower = arr.Lower(), i = lower, upper = arr.Upper();
247     for (; i <= upper; i++)
248     {
249       if (!arr.Value(i).IsNull())
250         aDataSet->AddLabel(arr.Value(i));
251     }
252   }
253 }
254
255 //=======================================================================
256 //function : Dump
257 //purpose  : 
258 //=======================================================================
259 Standard_OStream& TDataStd_ReferenceArray::Dump (Standard_OStream& anOS) const
260 {  
261   anOS << "ReferenceArray";
262   return anOS;
263 }