1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 //#include <Dico_Dictionary.ixx> pas en gxx
20 #include <Standard_NoSuchObject.hxx>
25 // thecars[0] : caractere de consigne, caracterisant la cellule
26 // thecars[1] : indicateur de presence : 0 rien, ==thecar[0] item present
27 // thecars[2] : caractere du Sub ou 0
28 // thecars[3] : caractere du Next ou 0
30 // REMARQUE : Fonctions d acces dupliquees : TCollection_AsciiString / CString
31 // C est a chaque fois le MEME CODE, mais Length et Value ne sont pas obtenues
32 // de la meme maniere ...
33 // SearchCell pas duplique : la version String appelle la version CString
34 // Les autres fonctions doivent d abord evaluer la longueur de <name>
35 // Sur String, methode Length, mais sur CString, il faut evaluer par strlen
36 // String serait donc meilleur (plus systematique) MAIS suppose, sur appel
37 // CString, de constituer une TCollection_AsciiString ce qui peut couter ...
38 // CONCLUSION : Fonctions d acces par Nom dupliquees, pour optimisation
41 Dico_Dictionary::Dico_Dictionary ()
43 thecars[0] = thecars[1] = thecars[2] = thecars[3] = '\0';
44 thesub.Nullify(); thenext.Nullify();
47 void Dico_Dictionary::SetChar (const char car) { thecars[0] = car; }
52 Standard_Boolean Dico_Dictionary::HasItem
53 (const Standard_CString name, const Standard_Boolean exact) const
55 Handle(Dico_Dictionary) acell;
56 Standard_Integer reslev,stat;
57 SearchCell (name,strlen(name),name[0],1, acell,reslev,stat);
58 if (stat != 0 || reslev != 0) return Standard_False;
59 if (acell->HasIt()) return Standard_True;
60 if (!exact) { if (!acell->Complete(acell)) return Standard_False; }
61 return (acell->HasIt());
64 Standard_Boolean Dico_Dictionary::HasItem
65 (const TCollection_AsciiString& name, const Standard_Boolean exact) const
67 Handle(Dico_Dictionary) acell;
68 Standard_Integer reslev,stat;
69 SearchCell (name.ToCString(),name.Length(),name.Value(1),1, acell,reslev,stat);
70 if (stat != 0 || reslev != 0) return Standard_False;
71 if (acell->HasIt()) return Standard_True;
72 if (!exact) { if (!acell->Complete(acell)) return Standard_False; }
73 return (acell->HasIt());
78 const TheItem& Dico_Dictionary::Item
79 (const Standard_CString name, const Standard_Boolean exact) const
81 Handle(Dico_Dictionary) acell;
82 Standard_Integer reslev,stat;
83 SearchCell (name,strlen(name),name[0],1, acell,reslev,stat);
84 if (stat != 0 || reslev != 0)
85 Standard_NoSuchObject::Raise("Dictionary : Item");
86 if (acell->HasIt()) return acell->It();
87 if (!exact) { if (!acell->Complete(acell)) return acell->It(); }
88 if (!acell->HasIt()) Standard_NoSuchObject::Raise("Dictionary : Item");
92 const TheItem& Dico_Dictionary::Item
93 (const TCollection_AsciiString& name, const Standard_Boolean exact) const
95 Handle(Dico_Dictionary) acell;
96 Standard_Integer reslev,stat;
97 SearchCell (name.ToCString(),name.Length(),name.Value(1),1, acell,reslev,stat);
98 if (stat != 0 || reslev != 0)
99 Standard_NoSuchObject::Raise("Dictionary : Item");
100 if (acell->HasIt()) return acell->It();
101 if (!exact) { if (!acell->Complete(acell)) return acell->It(); }
102 if (!acell->HasIt()) Standard_NoSuchObject::Raise("Dictionary : Item");
103 return (acell->It());
108 Standard_Boolean Dico_Dictionary::GetItem
109 (const Standard_CString name,
110 TheItem& anitem, const Standard_Boolean exact) const
112 Handle(Dico_Dictionary) acell;
113 Standard_Integer reslev,stat;
114 SearchCell (name,strlen(name),name[0],1, acell,reslev,stat);
115 if (stat != 0 || reslev != 0) return Standard_False;
116 if (acell->HasIt()) { anitem = acell->It(); return Standard_True; }
117 if (!exact) { if (!acell->Complete(acell)) return Standard_False; }
118 anitem = acell->It();
119 return (acell->HasIt());
122 Standard_Boolean Dico_Dictionary::GetItem
123 (const TCollection_AsciiString& name,
124 TheItem& anitem, const Standard_Boolean exact) const
126 Handle(Dico_Dictionary) acell;
127 Standard_Integer reslev,stat;
128 SearchCell (name.ToCString(),name.Length(),name.Value(1),1, acell,reslev,stat);
129 if (stat != 0 || reslev != 0) return Standard_False;
130 if (acell->HasIt()) { anitem = acell->It(); return Standard_True; }
131 if (!exact) { if (!acell->Complete(acell)) return Standard_False; }
132 anitem = acell->It();
133 return (acell->HasIt());
138 void Dico_Dictionary::SetItem
139 (const Standard_CString name,
140 const TheItem& anitem, const Standard_Boolean exact)
142 Handle(Dico_Dictionary) acell;
143 Standard_Integer reslev,stat;
144 Standard_Integer namlen = strlen(name);
145 SearchCell (name,namlen,name[0],1, acell,reslev,stat);
146 if (!exact && !acell->HasIt())
147 { if (acell->Complete(acell)) { acell->SetIt(anitem); return; } }
148 if (stat < 0) { cout<<"Dictionary walk back not performed"<<endl; return; }
149 NewCell (name,namlen, acell,reslev,stat);
150 acell->SetIt(anitem);
154 void Dico_Dictionary::SetItem
155 (const TCollection_AsciiString& name,
156 const TheItem& anitem, const Standard_Boolean exact)
158 Handle(Dico_Dictionary) acell;
159 Standard_Integer reslev,stat;
160 Standard_CString namval = name.ToCString();
161 Standard_Integer namlen = name.Length();
162 SearchCell (namval,namlen,name.Value(1),1, acell,reslev,stat);
163 if (!exact && !acell->HasIt())
164 { if (acell->Complete(acell)) { acell->SetIt(anitem); return; } }
165 if (stat < 0) { cout<<"Dictionary walk back not performed"<<endl; return; }
166 NewCell (namval,namlen, acell,reslev,stat);
167 acell->SetIt(anitem);
173 TheItem& Dico_Dictionary::NewItem
174 (const Standard_CString name,
175 Standard_Boolean& isvalued, const Standard_Boolean exact)
177 Handle(Dico_Dictionary) acell;
178 Standard_Integer reslev,stat;
179 Standard_Integer namlen = strlen(name);
180 SearchCell (name,namlen,name[0],1, acell,reslev,stat);
181 if (stat == 0 && reslev == 0) {
182 isvalued = acell->HasIt(); // ancien statut
183 acell->DeclIt(); // nouveau statut = value d office
184 return acell->ItAdr();
187 if (acell->Complete(acell))
188 { isvalued = acell->HasIt(); acell->DeclIt(); return acell->ItAdr(); }
190 if (stat < 0) { Standard_NoSuchObject::Raise("Dictionary : NewItem"); }
191 NewCell (name,namlen, acell,reslev,stat);
192 isvalued = acell->HasIt(); // ancien statut
193 acell->DeclIt(); // nouveau statut = value d office
194 return acell->ItAdr();
198 TheItem& Dico_Dictionary::NewItem
199 (const TCollection_AsciiString& name,
200 Standard_Boolean& isvalued, const Standard_Boolean exact)
202 Handle(Dico_Dictionary) acell;
203 Standard_Integer reslev,stat;
204 Standard_Integer namlen = name.Length();
205 Standard_CString namval = name.ToCString();
206 SearchCell (namval,namlen,name.Value(1),1, acell,reslev,stat);
207 if (stat == 0 && reslev == 0) {
208 isvalued = acell->HasIt(); // ancien statut
209 acell->DeclIt(); // nouveau statut = value d office
210 return acell->ItAdr();
213 if (acell->Complete(acell))
214 { isvalued = acell->HasIt(); acell->DeclIt(); return acell->ItAdr(); }
216 if (stat < 0) { Standard_NoSuchObject::Raise("Dictionary : NewItem"); }
217 NewCell (namval,namlen, acell,reslev,stat);
218 isvalued = acell->HasIt(); // ancien statut
219 acell->DeclIt(); // nouveau statut = value d office
220 return acell->ItAdr();
223 // .... RemoveItem ....
225 Standard_Boolean Dico_Dictionary::RemoveItem
226 (const Standard_CString name,
227 const Standard_Boolean cln, const Standard_Boolean exact)
229 Handle(Dico_Dictionary) acell;
230 Standard_Integer reslev,stat;
231 SearchCell (name,strlen(name),name[0],1, acell,reslev,stat);
232 // if (stat != 0) { cout<<"Dictionary : RemoveItem not found"<<endl; return; }
233 if (stat != 0) return Standard_False;
234 if (!exact && !acell->HasIt())
235 { if (!acell->Complete(acell)) return Standard_False; }
238 return Standard_True;
241 Standard_Boolean Dico_Dictionary::RemoveItem
242 (const TCollection_AsciiString& name,
243 const Standard_Boolean cln, const Standard_Boolean exact)
245 Handle(Dico_Dictionary) acell;
246 Standard_Integer reslev,stat;
247 SearchCell (name.ToCString(),name.Length(),name.Value(1),1, acell,reslev,stat);
248 // if (stat != 0) { cout<<"Dictionary : RemoveItem not found"<<endl; return; }
249 if (stat != 0) return Standard_False;
250 if (!exact && !acell->HasIt())
251 { if (!acell->Complete(acell)) return Standard_False; }
254 return Standard_True;
257 // .... Methodes d Interet General ....
259 void Dico_Dictionary::Clean ()
263 if (!thesub->HasIt() && !thesub->HasSub()) { // alors prendre son Next
264 if (thesub->HasNext()) {
265 thesub = thesub->Next();
266 thecars[2] = thesub->CellChar();
275 if (!thenext->HasIt() && !thenext->HasSub()) { // alors prendre son Next
276 if (thenext->HasNext()) {
277 thenext = thenext->Next();
278 thecars[3] = thenext->CellChar();
287 Standard_Boolean Dico_Dictionary::IsEmpty () const
289 if (thecars[1] != '\0') return Standard_False;
290 if (!thesub.IsNull())
291 { if (!thesub->IsEmpty()) return Standard_False; }
292 if (!thenext.IsNull())
293 { if (!thenext->IsEmpty()) return Standard_False; }
294 return Standard_True;
297 void Dico_Dictionary::Clear ()
299 thecars[0] = thecars[1] = thecars[2] = thecars[3] = '\0';
300 thesub.Nullify(); thenext.Nullify();
304 Handle(Dico_Dictionary) Dico_Dictionary::Copy () const
306 Handle(Dico_Dictionary) newdic = new Dico_Dictionary;
307 // Handle(Dico_Dictionary)::DownCast(ShallowCopy());
308 newdic->GetCopied(this); // qui doit gerer completement thecars et item
312 // ########################################################################
314 // .... Routines internes ....
316 Standard_Boolean Dico_Dictionary::HasSub () const
317 { return (thecars[2] != '\0'); }
319 Handle(Dico_Dictionary) Dico_Dictionary::Sub () const { return thesub; }
321 Standard_Boolean Dico_Dictionary::HasNext () const
322 { return (thecars[3] != '\0'); }
324 Handle(Dico_Dictionary) Dico_Dictionary::Next () const { return thenext; }
326 void Dico_Dictionary::SetSub (const Handle(Dico_Dictionary)& acell)
328 thesub = acell; thecars[2] = '\0';
329 if (!acell.IsNull()) thecars[2] = acell->CellChar();
332 void Dico_Dictionary::SetNext (const Handle(Dico_Dictionary)& acell)
334 thenext = acell; thecars[3] = '\0';
335 if (!acell.IsNull()) thecars[3] = acell->CellChar();
338 // .... SearchCell ....
340 void Dico_Dictionary::SearchCell
341 (const Standard_CString name, const Standard_Integer lmax,
342 const Standard_Character car, const Standard_Integer level,
343 Handle(Dico_Dictionary)& acell,
344 Standard_Integer& reslev, Standard_Integer& stat) const
346 reslev = lmax - level;
347 if (car > thecars[0]) {
348 if (thecars[3] == '\0') { acell = this; stat = 1; return; }
349 else { // ici, HasNext
350 if (thecars[3] > car) { acell = this; stat = 1; return; }
351 Standard_Integer lev2,stat2;
352 thenext->SearchCell (name,lmax,car,level,acell,lev2,stat2);
353 if (stat2 < 0) { acell = this; stat = 1; return; }
354 else { stat = stat2; reslev = lev2; return; }
357 else if (car == thecars[0]) {
358 if (reslev == 0 || thecars[2] == '\0') // c-a-d !HasSub
359 { acell = this; stat = 0; return; }
361 Standard_Character carsub = name[level]; // caractere no (level+1);
362 if (thecars[2] > carsub) { acell = this; stat = 0; return; }
363 Standard_Integer lev2,stat2;
364 thesub->SearchCell (name,lmax,carsub,level+1,acell,lev2,stat2);
365 if (stat2 < 0) { acell = this; stat = 0; return; }
366 else { stat = stat2; reslev = lev2; return; }
369 else if (car < thecars[0]) { acell = this; stat = -1; return; }
375 void Dico_Dictionary::NewCell
376 (const Standard_CString name, const Standard_Integer namlen,
377 Handle(Dico_Dictionary)& acell,
378 const Standard_Integer reslev, const Standard_Integer stat)
380 Standard_Integer level = namlen - reslev;
381 if (stat > 0) { // Creer une cellule next
382 Handle(Dico_Dictionary) newcell = new Dico_Dictionary;
383 newcell->SetChar( name[level-1] ); // caractere no level
384 if (acell->HasNext()) newcell->SetNext(acell->Next());
385 acell->SetNext(newcell);
388 // A present, voir les sous-niveaux
389 for (Standard_Integer i = level+1; i <= namlen; i ++) {
390 Handle(Dico_Dictionary) newcell = new Dico_Dictionary;
391 newcell->SetChar(name[i-1]);
392 if (acell->HasSub()) newcell->SetNext(acell->Sub());
393 acell->SetSub(newcell);
399 Standard_Boolean Dico_Dictionary::Complete
400 (Handle(Dico_Dictionary)& newcell) const
402 if (!HasSub()) { newcell = this; return HasIt(); }
403 if (HasIt()) { newcell = this; return Standard_False; }
404 if (thesub->HasNext()) { newcell = this; return Standard_False; }
405 return thesub->Complete (newcell);
409 // ## ## ## ## ## ## ## ## ## ## ## ## ##
410 // .... Actions Internes Unitaires ....
412 Standard_Boolean Dico_Dictionary::HasIt () const
413 { return (thecars[1] != '\0'); }
415 const TheItem& Dico_Dictionary::It () const { return theitem; }
417 TheItem& Dico_Dictionary::ItAdr () { return theitem; }
419 void Dico_Dictionary::SetIt (const TheItem& anitem)
420 { theitem = anitem; thecars[1] = thecars[0]; }
422 void Dico_Dictionary::DeclIt () { thecars[1] = thecars[0]; }
424 void Dico_Dictionary::RemoveIt () { thecars[1] = '\0'; }
426 Standard_Character Dico_Dictionary::CellChar () const
427 { return thecars[0]; }
429 void Dico_Dictionary::GetCopied (const Handle(Dico_Dictionary)& fromcell)
431 thecars[0] = fromcell->CellChar();
432 // On reprend l item s ilyena un
433 if (fromcell->HasIt()) {
434 thecars[1] = thecars[0];
435 theitem = fromcell->It();
437 else thecars[1] = '\0';
439 // On saute les noeuds vides
440 if (fromcell->HasSub()) {
441 thesub = fromcell->Sub()->Copy();
442 while (!thesub->HasIt() && !thesub->HasSub()) {
443 thesub = thesub->Next();
444 if (thesub.IsNull()) { thecars[2] = '\0'; break; }
445 else thecars[2] = thesub->CellChar();
449 if (fromcell->HasNext()) {
450 thenext = fromcell->Next()->Copy();
451 while (!thenext->HasIt() && !thenext->HasSub()) {
452 thenext = thenext->Next();
453 if (thenext.IsNull()) { thecars[3] = '\0'; break; }
454 else thecars[3] = thenext->CellChar();