1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //szv#4 S4163
15
16 #include <Interface_IntList.hxx>
17
18 // Organisation des donnees :
19 // theents vaut : 0 pas de reference
20 // > 0 : une reference, dont voici la valeur; pas de liste
21 // < 0 : une liste de references; on stocke <rank>, elle debute a <rank>+1
22 // la liste est dans therefs et est ainsi constitue :
23 // liste de valeurs negatives, se terminant pas une valeur positive :
24 // de <rank>+1 a <rank>+nb , <rank>+1 a <rank>+nb-1 sont negatifs et
25 // <rank>+nb est negatif
26 // un zero signifie : place libre
27 // Pre-reservation : <rank> note le nombre courant, en positif strict
28 // Il faut alors l incrementer a chaque ajout
29 // Usage contextuel, il faut demander SetNumber(num < 0) pour exploiter cette
30 // info et Add(ref < 0) pour la gerer.
31 // Si elle n est pas presente, on bascule en mode courant
Interface_IntList()32 Interface_IntList::Interface_IntList ()
33 {
34 thenbe = thenbr = thenum = thecount = therank = 0;
35 }
Interface_IntList(const Standard_Integer nbe)36 Interface_IntList::Interface_IntList (const Standard_Integer nbe)
37 {
38 Initialize (nbe);
39 }
40
Interface_IntList(const Interface_IntList & other,const Standard_Boolean copied)41 Interface_IntList::Interface_IntList (const Interface_IntList& other, const Standard_Boolean copied)
42 {
43 thenbe = other.NbEntities();
44 thenum = thecount = therank = 0; //szv#4:S4163:12Mar99 initialization needed
45 other.Internals (thenbr, theents, therefs);
46 if (copied) {
47 Standard_Integer i;
48 Handle(TColStd_HArray1OfInteger) ents = new TColStd_HArray1OfInteger (0,thenbe); ents->Init(0);
49 for (i = 1; i <= thenbe; i ++) ents->SetValue (i,theents->Value(i));
50 Handle(TColStd_HArray1OfInteger) refs = new TColStd_HArray1OfInteger (0,thenbr); refs->Init(0);
51 for (i = 1; i <= thenbr; i ++) refs->SetValue (i,therefs->Value(i));
52 theents = ents;
53 therefs = refs;
54 }
55 SetNumber (other.Number());
56 }
Initialize(const Standard_Integer nbe)57 void Interface_IntList::Initialize (const Standard_Integer nbe)
58 {
59 thenbe = nbe; thenbr = thenum = thecount = therank = 0;
60 theents = new TColStd_HArray1OfInteger (0,nbe); theents->Init(0);
61 }
62
Internals(Standard_Integer & nbrefs,Handle (TColStd_HArray1OfInteger)& ents,Handle (TColStd_HArray1OfInteger)& refs) const63 void Interface_IntList::Internals (Standard_Integer& nbrefs,
64 Handle(TColStd_HArray1OfInteger)& ents,
65 Handle(TColStd_HArray1OfInteger)& refs) const
66 {
67 nbrefs = thenbr; ents = theents; refs = therefs;
68 }
69
NbEntities() const70 Standard_Integer Interface_IntList::NbEntities () const
71 {
72 return thenbe;
73 }
74
SetNbEntities(const Standard_Integer nbe)75 void Interface_IntList::SetNbEntities (const Standard_Integer nbe)
76 {
77 if (nbe <= theents->Upper()) return;
78 Standard_Integer i;
79 Handle(TColStd_HArray1OfInteger) ents = new TColStd_HArray1OfInteger (0,nbe); ents->Init(0);
80 for (i = 1; i <= thenbe; i ++) ents->SetValue (i,theents->Value(i));
81 theents = ents;
82 thenbe = nbe;
83 }
84
SetNumber(const Standard_Integer number)85 void Interface_IntList::SetNumber (const Standard_Integer number)
86 {
87 // Usage en pre-reservation : a demander specifiquement ! -> optimisation
88 // <preres> verifie que la pre-reservation est valide
89 if (number < 0) {
90 if (thenum == -number || number < - thenbe) return;
91 Standard_Boolean preres = Standard_True;
92 thenum = -number;
93 Standard_Integer val = theents->Value (thenum);
94 if (val == 0) { thecount = 0; therank = 0; }
95 else if (val > 0) { thecount = 1; therank = -1; }
96 if (val < -1) {
97 therank = -val;
98 thecount = therefs->Value(therank);
99 if (thecount <= 0) preres = Standard_False;
100 }
101 if (preres) return;
102 }
103 // Usage courant. La suite en usage courant ou si pas de pre-reservation
104 else if (number > 0) {
105 if (thenum == number || number > thenbe) return;
106 thenum = number;
107 }
108 else return;
109
110 Standard_Integer val = theents->Value(thenum);
111 if (val == 0) { thecount = 0; therank = 0; }
112 else if (val > 0) { thecount = 1; therank = -1; }
113 else if (val < -1) {
114 therank = - val; thecount = 0;
115 if (therefs->Value(therank+1) == 0) thecount = - therefs->Value(therank);
116 else {
117 for (Standard_Integer j = 1; ; j ++) {
118 val = therefs->Value (therank+j);
119 if (val >= 0) break;
120 thecount ++;
121 }
122 if (val > 0) thecount ++;
123 }
124 }
125 else { thecount = 0; therank = -1; } // val == -1 reste
126 }
127
Number() const128 Standard_Integer Interface_IntList::Number () const
129 {
130 return thenum;
131 }
132
List(const Standard_Integer number,const Standard_Boolean copied) const133 Interface_IntList Interface_IntList::List (const Standard_Integer number,
134 const Standard_Boolean copied) const
135 {
136 Interface_IntList alist (*this,copied);
137 alist.SetNumber (number);
138 return alist;
139 }
140
SetRedefined(const Standard_Boolean mode)141 void Interface_IntList::SetRedefined (const Standard_Boolean mode)
142 {
143 if (!NbEntities() || thenum == 0) return;
144
145 Standard_Integer val = theents->Value(thenum);
146 if (val < -1) return;
147 else if (mode) {
148 if (val == 0) theents->SetValue (thenum,-1);
149 else if (val > 0) {
150 Reservate (2);
151 theents->SetValue (thenum, -thenbr);
152 therefs->SetValue (thenbr+1, val);
153 thenbr ++;
154 }
155 } else if (!mode) {
156 if (val == -1) theents->SetValue (thenum,0);
157 else if (therefs->Value (therank+1) >= 0) {
158 theents->SetValue (thenum, therefs->Value(therank+1));
159 if (thenbr == therank+1) thenbr --;
160 }
161 }
162 }
163
Reservate(const Standard_Integer count)164 void Interface_IntList::Reservate (const Standard_Integer count)
165 {
166 // Reservate (-count) = Reservate (count) + allocation sur entite courante + 1
167 if (count < 0) {
168 Reservate(-count-1);
169 if (thenum == 0) return;
170 thenbr ++;
171 therefs->SetValue (thenbr,0); // contiendra le nombre ...
172 therank = thenbr;
173 theents->SetValue(thenum, -thenbr);
174 thenbr -= count;
175 return;
176 }
177 Standard_Integer up, oldup = 0;
178 if (thenbr == 0) { // c-a-d pas encore allouee ...
179 up = thenbe/2+1; if (up < 2) up = 2;
180 if (up < count) up = count*3/2;
181 therefs = new TColStd_HArray1OfInteger (0,up); therefs->Init(0);
182 thenbr = 2; // on commence apres (commodite d adressage)
183 }
184 oldup = therefs->Upper();
185 if (thenbr + count < oldup) return; // OK
186 up = oldup*3/2+count; if (up < 2) up = 2;
187 Handle(TColStd_HArray1OfInteger) refs = new TColStd_HArray1OfInteger (0,up); refs->Init(0);
188 for (Standard_Integer i = 1; i <= oldup; i ++) refs->SetValue (i,therefs->Value(i));
189 therefs = refs;
190 }
191
Add(const Standard_Integer ref)192 void Interface_IntList::Add (const Standard_Integer ref)
193 {
194 if (thenum == 0) return;
195 // ref < 0 : pre-reservation
196 if (ref < 0) {
197 Add(-ref);
198 if (therank <= 0) return;
199 if (therefs->Value(therank) >= 0) therefs->SetValue (therank, thecount);
200 return;
201 }
202
203 if (therank == 0)
204 { theents->SetValue (thenum,ref); thecount = 1; therank = -1; }
205 else if (therank < 0) {
206 Reservate (2);
207 therank = thenbr;
208 Standard_Integer val = theents->Value(thenum);
209 theents->SetValue (thenum, -thenbr);
210 if (thecount == 1)
211 { therefs->SetValue (thenbr+1, -val); thenbr ++; }
212 therefs->SetValue (thenbr+1, ref); thenbr ++;
213 thecount ++;
214 } else if (thenbr == therank+thecount) { // place libre en fin
215 therefs->SetValue (thenbr, -therefs->Value(thenbr));
216 therefs->SetValue (thenbr+1, ref); thenbr ++;
217 thecount ++;
218 } else if (therefs->Value(therank+thecount+1) == 0) { // place libre apres
219 therefs->SetValue (therank+thecount, -therefs->Value(therank+thecount));
220 therefs->SetValue (therank+thecount+1, ref);
221 thecount ++;
222 } else { // recopier plus loin !
223 Reservate (thecount+2);
224 Standard_Integer rank = therank;
225 therank = thenbr;
226 theents->SetValue (thenum,-therank);
227 for (Standard_Integer i = 1; i < thecount; i ++) {
228 therefs->SetValue (therank+i, therefs->Value(rank+i));
229 therefs->SetValue (rank+i,0);
230 }
231 therefs->SetValue (therank+thecount, -therefs->Value(rank+thecount));
232 therefs->SetValue (rank+thecount,0);
233 therefs->SetValue (therank+thecount+1,ref);
234 thecount ++; thenbr = therank + thecount + 1;
235 }
236 }
237
238
Length() const239 Standard_Integer Interface_IntList::Length () const
240 {
241 return thecount;
242 }
243
IsRedefined(const Standard_Integer num) const244 Standard_Boolean Interface_IntList::IsRedefined (const Standard_Integer num) const
245 {
246 Standard_Integer n = (num == 0 ? thenum : num);
247 if (!NbEntities() || n == 0) return Standard_False;
248 if (theents->Value(n) < 0) return Standard_True;
249 return Standard_False;
250 }
251
Value(const Standard_Integer num) const252 Standard_Integer Interface_IntList::Value (const Standard_Integer num) const
253 {
254 if (thenum == 0) return 0;
255 if (num <= 0 || num > thecount) return 0;
256 if (thecount == 0) return 0;
257 if (therank <= 0) return theents->Value(thenum);
258 Standard_Integer val = therefs->Value (therank+num);
259 if (val < 0) return -val;
260 return val;
261 }
262
Remove(const Standard_Integer)263 Standard_Boolean Interface_IntList::Remove (const Standard_Integer)
264 {
265 return Standard_False; // not yet implemented
266 }
267
Clear()268 void Interface_IntList::Clear ()
269 {
270 if (thenbr == 0) return; // deja clear
271 Standard_Integer i,low,up;
272 low = theents->Lower(); up = theents->Upper();
273 for (i = low; i <= up; i ++) theents->SetValue (i,0);
274 thenbr = 0;
275 if (therefs.IsNull()) return;
276 low = therefs->Lower(); up = therefs->Upper();
277 for (i = low; i <= up; i ++) therefs->SetValue (i,0);
278 }
279
AdjustSize(const Standard_Integer margin)280 void Interface_IntList::AdjustSize (const Standard_Integer margin)
281 {
282 Standard_Integer i, up = theents->Upper();
283 if (up > thenbe) {
284 Handle(TColStd_HArray1OfInteger) ents = new TColStd_HArray1OfInteger (0,thenbe); ents->Init(0);
285 for (i = 1; i <= thenbe; i ++) ents->SetValue (i,theents->Value(i));
286 theents = ents;
287 }
288 if (thenbr == 0) Reservate (margin);
289 else {
290 up = therefs->Upper();
291 if (up >= thenbr && up <= thenbr + margin) return;
292 Handle(TColStd_HArray1OfInteger) refs = new TColStd_HArray1OfInteger (0,thenbr+margin); refs->Init(0);
293 for (i = 1; i <= thenbr; i ++) refs->SetValue (i,therefs->Value(i));
294 therefs = refs;
295 }
296 }
297