1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 // abv 09.04.99 S4136: eliminate parameter step.readaccept.void
15 // sln 04,10.2001. BUC61003. Prevent exception which may occur during reading of complex entity (if entity's items are not in alphabetical order)
17 #include <Interface_Check.hxx>
18 #include <Interface_FileParameter.hxx>
19 #include <Interface_HArray1OfHAsciiString.hxx>
20 #include <Interface_Macros.hxx>
21 #include <Interface_ParamList.hxx>
22 #include <Message.hxx>
23 #include <Message_Messenger.hxx>
24 #include <Standard_Transient.hxx>
25 #include <Standard_Type.hxx>
26 #include <StepData_EnumTool.hxx>
27 #include <StepData_ESDescr.hxx>
28 #include <StepData_Field.hxx>
29 #include <StepData_FieldList.hxx>
30 #include <StepData_PDescr.hxx>
31 #include <StepData_SelectArrReal.hxx>
32 #include <StepData_SelectInt.hxx>
33 #include <StepData_SelectMember.hxx>
34 #include <StepData_SelectNamed.hxx>
35 #include <StepData_SelectReal.hxx>
36 #include <StepData_SelectType.hxx>
37 #include <StepData_StepModel.hxx>
38 #include <StepData_StepReaderData.hxx>
39 #include <TCollection_AsciiString.hxx>
40 #include <TCollection_HAsciiString.hxx>
41 #include <TColStd_Array1OfInteger.hxx>
42 #include <TColStd_HArray1OfInteger.hxx>
43 #include <TColStd_HArray1OfReal.hxx>
44 #include <TColStd_HArray1OfTransient.hxx>
45 #include <TColStd_HSequenceOfReal.hxx>
46 #include <TColStd_IndexedMapOfInteger.hxx>
47 #include <TColStd_SequenceOfInteger.hxx>
48 #include <StepData_UndefinedEntity.hxx>
51 IMPLEMENT_STANDARD_RTTIEXT(StepData_StepReaderData, Interface_FileReaderData)
53 // Le Header est constitue d entites analogues dans leur principe a celles
54 // du Data, a ceci pres qu elles sont sans identifieur, et ne peuvent ni
55 // referencer, ni etre referencees (que ce soit avec Header ou avec Data)
56 // Ainsi, dans StepReaderData, le Header est constitue des "thenbhead" 1res Entites
57 // #########################################################################
58 // .... Creation et Acces de base aux donnees atomiques du fichier ....
59 typedef TCollection_HAsciiString String;
60 static char txtmes[200]; // plus commode que redeclarer partout
63 static Standard_Boolean initstr = Standard_False;
66 //static TCollection_AsciiString subl[Maxlst]; // Maxlst : minimum 10
68 static Standard_Integer acceptvoid = 0;
70 // ---------- Fonctions Utilitaires ----------
72 //=======================================================================
73 //function : CleanText
75 //=======================================================================
76 static void CleanText(const Handle(TCollection_HAsciiString)& val)
78 Standard_Integer n = val->Length(); // avant reduction
81 // Ne pas oublier de traiter les caracteres speciaux
82 for (Standard_Integer i = n - 2; i > 0; i--) {
83 char uncar = val->Value(i);
85 { val->Remove(i); if (i < n-2) uncar = val->Value(i); }
86 if (uncar == '\'' && i < n - 2) {
87 if (val->Value(i + 1) == '\'') { val->Remove(i + 1); continue; }
89 if (uncar == '\\' && i < n - 2) {
90 if (val->Value(i + 1) == '\\') { val->Remove(i + 1); continue; }
92 else if (uncar == '\\' && i < n - 3) {
93 if (val->Value(i + 2) == '\\') {
94 if (val->Value(i + 1) == 'N')
95 { val->SetValue(i,'\n'); val->Remove(i+1,2); continue; }
96 if (val->Value(i + 1) == 'T')
97 { val->SetValue(i,'\t'); val->Remove(i+1,2); continue; }
103 // ------------- METHODES -------------
105 //=======================================================================
106 //function : StepData_StepReaderData
108 //=======================================================================
110 StepData_StepReaderData::StepData_StepReaderData
111 (const Standard_Integer nbheader, const Standard_Integer nbtotal,
112 const Standard_Integer nbpar)
113 : Interface_FileReaderData(nbtotal, nbpar), theidents(1, nbtotal),
114 thetypes(1, nbtotal) //, themults (1,nbtotal)
117 thenbscop = 0; thenbents = 0; thelastn = 0; thenbhead = nbheader;
119 thecheck = new Interface_Check;
121 //for (Standard_Integer i = 0; i < Maxlst; i ++) {
122 // sprintf(textnum,"$%d",i+1);
123 // subl[i].AssignCat(textnum);
125 initstr = Standard_True;
129 //=======================================================================
130 //function : SetRecord
132 //=======================================================================
134 void StepData_StepReaderData::SetRecord(const Standard_Integer num,
135 const Standard_CString ident,
136 const Standard_CString type,
137 const Standard_Integer /* nbpar */)
139 Standard_Integer numlst;
141 if (strcmp(type,"/ * (SUB) * /") == 0) { // defini dans recfile.pc
142 thetypes.SetValue (num,sublist);
144 thenbents ++; // total de termes propres du fichier
145 thetypes.SetValue(num,TCollection_AsciiString(type));
146 // if (strcmp(ident,"SCOPE") != 0) thenbscop ++; // ?? a verifier
149 if (type[0] != '(') thenbents++; // total de termes propres du fichier
151 //thetypes.ChangeValue(num).SetValue(1,type); gka memory
152 //============================================
153 Standard_Integer index = 0;
154 TCollection_AsciiString strtype(type);
155 if (thenametypes.Contains(type))
156 index = thenametypes.FindIndex(strtype);
157 else index = thenametypes.Add(strtype);
158 thetypes.ChangeValue(num) = index;
159 //===========================================
161 if (ident[0] == '$') {
162 if (strlen(ident) > 2) numlst = atoi(&ident[1]);
163 else numlst = ident[1] - 48;
164 if (thelastn < numlst) thelastn = numlst; // plus fort n0 de sous-liste
165 theidents.SetValue(num, -2 - numlst);
166 } else if (ident[0] == '#') {
167 numlst = atoi(&ident[1]);
168 theidents.SetValue(num, numlst);
169 if (numlst == 0 && num > thenbhead) {
170 // Header, ou bien Type Complexe ...
171 // Si Type Complexe, retrouver Type Precedent (on considere que c est rare)
172 // On chaine le type precedent sur le suivant
173 // VERIFICATION que les types sont en ordre alphabetique
174 for (Standard_Integer prev = num - 1; prev > thenbhead; prev--) {
175 if (theidents(prev) >= 0) {
177 //themults.SetValue(prev,num);
178 themults.Bind(prev, num);
179 if (thenametypes.FindKey(thetypes.Value(num)).IsLess(thenametypes.FindKey(thetypes.Value(prev)))) {
180 // Warning: components in complex entity are not in alphabetical order.
181 TCollection_AsciiString errm("Complex Type incorrect : ");
182 errm.AssignCat(thenametypes.FindKey(thetypes.Value(prev)));
183 errm.AssignCat(" / ");
184 errm.AssignCat(thenametypes.FindKey(thetypes.Value(num)));
185 errm.AssignCat(" ... ");
187 while (theidents(prev) <= 0) {
188 prev--; if (prev <= 0) break;
190 Handle(Message_Messenger) sout = Message::DefaultMessenger();
191 sout << " *** Error on Record " << num << " (on " << NbRecords()
192 << " -> " << num * 100 / NbRecords() << " % in File) ***";
193 if (prev > 0) sout << " Ident #" << theidents(prev);
194 sout << "\n" << errm << Message_EndLine;
196 thecheck->AddWarning(errm.ToCString(), "Complex Type incorrect : ");
203 else if (!strcmp(ident, "SCOPE")) {
204 theidents.SetValue(num, -1); // SCOPE
207 else if (!strcmp(ident, "ENDSCOPE")) theidents.SetValue(num, -2); // ENDSCOPE
214 //=======================================================================
215 //function : AddStepParam
217 //=======================================================================
219 void StepData_StepReaderData::AddStepParam(const Standard_Integer num,
220 const Standard_CString aval,
221 const Interface_ParamType atype,
222 const Standard_Integer nument)
224 if (atype == Interface_ParamSub) {
225 Standard_Integer numid = 0;
226 if (aval[2] != '\0') {
227 numid = atoi(&aval[1]);
228 // if (numid <= Maxlst) Interface_FileReaderData::AddParam
229 // (num,subl[numid-1].ToCString(),atype,numid);
230 Interface_FileReaderData::AddParam(num, aval, atype, numid);
232 char *numlstchar = (char *)(aval + 1);
233 numid = (*numlstchar) - 48; // -48 ('0') -1 (adresse [] depuis 0)
234 // Interface_FileReaderData::AddParam (num,subl[numid].ToCString(),atype,numid);
235 Interface_FileReaderData::AddParam(num, aval, atype, numid);
237 } else if (atype == Interface_ParamIdent) {
238 Standard_Integer numid = atoi(&aval[1]);
239 Interface_FileReaderData::AddParam(num, aval, atype, numid);
241 Interface_FileReaderData::AddParam(num, aval, atype, nument);
244 // Interface_FileReaderData::AddParam (num,parval,atype,numid);
248 //=======================================================================
249 //function : RecordType
251 //=======================================================================
253 const TCollection_AsciiString& StepData_StepReaderData::RecordType
254 (const Standard_Integer num) const
256 return thenametypes.FindKey(thetypes.Value(num));
260 //=======================================================================
263 //=======================================================================
265 Standard_CString StepData_StepReaderData::CType(const Standard_Integer num) const
267 return thenametypes.FindKey(thetypes.Value(num)).ToCString();
271 //=======================================================================
272 //function : RecordIdent
274 //=======================================================================
276 Standard_Integer StepData_StepReaderData::RecordIdent(const Standard_Integer num) const
278 return theidents(num);
282 // ########################################################################
283 // .... Aides a la lecture des parametres, adaptees a STEP ....
286 //=======================================================================
287 //function : SubListNumber
289 //=======================================================================
291 Standard_Integer StepData_StepReaderData::SubListNumber(const Standard_Integer num,
292 const Standard_Integer nump,
293 const Standard_Boolean aslast) const
295 if (nump == 0 || nump > NbParams(num)) return 0;
296 const Interface_FileParameter& FP = Param(num, nump);
297 if (FP.ParamType() != Interface_ParamSub) return 0;
298 if (aslast) { if (nump != NbParams(num)) return 0; }
299 return FP.EntityNumber();
303 //=======================================================================
304 //function : IsComplex
306 //=======================================================================
308 Standard_Boolean StepData_StepReaderData::IsComplex(const Standard_Integer num) const
310 //return (themults(num) != 0);
311 return themults.IsBound(num);
315 //=======================================================================
316 //function : ComplexType
318 //=======================================================================
320 void StepData_StepReaderData::ComplexType(const Standard_Integer num,
321 TColStd_SequenceOfAsciiString& types) const
323 if (theidents(num) < 0) return;
324 for (Standard_Integer i = num; i > 0; i = NextForComplex(i)) {
325 types.Append(RecordType(i));
330 //=======================================================================
331 //function : NextForComplex
333 //=======================================================================
335 Standard_Integer StepData_StepReaderData::NextForComplex
336 (const Standard_Integer num) const
338 Standard_Integer next = 0;
339 if (themults.IsBound(num))
340 next = themults.Find(num);
344 //=======================================================================
345 //function : NamedForComplex
347 //=======================================================================
349 Standard_Boolean StepData_StepReaderData::NamedForComplex
350 (const Standard_CString name, const Standard_Integer num0,
351 Standard_Integer& num, Handle(Interface_Check)& ach) const
353 //Standard_Boolean stat = Standard_True;
354 Standard_Integer n = (num <= 0 ? num0 : NextForComplex(num));
355 // sln 04,10.2001. BUC61003. if(n==0) the next function is not called in order to avoid exception
356 if ((n != 0) && (!strcmp(RecordType(n).ToCString(), name)))
357 { num = n; return Standard_True; }
359 if (n == 0) /*stat =*/ NamedForComplex(name, num0, n, ach); // on a rembobine
360 // Pas dans l ordre alphabetique : boucler
361 Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
362 sprintf(txtmes, errmess->ToCString(), num0, name);
363 for (n = num0; n > 0; n = NextForComplex(n)) {
364 if (!strcmp(RecordType(n).ToCString(), name)) {
366 errmess = new String("Complex Record n0.%d, member type %s not in alphabetic order");
367 sprintf(txtmes, errmess->ToCString(), num0, name);
368 ach->AddWarning(txtmes, errmess->ToCString());
369 return Standard_False;
373 errmess = new String("Complex Record n0.%d, member type %s not found");
374 sprintf(txtmes, errmess->ToCString(), num0, name);
375 ach->AddFail(txtmes, errmess->ToCString());
376 return Standard_False;
379 //=======================================================================
380 //function : NamedForComplex
382 //=======================================================================
384 Standard_Boolean StepData_StepReaderData::NamedForComplex
385 (const Standard_CString theName, const Standard_CString theShortName,
386 const Standard_Integer num0, Standard_Integer& num,
387 Handle(Interface_Check)& ach) const
389 Standard_Integer n = (num <= 0 ? num0 : NextForComplex(num));
391 if ((n != 0) && (!strcmp(RecordType(n).ToCString(), theName) ||
392 !strcmp(RecordType(n).ToCString(), theShortName)))
395 return Standard_True;
398 //entities are not in alphabetical order
399 Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
400 sprintf(txtmes, errmess->ToCString(), num0, theName);
401 for (n = num0; n > 0; n = NextForComplex(n))
403 if (!strcmp(RecordType(n).ToCString(), theName) ||
404 !strcmp(RecordType(n).ToCString(), theShortName))
407 errmess = new String("Complex Record n0.%d, member type %s not in alphabetic order");
408 sprintf(txtmes, errmess->ToCString(), num0, theName);
409 ach->AddWarning(txtmes, errmess->ToCString());
410 return Standard_False;
414 errmess = new String("Complex Record n0.%d, member type %s not found");
415 sprintf(txtmes, errmess->ToCString(), num0, theName);
416 ach->AddFail(txtmes, errmess->ToCString());
417 return Standard_False;
420 // ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
423 //=======================================================================
424 //function : CheckNbParams
426 //=======================================================================
428 Standard_Boolean StepData_StepReaderData::CheckNbParams(const Standard_Integer num,
429 const Standard_Integer nbreq,
430 Handle(Interface_Check)& ach,
431 const Standard_CString mess) const
433 if (NbParams(num) == nbreq) return Standard_True;
434 Handle(String) errmess;
435 if (mess[0] == '\0') errmess = new String("Count of Parameters is not %d");
436 else errmess = new String("Count of Parameters is not %d for %s");
437 sprintf(txtmes, errmess->ToCString(), nbreq, mess);
438 ach->AddFail(txtmes, errmess->ToCString());
439 return Standard_False;
443 //=======================================================================
444 //function : ReadSubList
446 //=======================================================================
448 Standard_Boolean StepData_StepReaderData::ReadSubList(const Standard_Integer num,
449 const Standard_Integer nump,
450 const Standard_CString mess,
451 Handle(Interface_Check)& ach,
452 Standard_Integer& numsub,
453 const Standard_Boolean optional,
454 const Standard_Integer /* lenmin */,
455 const Standard_Integer /* lenmax */) const
457 numsub = SubListNumber(num, nump, Standard_False);
460 return (NbParams(numsub) > 0);
462 // Si optionel indefini, on passe l eponge
464 Standard_Boolean isvoid = (Param(num, nump).ParamType() == Interface_ParamVoid);
465 if (isvoid && optional) return Standard_False;
467 Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
468 sprintf(txtmes, errmess->ToCString(), nump, mess);
469 if (acceptvoid && isvoid) ach->AddWarning(txtmes, errmess->ToCString());
470 else { ach->AddFail(txtmes, errmess->ToCString()); return Standard_False; }
471 return Standard_True;
475 // ... Facilites pour LateBinding
478 //=======================================================================
481 //=======================================================================
483 Standard_Integer StepData_StepReaderData::ReadSub(const Standard_Integer numsub,
484 const Standard_CString mess,
485 Handle(Interface_Check)& ach,
486 const Handle(StepData_PDescr)& descr,
487 Handle(Standard_Transient)& val) const
489 Standard_Integer nbp = NbParams(numsub);
490 if (nbp == 0) return 0; // liste vide = Handle Null
491 const TCollection_AsciiString& rectyp = RecordType(numsub);
492 if (nbp == 1 && rectyp.ToCString()[0] != '(') {
493 // c est un type avec un parametre -> SelectNamed
494 // cf ReadSelect mais ici, on est deja sur le contenu du parametre
495 Handle(StepData_SelectNamed) sn = new StepData_SelectNamed;
497 sn->SetName(rectyp.ToCString());
498 Handle(Standard_Transient) aSN = sn;
499 if (ReadAny(numsub, 1, mess, ach, descr, aSN)) return sn->Kind();
503 // cas courant : faire un HArray1 de ... de ... de quoi au fait
504 const Interface_FileParameter& FP0 = Param(numsub, 1);
505 Interface_ParamType FT, FT0 = FP0.ParamType();
506 Standard_CString str = FP0.CValue();
507 Handle(TColStd_HArray1OfTransient) htr;
508 Handle(TColStd_HArray1OfInteger) hin;
509 Handle(TColStd_HArray1OfReal) hre;
510 Handle(Interface_HArray1OfHAsciiString) hst;
511 Standard_Integer kod = 0;
513 case Interface_ParamMisc: return -1;
514 case Interface_ParamInteger: kod = 1; break;
515 case Interface_ParamReal: kod = 5; break;
516 case Interface_ParamIdent: kod = 7; break;
517 case Interface_ParamVoid: kod = 0; break;
518 case Interface_ParamText: kod = 6; break;
519 case Interface_ParamEnum: kod = 4; break; // a confirmer(logical)
521 if ( str[0] == '.' && str[2] == '.' && str[3] == '\0' &&
522 (str[1] == 'T' || str[1] == 'F' || str[1] == 'U') ) kod = 3;
524 case Interface_ParamLogical: return -1;
525 case Interface_ParamSub: kod = 0; break;
526 case Interface_ParamHexa: return -1;
527 case Interface_ParamBinary: return -1;
530 if (kod == 1 || kod == 3) { hin = new TColStd_HArray1OfInteger(1, nbp); val = hin; }
531 else if (kod == 5) { hre = new TColStd_HArray1OfReal(1, nbp); val = hre; }
532 else if (kod == 6) { hst = new Interface_HArray1OfHAsciiString(1, nbp); val = hst; }
533 else { htr = new TColStd_HArray1OfTransient(1, nbp); val = htr; }
534 // Attention : si type variable, faudra changer son fusil d epaule -> htr
536 for (Standard_Integer ip = 1; ip <= nbp; ip++) {
537 const Interface_FileParameter& FP = Param(numsub, ip);
542 if (FT != Interface_ParamInteger) { kod = 0; break; }
543 hin->SetValue(ip, atoi(str)); break;
547 if (FT != Interface_ParamEnum) { kod = 0; break; }
548 if (!strcmp(str, ".F.")) hin->SetValue(ip, 0);
549 else if (!strcmp(str, ".T.")) hin->SetValue(ip, 1);
550 else if (!strcmp(str, ".U.")) hin->SetValue(ip, 2);
555 if (FT != Interface_ParamEnum) { kod = 0; break; }
556 Handle(StepData_SelectNamed) sn = new StepData_SelectNamed;
557 sn->SetEnum(-1, str);
558 htr->SetValue(ip, sn); break;
561 if (FT != Interface_ParamReal) { kod = 0; break; }
562 hre->SetValue(ip, Interface_FileReaderData::Fastof(str)); break;
565 if (FT != Interface_ParamText) { kod = 0; break; }
566 Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
567 CleanText(txt); hst->SetValue(ip, txt); break;
570 Handle(Standard_Transient) ent = BoundEntity(FP.EntityNumber());
571 htr->SetValue(ip, ent); break;
575 // Restent les autres cas ... tout est possible. cf le type du Param
576 if (kod > 0) continue;
577 // Il faut passer au transient ...
579 htr = new TColStd_HArray1OfTransient(1, nbp); val = htr;
582 for (jp = 1; jp < ip; jp++) {
583 Handle(StepData_SelectInt) sin = new StepData_SelectInt;
584 sin->SetInt(hin->Value(jp));
585 htr->SetValue(jp, sin);
589 for (jp = 1; jp < ip; jp++) {
590 Handle(StepData_SelectReal) sre = new StepData_SelectReal;
591 sre->SetReal(hre->Value(jp));
592 htr->SetValue(jp, sre);
596 for (jp = 1; jp < ip; jp++) {
597 htr->SetValue(jp, hst->Value(jp));
601 // A present, faut y aller : lire le champ et le mettre en place
602 // Ce qui suit ressemble fortement a ReadAny ...
605 case Interface_ParamMisc: break;
606 case Interface_ParamInteger: {
607 Handle(StepData_SelectInt) sin = new StepData_SelectInt;
608 sin->SetInteger(atoi(str));
609 htr->SetValue(ip, sin); break;
611 case Interface_ParamReal: {
612 Handle(StepData_SelectReal) sre = new StepData_SelectReal;
613 sre->SetReal(Interface_FileReaderData::Fastof(str)); break;
614 //htr->SetValue (ip,sre); break; svv #2: unreachable
616 case Interface_ParamIdent: htr->SetValue(ip, BoundEntity(FP.EntityNumber())); break;
617 case Interface_ParamVoid: break;
618 case Interface_ParamEnum: {
619 Handle(StepData_SelectInt) sin;
620 Handle(StepData_SelectNamed) sna;
621 Standard_Integer logic = -1;
623 // set the default value of StepData_Logical
624 StepData_Logical slog = StepData_LUnknown;
625 if (str[0] == '.' && str[2] == '.' && str[3] == '\0') {
626 if (str[1] == 'F') { slog = StepData_LFalse; logic = 0; }
627 else if (str[1] == 'T') { slog = StepData_LTrue; logic = 1; }
628 else if (str[1] == 'U') { slog = StepData_LUnknown; logic = 2; }
631 { sin = new StepData_SelectInt; sin->SetLogical(slog); htr->SetValue(ip,sin); }
632 else { sna = new StepData_SelectNamed;
633 sna->SetEnum (logic,str); htr->SetValue (ip,sna); }
636 case Interface_ParamLogical: break;
637 case Interface_ParamText: {
638 Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
639 CleanText(txt); htr->SetValue(ip, txt); break;
641 case Interface_ParamSub: {
642 Handle(Standard_Transient) sub;
643 Standard_Integer nent = FP.EntityNumber();
644 Standard_Integer kind = ReadSub(nent, mess, ach, descr, sub); if (kind < 0) break;
645 htr->SetValue(ip, sub); break;
647 case Interface_ParamHexa: break;
648 case Interface_ParamBinary: break;
653 return 8; // pour Any
657 //=======================================================================
658 //function : ReadMember
660 //=======================================================================
662 Standard_Boolean StepData_StepReaderData::ReadMember(const Standard_Integer num,
663 const Standard_Integer nump,
664 const Standard_CString mess,
665 Handle(Interface_Check)& ach,
666 Handle(StepData_SelectMember)& val) const
668 Handle(Standard_Transient) v = val;
669 Handle(StepData_PDescr) nuldescr;
672 return ReadAny(num, nump, mess, ach, nuldescr, v) &&
673 !(val = Handle(StepData_SelectMember)::DownCast(v)).IsNull();
675 Standard_Boolean res = ReadAny(num, nump, mess, ach, nuldescr, v);
676 if (v == val) return res;
677 // changement -> refus
678 Handle(String) errmess =
679 new String("Parameter n0.%d (%s) : does not match SELECT clause");
680 sprintf(txtmes, errmess->ToCString(), nump, mess);
681 ach->AddFail(txtmes, errmess->ToCString());
682 return Standard_False;
686 //=======================================================================
687 //function : ReadField
689 //=======================================================================
691 Standard_Boolean StepData_StepReaderData::ReadField(const Standard_Integer num,
692 const Standard_Integer nump,
693 const Standard_CString mess,
694 Handle(Interface_Check)& ach,
695 const Handle(StepData_PDescr)& descr,
696 StepData_Field& fild) const
698 const Interface_FileParameter& FP = Param(num, nump);
699 Standard_CString str = FP.CValue();
700 Standard_Boolean OK = Standard_True;
701 Standard_Integer nent, kind;
702 Handle(TCollection_HAsciiString) txt;
703 Handle(Standard_Transient) sub;
704 Interface_ParamType FT = FP.ParamType();
706 case Interface_ParamMisc: OK = Standard_False; break;
707 case Interface_ParamInteger: fild.SetInteger(atoi(str)); break;
708 case Interface_ParamReal:
709 fild.SetReal(Interface_FileReaderData::Fastof(str)); break;
710 case Interface_ParamIdent:
711 nent = FP.EntityNumber();
712 if (nent > 0) fild.SetEntity(BoundEntity(nent));
714 case Interface_ParamVoid: break;
715 case Interface_ParamText:
716 txt = new TCollection_HAsciiString(str);
717 CleanText(txt); fild.Set(txt); break;
718 case Interface_ParamEnum:
719 if (!strcmp(str, ".T.")) fild.SetLogical(StepData_LTrue);
720 else if (!strcmp(str, ".F.")) fild.SetLogical(StepData_LFalse);
721 else if (!strcmp(str, ".U.")) fild.SetLogical(StepData_LUnknown);
722 else fild.SetEnum(-1, str);
724 case Interface_ParamLogical: OK = Standard_False; break;
725 case Interface_ParamSub:
726 nent = FP.EntityNumber();
727 kind = ReadSub(nent, mess, ach, descr, sub); if (kind < 0) break;
728 fild.Clear(kind); fild.Set(sub); break;
729 case Interface_ParamHexa: OK = Standard_False; break;
730 case Interface_ParamBinary: OK = Standard_False; break;
731 default: OK = Standard_False; break;
735 if (!strcmp(str, "*")) fild.SetDerived();
737 return Standard_True;
741 //=======================================================================
742 //function : ReadList
744 //=======================================================================
746 Standard_Boolean StepData_StepReaderData::ReadList(const Standard_Integer num,
747 Handle(Interface_Check)& ach,
748 const Handle(StepData_ESDescr)& descr,
749 StepData_FieldList& list) const
751 // controler nbs egaux
752 Standard_Integer i, nb = list.NbFields();
753 if (!CheckNbParams(num, nb, ach, descr->TypeName())) return Standard_False;
754 for (i = 1; i <= nb; i++) {
755 Handle(StepData_PDescr) pde = descr->Field(i);
756 StepData_Field& fild = list.CField(i);
757 ReadField(num, i, pde->Name(), ach, pde, fild);
759 return Standard_True;
763 //=======================================================================
766 //=======================================================================
768 Standard_Boolean StepData_StepReaderData::ReadAny(const Standard_Integer num,
769 const Standard_Integer nump,
770 const Standard_CString mess,
771 Handle(Interface_Check)& ach,
772 const Handle(StepData_PDescr)& descr,
773 Handle(Standard_Transient)& val) const
775 const Interface_FileParameter& FP = Param(num, nump);
776 Standard_CString str = FP.CValue();
777 Interface_ParamType FT = FP.ParamType();
779 // A present, faut y aller : lire le champ et le mettre en place
781 case Interface_ParamMisc: break;
782 case Interface_ParamInteger: {
784 DeclareAndCast(StepData_SelectMember, sm, val);
785 sm->SetInteger(atoi(str));
786 return Standard_True;
788 Handle(StepData_SelectInt) sin = new StepData_SelectInt;
789 sin->SetInteger(atoi(str));
791 return Standard_True;
793 case Interface_ParamReal: {
795 DeclareAndCast(StepData_SelectMember, sm, val);
796 sm->SetReal(Interface_FileReaderData::Fastof(str));
797 return Standard_True;
799 Handle(StepData_SelectReal) sre = new StepData_SelectReal;
800 sre->SetReal(Interface_FileReaderData::Fastof(str));
802 return Standard_True;
804 case Interface_ParamIdent: {
805 Standard_Integer nent = FP.EntityNumber();
806 if (nent > 0) val = BoundEntity(nent);
807 return (!val.IsNull());
809 case Interface_ParamVoid: break;
810 case Interface_ParamEnum: {
811 Handle(StepData_SelectMember) sm;
812 if (!val.IsNull()) sm = GetCasted(StepData_SelectMember, val);
813 Handle(StepData_SelectInt) sin;
814 Handle(StepData_SelectNamed) sna;
815 Standard_Integer logic = -1;
818 // set the default value of StepData_Logical
819 StepData_Logical slog = StepData_LUnknown;
820 if (str[0] == '.' && str[2] == '.' && str[3] == '\0') {
821 if (str[1] == 'F') { slog = StepData_LFalse; logic = 0; }
822 else if (str[1] == 'T') { slog = StepData_LTrue; logic = 1; }
823 else if (str[1] == 'U') { slog = StepData_LUnknown; logic = 2; }
826 if (!sm.IsNull()) sm->SetLogical(slog);
828 sin = new StepData_SelectInt; val = sin;
829 sin->SetLogical(slog);
833 if (!sm.IsNull()) sm->SetEnum(logic, str);
835 sna = new StepData_SelectNamed; val = sna; // Named sans nom...
836 sna->SetEnum(logic, str);
838 } // -> Select general
839 return Standard_True;
841 case Interface_ParamLogical: break;
842 case Interface_ParamText: {
843 Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
846 // PDN May 2000: for reading SOURCE_ITEM (external references)
848 DeclareAndCast(StepData_SelectMember, sm, val);
849 sm->SetString(txt->ToCString());
850 return Standard_True;
854 return Standard_True;
856 case Interface_ParamSub: {
857 Standard_Integer numsub = SubListNumber(num, nump, Standard_False);
858 Standard_Integer nbp = NbParams(numsub);
859 if (nbp == 0) return Standard_False; // liste vide = Handle Null
860 const TCollection_AsciiString& rectyp = RecordType(numsub);
861 if (nbp == 1 && rectyp.ToCString()[0] != '(') {
862 // SelectNamed because Field !!!
863 // skl 15.01.2003 (for members with array of real)
864 DeclareAndCast(StepData_SelectArrReal, sma, val);
866 Standard_Integer numsub2 = SubListNumber(numsub, 1, Standard_False);
867 Standard_Integer nbp2 = NbParams(numsub2);
869 if (Param(numsub2, 1).ParamType() == Interface_ParamReal) {
870 if (!sma->SetName(rectyp.ToCString())) return Standard_False;
871 Handle(TColStd_HSequenceOfReal) aSeq = new TColStd_HSequenceOfReal;
872 for (Standard_Integer i = 1; i <= nbp2; i++) {
873 if (Param(numsub2, i).ParamType() != Interface_ParamReal) continue;
874 Handle(Standard_Transient) asr = new StepData_SelectReal;
875 if (!ReadAny(numsub2, i, mess, ach, descr, asr)) continue;
876 Handle(StepData_SelectReal) sm1 = Handle(StepData_SelectReal)::DownCast(asr);
878 aSeq->Append(sm1->Real());
880 Handle(TColStd_HArray1OfReal) anArr = new TColStd_HArray1OfReal(1, aSeq->Length());
881 for (Standard_Integer nr = 1; nr <= aSeq->Length(); nr++) {
882 anArr->SetValue(nr, aSeq->Value(nr));
884 sma->SetArrReal(anArr);
885 return Standard_True;
889 DeclareAndCast(StepData_SelectMember, sm, val);
891 sm = new StepData_SelectNamed;
894 if (!sm->SetName(rectyp.ToCString())) return Standard_False; // loupe
895 return ReadAny(numsub, 1, mess, ach, descr, val);
900 return Standard_False;
907 //=======================================================================
910 //=======================================================================
912 Standard_Boolean StepData_StepReaderData::ReadXY(const Standard_Integer num,
913 const Standard_Integer nump,
914 const Standard_CString mess,
915 Handle(Interface_Check)& ach,
916 Standard_Real& X, Standard_Real& Y) const
918 Handle(String) errmess; // Null si pas d erreur
919 Standard_Integer numsub = SubListNumber(num, nump, Standard_False);
921 if (NbParams(numsub) == 2) {
922 const Interface_FileParameter& FPX = Param(numsub, 1);
923 if (FPX.ParamType() == Interface_ParamReal) X =
924 Interface_FileReaderData::Fastof(FPX.CValue());
925 else errmess = new String("Parameter n0.%d (%s) : (X,Y) X not a Real");
927 const Interface_FileParameter& FPY = Param(numsub, 2);
928 if (FPY.ParamType() == Interface_ParamReal) Y =
929 Interface_FileReaderData::Fastof(FPY.CValue());
930 else errmess = new String("Parameter n0.%d (%s) : (X,Y) Y not a Real");
933 else errmess = new String("Parameter n0.%d (%s) : (X,Y) has not 2 params");
935 else errmess = new String("Parameter n0.%d (%s) : (X,Y) not a SubList");
937 if (errmess.IsNull()) return Standard_True;
938 sprintf(txtmes, errmess->ToCString(), nump, mess);
939 ach->AddFail(txtmes, errmess->ToCString());
940 return Standard_False;
944 //=======================================================================
947 //=======================================================================
949 Standard_Boolean StepData_StepReaderData::ReadXYZ(const Standard_Integer num,
950 const Standard_Integer nump,
951 const Standard_CString mess,
952 Handle(Interface_Check)& ach,
953 Standard_Real& X, Standard_Real& Y,
954 Standard_Real& Z) const
956 Handle(String) errmess; // Null si pas d erreur
957 Standard_Integer numsub = SubListNumber(num, nump, Standard_False);
959 if (NbParams(numsub) == 3) {
960 const Interface_FileParameter& FPX = Param(numsub, 1);
961 if (FPX.ParamType() == Interface_ParamReal) X =
962 Interface_FileReaderData::Fastof(FPX.CValue());
963 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) X not a Real");
965 const Interface_FileParameter& FPY = Param(numsub, 2);
966 if (FPY.ParamType() == Interface_ParamReal) Y =
967 Interface_FileReaderData::Fastof(FPY.CValue());
968 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) Y not a Real");
970 const Interface_FileParameter& FPZ = Param(numsub, 3);
971 if (FPZ.ParamType() == Interface_ParamReal) Z =
972 Interface_FileReaderData::Fastof(FPZ.CValue());
973 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) Z not a Real");
976 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) has not 3 params");
978 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) not a SubList");
980 if (errmess.IsNull()) return Standard_True;
981 sprintf(txtmes, errmess->ToCString(), nump, mess);
982 ach->AddFail(txtmes, errmess->ToCString());
983 return Standard_False;
987 //=======================================================================
988 //function : ReadReal
990 //=======================================================================
992 Standard_Boolean StepData_StepReaderData::ReadReal(const Standard_Integer num,
993 const Standard_Integer nump,
994 const Standard_CString mess,
995 Handle(Interface_Check)& ach,
996 Standard_Real& val) const
998 Handle(String) errmess; // Null si pas d erreur
999 if (nump > 0 && nump <= NbParams(num)) {
1000 const Interface_FileParameter& FP = Param(num, nump);
1001 if (FP.ParamType() == Interface_ParamReal || FP.ParamType() == Interface_ParamInteger)
1002 val = Interface_FileReaderData::Fastof(FP.CValue());
1003 else errmess = new String("Parameter n0.%d (%s) not a Real");
1005 else errmess = new String("Parameter n0.%d (%s) absent");
1007 if (errmess.IsNull()) return Standard_True;
1008 sprintf(txtmes, errmess->ToCString(), nump, mess);
1009 ach->AddFail(txtmes, errmess->ToCString());
1010 return Standard_False;
1014 // ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1017 //=======================================================================
1018 //function : ReadEntity
1020 //=======================================================================
1022 Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num,
1023 const Standard_Integer nump,
1024 const Standard_CString mess,
1025 Handle(Interface_Check)& ach,
1026 const Handle(Standard_Type)& atype,
1027 Handle(Standard_Transient)& ent) const
1029 Handle(String) errmess; // Null si pas d erreur
1030 Standard_Boolean warn = Standard_False;
1031 if (nump > 0 && nump <= NbParams(num)) {
1032 const Interface_FileParameter& FP = Param(num, nump);
1033 Standard_Integer nent = FP.EntityNumber();
1034 if (FP.ParamType() == Interface_ParamIdent) {
1035 warn = (acceptvoid > 0);
1037 Handle(Standard_Transient) entent = BoundEntity(nent);
1038 if (entent.IsNull() || !entent->IsKind(atype))
1040 errmess = new String("Parameter n0.%d (%s) : Entity has illegal type");
1041 if (!entent.IsNull() && entent->IsKind(STANDARD_TYPE(StepData_UndefinedEntity)))
1046 else errmess = new String("Parameter n0.%d (%s) : Unresolved reference");
1049 if (acceptvoid && FP.ParamType() == Interface_ParamVoid) warn = Standard_True;
1050 errmess = new String("Parameter n0.%d (%s) not an Entity");
1054 warn = (acceptvoid > 0);
1055 errmess = new String("Parameter n0.%d (%s) absent");
1058 if (errmess.IsNull()) return Standard_True;
1059 sprintf(txtmes, errmess->ToCString(), nump, mess);
1060 if (warn) ach->AddWarning(txtmes, errmess->ToCString());
1061 else ach->AddFail(txtmes, errmess->ToCString());
1062 return Standard_False;
1066 //=======================================================================
1067 //function : ReadEntity
1069 //=======================================================================
1071 Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num,
1072 const Standard_Integer nump,
1073 const Standard_CString mess,
1074 Handle(Interface_Check)& ach,
1075 StepData_SelectType& sel) const
1077 Handle(String) errmess; // Null si pas d erreur
1078 Standard_Boolean warn = Standard_False;
1079 if (nump > 0 && nump <= NbParams(num)) {
1080 const Interface_FileParameter& FP = Param(num, nump);
1081 Standard_Integer nent = FP.EntityNumber();
1082 if (FP.ParamType() == Interface_ParamIdent) {
1083 warn = (acceptvoid > 0);
1085 Handle(Standard_Transient) entent = BoundEntity(nent);
1086 if (!sel.Matches(entent))
1088 errmess = new String("Parameter n0.%d (%s) : Entity has illegal type");
1089 //fot not suppported STEP entity
1090 if (!entent.IsNull() && entent->IsKind(STANDARD_TYPE(StepData_UndefinedEntity)))
1091 sel.SetValue(entent);
1094 sel.SetValue(entent);
1097 errmess = new String("Parameter n0.%d (%s) : Unresolved reference");
1099 else if (FP.ParamType() == Interface_ParamVoid) {
1100 if (acceptvoid) warn = Standard_True;
1101 errmess = new String("Parameter n0.%d (%s) not an Entity");
1104 // Cas restant : on s interesse en fait au SelectMember ...
1105 Handle(Standard_Transient) sm = sel.NewMember();
1106 // SelectMember qui assure ce role. Peut etre specialise
1107 if (!ReadAny(num, nump, mess, ach, sel.Description(), sm))
1108 errmess = new String("Parameter n0.%d (%s) : could not be read");
1109 if (!sel.Matches(sm))
1110 errmess = new String("Parameter n0.%d (%s) : illegal parameter type");
1116 warn = (acceptvoid > 0);
1117 errmess = new String("Parameter n0.%d (%s) absent");
1120 if (errmess.IsNull()) return Standard_True;
1121 sprintf(txtmes, errmess->ToCString(), nump, mess);
1122 if (warn) ach->AddWarning(txtmes, errmess->ToCString());
1123 else ach->AddFail(txtmes, errmess->ToCString());
1124 return Standard_False;
1128 // ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1131 //=======================================================================
1132 //function : ReadInteger
1134 //=======================================================================
1136 Standard_Boolean StepData_StepReaderData::ReadInteger(const Standard_Integer num,
1137 const Standard_Integer nump,
1138 const Standard_CString mess,
1139 Handle(Interface_Check)& ach,
1140 Standard_Integer& val) const
1142 Handle(String) errmess; // Null si pas d erreur
1143 if (nump > 0 && nump <= NbParams(num)) {
1144 const Interface_FileParameter& FP = Param(num, nump);
1145 if (FP.ParamType() == Interface_ParamInteger) val = atoi(FP.CValue());
1146 else errmess = new String("Parameter n0.%d (%s) not an Integer");
1148 else errmess = new String("Parameter n0.%d (%s) absent");
1150 if (errmess.IsNull()) return Standard_True;
1151 sprintf(txtmes, errmess->ToCString(), nump, mess);
1152 ach->AddFail(txtmes, errmess->ToCString());
1153 return Standard_False;
1157 //=======================================================================
1158 //function : ReadBoolean
1160 //=======================================================================
1162 Standard_Boolean StepData_StepReaderData::ReadBoolean(const Standard_Integer num,
1163 const Standard_Integer nump,
1164 const Standard_CString mess,
1165 Handle(Interface_Check)& ach,
1166 Standard_Boolean& flag) const
1168 flag = Standard_True;
1169 Handle(String) errmess; // Null si pas d erreur
1170 if (nump > 0 && nump <= NbParams(num)) {
1171 const Interface_FileParameter& FP = Param(num, nump);
1172 if (FP.ParamType() == Interface_ParamEnum) {
1173 Standard_CString txt = FP.CValue();
1174 if (!strcmp(txt, ".T.")) flag = Standard_True;
1175 else if (!strcmp(txt, ".F.")) flag = Standard_False;
1176 else errmess = new String("Parameter n0.%d (%s) : Incorrect Boolean Value. It was set to true");
1178 else errmess = new String("Parameter n0.%d (%s) not a Boolean. It was set to true");
1180 else errmess = new String("Parameter n0.%d (%s) absent.It was set to true");
1182 if (errmess.IsNull()) return Standard_True;
1183 sprintf(txtmes, errmess->ToCString(), nump, mess);
1184 ach->AddFail(txtmes, errmess->ToCString());
1185 return Standard_False;
1189 //=======================================================================
1190 //function : ReadLogical
1192 //=======================================================================
1194 Standard_Boolean StepData_StepReaderData::ReadLogical(const Standard_Integer num,
1195 const Standard_Integer nump,
1196 const Standard_CString mess,
1197 Handle(Interface_Check)& ach,
1198 StepData_Logical& flag) const
1200 Handle(String) errmess; // Null si pas d erreur
1201 if (nump > 0 && nump <= NbParams(num)) {
1202 const Interface_FileParameter& FP = Param(num, nump);
1203 if (FP.ParamType() == Interface_ParamEnum) {
1204 Standard_CString txt = FP.CValue();
1205 if (!strcmp(txt, ".T.")) flag = StepData_LTrue;
1206 else if (!strcmp(txt, ".F.")) flag = StepData_LFalse;
1207 else if (!strcmp(txt, ".U.")) flag = StepData_LUnknown;
1208 else errmess = new String("Parameter n0.%d (%s) : Incorrect Logical Value");
1210 else errmess = new String("Parameter n0.%d (%s) not a Logical");
1212 else errmess = new String("Parameter n0.%d (%s) absent");
1214 if (errmess.IsNull()) return Standard_True;
1215 sprintf(txtmes, errmess->ToCString(), nump, mess);
1216 ach->AddFail(txtmes, errmess->ToCString());
1217 return Standard_False;
1221 //=======================================================================
1222 //function : ReadString
1224 //=======================================================================
1226 Standard_Boolean StepData_StepReaderData::ReadString(const Standard_Integer num,
1227 const Standard_Integer nump,
1228 const Standard_CString mess,
1229 Handle(Interface_Check)& ach,
1230 Handle(TCollection_HAsciiString)& val) const
1232 Handle(String) errmess; // Null si pas d erreur
1233 Standard_Boolean warn = Standard_False;
1234 if (nump > 0 && nump <= NbParams(num)) {
1235 const Interface_FileParameter& FP = Param(num, nump);
1236 if (FP.ParamType() == Interface_ParamText) {
1237 /*Standard_CString anStr = FP.CValue();
1238 if(strlen(anStr) < 3)
1239 val = new TCollection_HAsciiString("");
1241 val = new TCollection_HAsciiString(FP.CValue());
1244 val = new TCollection_HAsciiString(FP.CValue());
1247 if (acceptvoid && FP.ParamType() == Interface_ParamVoid) warn = Standard_True;
1248 errmess = new String("Parameter n0.%d (%s) not a quoted String");
1251 else errmess = new String("Parameter n0.%d (%s) absent");
1253 if (errmess.IsNull()) return Standard_True;
1254 sprintf(txtmes, errmess->ToCString(), nump, mess);
1255 if (warn) ach->AddWarning(txtmes, errmess->ToCString());
1256 else ach->AddFail(txtmes, errmess->ToCString());
1257 return Standard_False;
1261 //=======================================================================
1262 //function : ReadEnumParam
1264 //=======================================================================
1266 Standard_Boolean StepData_StepReaderData::ReadEnumParam(const Standard_Integer num,
1267 const Standard_Integer nump,
1268 const Standard_CString mess,
1269 Handle(Interface_Check)& ach,
1270 Standard_CString& text) const
1272 Handle(String) errmess; // Null si pas d erreur
1273 Standard_Boolean warn = Standard_False;
1274 if (nump > 0 && nump <= NbParams(num)) {
1275 const Interface_FileParameter& FP = Param(num, nump);
1276 if (FP.ParamType() == Interface_ParamEnum) {
1278 warn = (acceptvoid > 0);
1279 } else if (FP.ParamType() == Interface_ParamVoid) {
1281 new String("Parameter n0.%d (%s) : Undefined Enumeration not allowed");
1282 warn = (acceptvoid > 0);
1284 else errmess = new String("Parameter n0.%d (%s) not an Enumeration");
1286 else errmess = new String("Parameter n0.%d (%s) absent");
1288 if (errmess.IsNull()) return Standard_True;
1289 sprintf(txtmes, errmess->ToCString(), nump, mess);
1290 if (warn) ach->AddWarning(txtmes, errmess->ToCString());
1291 else ach->AddFail(txtmes, errmess->ToCString());
1292 return Standard_False;
1296 //=======================================================================
1297 //function : FailEnumValue
1299 //=======================================================================
1301 void StepData_StepReaderData::FailEnumValue(const Standard_Integer /* num */,
1302 const Standard_Integer nump,
1303 const Standard_CString mess,
1304 Handle(Interface_Check)& ach) const
1306 Handle(String) errmess =
1307 new String("Parameter n0.%d (%s) : Incorrect Enumeration Value");
1308 sprintf(txtmes, errmess->ToCString(), nump, mess);
1309 ach->AddFail(txtmes, errmess->ToCString());
1313 //=======================================================================
1314 //function : ReadEnum
1316 //=======================================================================
1318 Standard_Boolean StepData_StepReaderData::ReadEnum(const Standard_Integer num,
1319 const Standard_Integer nump,
1320 const Standard_CString mess,
1321 Handle(Interface_Check)& ach,
1322 const StepData_EnumTool& enumtool,
1323 Standard_Integer& val) const
1325 // reprendre avec ReadEnumParam ?
1326 Handle(String) errmess; // Null si pas d erreur
1327 Standard_Boolean warn = Standard_False;
1328 if (nump > 0 && nump <= NbParams(num)) {
1329 const Interface_FileParameter& FP = Param(num, nump);
1330 if (FP.ParamType() == Interface_ParamEnum) {
1331 val = enumtool.Value(FP.CValue());
1332 if (val >= 0) return Standard_True;
1333 else errmess = new String("Parameter n0.%d (%s) : Incorrect Enumeration Value");
1334 warn = (acceptvoid > 0);
1336 else if (FP.ParamType() == Interface_ParamVoid) {
1337 val = enumtool.NullValue();
1338 if (val < 0) errmess =
1339 new String("Parameter n0.%d (%s) : Undefined Enumeration not allowed");
1340 warn = (acceptvoid > 0);
1342 else errmess = new String("Parameter n0.%d (%s) not an Enumeration");
1344 else errmess = new String("Parameter n0.%d (%s) absent");
1346 if (errmess.IsNull()) return Standard_True;
1347 sprintf(txtmes, errmess->ToCString(), nump, mess);
1349 ach->AddWarning(txtmes, errmess->ToCString());
1351 ach->AddFail(txtmes, errmess->ToCString());
1352 return Standard_False;
1356 //=======================================================================
1357 //function : ReadTypedParam
1359 //=======================================================================
1361 Standard_Boolean StepData_StepReaderData::ReadTypedParam(const Standard_Integer num,
1362 const Standard_Integer nump,
1363 const Standard_Boolean mustbetyped,
1364 const Standard_CString mess,
1365 Handle(Interface_Check)& ach,
1366 Standard_Integer& numr,
1367 Standard_Integer& numrp,
1368 TCollection_AsciiString& typ) const
1370 Handle(String) errmess; // Null si pas d erreur
1371 if (nump > 0 && nump <= NbParams(num)) {
1372 const Interface_FileParameter& FP = Param(num, nump);
1373 if (FP.ParamType() != Interface_ParamSub) {
1374 // Pas une sous-liste : OK si admis
1375 numr = num; numrp = nump; typ.Clear();
1377 errmess = new String("Parameter n0.%d (%s) : single, not typed");
1378 sprintf(txtmes, errmess->ToCString(), nump, mess);
1379 ach->AddFail(txtmes, errmess->ToCString());
1380 return Standard_False;
1382 return Standard_True;
1384 numr = FP.EntityNumber(); numrp = 1;
1385 if (NbParams(numr) != 1) errmess =
1386 new String("Parameter n0.%d (%s) : SubList, not typed");
1387 typ = RecordType(numr);
1389 else errmess = new String("Parameter n0.%d (%s) absent");
1391 if (errmess.IsNull()) return Standard_True;
1392 sprintf(txtmes, errmess->ToCString(), nump, mess);
1393 ach->AddFail(txtmes, errmess->ToCString());
1394 return Standard_False;
1398 //=======================================================================
1399 //function : CheckDerived
1401 //=======================================================================
1403 Standard_Boolean StepData_StepReaderData::CheckDerived(const Standard_Integer num,
1404 const Standard_Integer nump,
1405 const Standard_CString mess,
1406 Handle(Interface_Check)& ach,
1407 const Standard_Boolean errstat) const
1409 Handle(String) errmess; // Null si pas d erreur
1410 Standard_Boolean warn = !errstat;
1411 if (nump > 0 && nump <= NbParams(num)) {
1412 if (!strcmp(Param(num, nump).CValue(), "*")) return Standard_True;
1413 else errmess = new String("Parameter n0.%d (%s) not Derived");
1414 if (acceptvoid) warn = Standard_True;
1416 else errmess = new String("Parameter n0.%d (%s) absent");
1418 if (errmess.IsNull()) return Standard_True;
1419 sprintf(txtmes, errmess->ToCString(), nump, mess);
1420 if (warn) ach->AddWarning(txtmes, errmess->ToCString());
1421 else ach->AddFail(txtmes, errmess->ToCString());
1422 return Standard_False;
1426 // #########################################################################
1427 // .... Methodes specifiques (demandees par FileReaderData) .... //
1430 //=======================================================================
1431 //function : NbEntities
1433 //=======================================================================
1435 Standard_Integer StepData_StepReaderData::NbEntities() const // redefined
1441 //=======================================================================
1442 //function : FindNextRecord
1444 //=======================================================================
1446 Standard_Integer StepData_StepReaderData::FindNextRecord
1447 (const Standard_Integer num) const
1449 // retourne, sur un numero d enregistrement donne (par num), le suivant qui
1450 // definit une entite, ou 0 si c est fini :
1451 // passe le Header (nbhend premiers records) et
1452 // saute les enregistrements SCOPE et ENDSCOPE et les SOUS-LISTES
1454 if (num < 0) return 0;
1455 Standard_Integer num1 = num + 1; if (num == 0) num1 = thenbhead + 1;
1456 Standard_Integer max = NbRecords();
1458 while (num1 <= max) {
1459 if (theidents(num1) > 0) return num1;
1461 // SCOPE,ENDSCOPE et Sous-Liste ont un identifieur fictif: -1,-2 respectivement
1462 // et SUBLIST ont un negatif. Seule une vraie entite a un Ident positif
1469 //=======================================================================
1470 //function : FindEntityNumber
1472 //=======================================================================
1474 Standard_Integer StepData_StepReaderData::FindEntityNumber(const Standard_Integer num,
1475 const Standard_Integer id) const
1477 // Soit un "Id" : recherche dans les Parametres de type Ident de <num>,
1478 // si un d eux designe #Id justement. Si oui, retourne son EntityNumber
1479 if (num == 0) return 0;
1480 Standard_Integer nb = NbParams(num);
1481 for (Standard_Integer i = 1; i <= nb; i++) {
1482 const Interface_FileParameter& FP = Param(num, i);
1483 if (FP.ParamType() != Interface_ParamIdent) continue;
1484 Standard_Integer ixp = atoi(&FP.CValue()[1]);
1485 if (ixp == id) return FP.EntityNumber();
1487 return 0; // ici, pas trouve
1491 // ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1492 // .... La fonction qui suit merite une attention speciale ....
1495 // Cette methode precharge les EntityNumbers dans les Params : ils designent
1496 // les Entites proprement dites dans la liste lue par BoundEntity
1497 // Interet : adresse de meme les sous-listes (Num->no record dans le Direc)
1498 // resultat exploite par ParamEntity et ParamNumber
1500 // En l absence de SCOPE, ou si les "ident" sont strictement ordonnes, a coup
1501 // sur ils ne sont pas dupliques, on peut utiliser une IndexedMap en toute
1502 // confiance. Sinon, il faut balayer dans le fichier, mais avec les SCOPES
1503 // cela va beaucoup plus vite (s ils sont assez gros) : on s y retrouve.
1505 // Pour la recherche par balayage, On opere en plusieurs etapes
1506 // Avant toute chose, le chargement a deja fait une preparation : les idents
1507 // (Entity, SubList) sont deja en entiers (rapidite de lecture), en particulier
1508 // dans les EntityNumber : ainsi, on lit cet ident, on le traite, et on remet
1509 // a la place un vrai numero de Record
1511 // D abord, on passe le directory en table d entiers, sous-listes expurgees
1512 // en // , table inverse vers cette table, car les sous-listes peuvent par
1513 // contre designer des objets ...
1515 // Pour les sous-listes, on exploite leur mode de construction : elles sont
1516 // enregistrees AVANT d etre referencees. Un tableau "subn" note donc pour
1517 // chaque numero de sous-liste (relatif a une entite qui suit, et reference
1518 // par elle ou une autre sous-liste qui suit egalement), son n0 de record
1519 // REMARQUE : ceci marche aussi pour le Header, traite par l occasion
1522 //=======================================================================
1523 //function : SetEntityNumbers
1525 //=======================================================================
1527 void StepData_StepReaderData::SetEntityNumbers(const Standard_Boolean withmap)
1529 Handle(Message_Messenger) sout = Message::DefaultMessenger();
1530 // Passe initiale : Resolution directe par Map
1531 // si tout passe (pas de collision), OK. Sinon, autres passes a prevoir
1532 // On resoud du meme coup les sous-listes
1533 Standard_Integer nbdirec = NbRecords();
1534 TColStd_Array1OfInteger subn(0, thelastn);
1536 Standard_Boolean pbmap = Standard_False; // au moins un conflit
1537 Standard_Integer nbmap = 0;
1538 TColStd_IndexedMapOfInteger imap(thenbents);
1539 TColStd_Array1OfInteger indm(0, nbdirec); // Index Map -> Record Number (seulement si map)
1541 Standard_Integer num; // svv Jan11 2000 : porting on DEC
1542 for (num = 1; num <= nbdirec; num++) {
1543 Standard_Integer ident = theidents(num);
1544 if (ident > 0) { // Ident normal -> Map ?
1545 // Map : si Recouvrement, l inhiber. Sinon, noter index
1546 Standard_Integer indmap = imap.Add(ident);
1547 if (indmap <= nbmap) {
1548 indmap = imap.FindIndex(ident); // plus sur
1549 indm(indmap) = -1; // Map -> pb
1550 pbmap = Standard_True;
1551 // pbmap signifie qu une autre passe sera necessaire ...
1554 indm(indmap) = num; // Map ->ident
1559 for (num = 1; num <= nbdirec; num++) {
1560 Standard_Integer ident = theidents(num);
1561 if (ident < -2) subn(-(ident + 2)) = num; // toujours a jour ...
1563 Standard_Integer nba = NbParams(num);
1564 Standard_Integer nda = (num == 1 ? 0 : ParamFirstRank(num - 1));
1566 for (Standard_Integer na = nba; na > 0; na--) {
1567 // On traite : les sous-listes (sf subn), les idents (si Map dit OK ...)
1568 Interface_FileParameter& FP = ChangeParameter(nda + na);
1569 // Interface_FileParameter& FP = ChangeParam (num,na);
1570 Interface_ParamType letype = FP.ParamType();
1571 if (letype == Interface_ParamSub) {
1572 Standard_Integer numsub = FP.EntityNumber();
1573 if (numsub > thelastn) {
1574 sout << "Bad Sub.N0, Record " << num << " Param " << na << ":$" << numsub << Message_EndLine;
1577 FP.SetEntityNumber(subn(numsub));
1578 } else if (letype == Interface_ParamIdent) {
1579 Standard_Integer id = FP.EntityNumber();
1580 Standard_Integer indmap = imap.FindIndex(id);
1581 if (indmap > 0) { // la map a trouve
1582 Standard_Integer num0 = indm(indmap);
1583 if (num0 > 0) FP.SetEntityNumber(num0); // ET VOILA, on a resolu
1584 else FP.SetEntityNumber(-id); // CONFLIT -> faudra resoudre ...
1585 } else { // NON RESOLU, si pas pbmap, le dire
1587 FP.SetEntityNumber(-id);
1588 continue; // pbmap : on se retrouvera
1591 // ... Construire le Check ...
1593 "Unresolved Reference, Ent.Id.#%d Param.n0 %d (Id.#%d)",
1595 thecheck->AddFail(failmess, "Unresolved Reference");
1596 // ... Et sortir message un peu plus complet
1597 sout << "*** ERR StepReaderData *** Pour Entite #" << ident
1598 << "\n Type:" << RecordType(num)
1599 << " Param.n0 " << na << ": #" << id << " Non trouve" << Message_EndLine;
1601 } // FIN Traitement Reference
1602 } // FIN Boucle Parametres
1603 } // FIN Boucle Repertoires
1608 sout << " -- 2nd pass required --";
1610 Standard_Integer nbseq = thenbents + 2 * thenbscop;
1611 TColStd_Array1OfInteger inds(0, nbseq); // n0 Record/Entite
1612 TColStd_Array1OfInteger indi(0, nbseq); // Idents/scopes
1613 TColStd_Array1OfInteger indr(0, nbdirec); // inverse de nds
1614 Handle(TColStd_HArray1OfInteger) indx; // pour EXPORT (silya)
1617 Standard_Boolean iamap = withmap; // (par defaut True)
1620 TColStd_SequenceOfInteger scopile; // chainage des scopes note par pile
1621 Standard_Integer nr = 0;
1622 for (num = 1; num <= nbdirec; num++) {
1623 Standard_Integer ident = theidents(num);
1624 if (ident < -2) { // SOUS-LISTE (cas le plus courant)
1625 indr(num) = nr + 1; // recherche basee sur nr (objet qui suit)
1626 } else if (ident >= 0) { // Ident normal
1627 nr++; inds(nr) = num; indi(nr) = ident; indr(num) = nr;
1628 if (ident > 0) { // et non (iamap && ident > 0)
1629 // Map : si Recouvrement, l inhiber. Sinon, noter index
1630 Standard_Integer indmap = imap.Add(ident);
1631 if (indmap <= nbmap) {
1632 Standard_Boolean errorscope = Standard_False;
1633 indmap = imap.FindIndex(ident); // plus sur
1634 pbmap = Standard_True;
1635 if (thenbscop == 0) errorscope = Standard_True;
1636 // Numeros identiques alors quilnya pas de SCOPE ? ERREUR !
1637 // (Bien sur, silya des SCOPES, on passe au travers, mais bon...)
1639 // Silya des SCOPES, tachons d y voir de plus pres pour signaler un probleme
1640 // Erreur si MEME groupe SCOPE
1641 // ATTENTION, on recherche, non dans tous les records, mais dans les records
1642 // CHAINES, cf nr et non num (pas de sous-liste, chainage scope-endscope)
1643 Standard_Integer fromscope = nr;
1644 Standard_Integer toscope = indm(indmap);
1645 if (toscope < 0) toscope = -toscope;
1647 fromscope--; // iteration de base
1648 if (fromscope <= toscope) {
1649 errorscope = Standard_True; // BANG, on est dessus
1652 Standard_Integer idtest = indi(fromscope);
1653 if (idtest >= 0) continue; // le suivant (enfin, le precedent)
1654 if (idtest == -1) break; // pas meme niveau, donc c est OK
1656 fromscope = inds(fromscope);
1657 if (fromscope < toscope) break; // on sort, pas en meme niveau
1662 // On est dedans : le signaler
1664 sprintf(ligne, "Ident defined SEVERAL TIMES : #%d", ident);
1665 thecheck->AddFail(ligne, "Ident defined SEVERAL TIMES : #%d");
1666 sout << "StepReaderData:SetEntityNumbers, " << ligne << Message_EndLine;
1668 if (indm(indmap) > 0) indm(indmap) = -indm(indmap); // Pas pour Map
1669 // Cas Normal pour la Map
1672 indm(indmap) = nr; // Map ->(indm)->inds
1675 } else if (ident == -1) { // SCOPE
1676 nr ++; inds(nr) = num; indi(nr) = -1; indr(num) = 0;
1677 scopile.Append(nr) ;
1678 } else if (ident == -2) { // ENDSCOPE
1679 Standard_Integer nscop = scopile.Last() ; // chainage SCOPE-ENDSCOPE
1680 scopile.Remove(scopile.Length()) ;
1681 nr ++; inds(nr) = nscop; indi(nr) = -3; indr(num) = 0; inds(nscop) = nr;
1682 if (NbParams(num) > 0) {
1683 // EXPORT : traitement special greffe sur celui de SCOPE (sans le perturber)
1684 if (indx.IsNull()) {
1685 indx = new TColStd_HArray1OfInteger(0, nbseq);
1686 for (Standard_Integer ixp = 0; ixp <= nbseq; ixp ++) indx->ChangeValue(ixp) = 0;
1688 indx->ChangeValue(nr) = num; indx->ChangeValue(nscop) = num;
1690 } else if (ident == 0) { // HEADER
1695 // .. Resolution des EXPORT, silyena et silya besoin ..
1696 // Pour chaque valeur de EXPORT qui n a pas ete resolue par la MAP,
1697 // determiner sa position locale par recherche en arriere depuis ENDSCOPE
1698 if ((!iamap || pbmap) && !indx.IsNull()) {
1699 for (nr = 0; nr <= nbseq; nr++) {
1700 if (indx->Value(nr) == 0 && indi(nr) != -3) continue; // ENDSCOPE + EXPORT
1701 num = indx->Value(nr);
1702 Standard_Integer nba = NbParams(num);
1703 for (Standard_Integer na = 1; na <= nba; na++) {
1704 Interface_FileParameter& FP = ChangeParam(num, na);
1705 if (FP.ParamType() != Interface_ParamIdent) continue;
1706 Standard_Integer id = -FP.EntityNumber();
1707 if (id < 0) continue; // deja resolu en tete
1708 /* if (imap.Contains(id)) { et voila
1709 FP.SetEntityNumber(indm(imap.FindIndex(id)));
1713 // Recherche du Id demande : si EXPORT imbrique, deja resolu mais il faut
1714 // regarder ! (inutile par contre d aller y voir : c est deja fait, car
1715 // un EXPORT imbrique a ete traite AVANT celui qui imbrique)
1716 Standard_Integer n0 = nr - 1;
1717 if (indi(n0) == -3) n0--; // si on suit juste un ENDSCOPE
1719 Standard_Integer irec = indi(n0);
1720 if (irec == id) { // trouve
1721 FP.SetEntityNumber(inds(n0));
1724 if (irec == -1) break; // SCOPE : fin de ce SCOPE/ENDSCOPE
1726 // gare a EXPORT : si un EXPORT detient Id, noter son Numero deja calcule
1727 // Attention : Id a lire depuis CValue car EntityNumber deja resolu
1728 Standard_Integer nok = FindEntityNumber(indx->Value(n0), id);
1730 FP.SetEntityNumber(nok);
1733 n0 = inds(n0); // ENDSCOPE ou EXPORT infructueux : le sauter
1734 } // fin traitement sur un ENDSCOPE ou EXPORT
1736 } // fin resolution d un Parametre EXPORT
1737 } // fin resolution de la liste d un EXPORT
1738 } // fin bouclage sur les EXPORT
1741 // Exploitation de la table : bouclage porte sur la table
1743 // Traitement des sous-listes : se fait dans la foulee, par gestion d une pile
1744 // basee sur la constitution des sous-listes
1745 Standard_Integer maxsubpil = 30; // pile simulee avec un Array : tres fort
1746 Handle(TColStd_HArray1OfInteger) subpile = // ... gagne de la memoire ...
1747 new TColStd_HArray1OfInteger(1, maxsubpil);
1748 Standard_Integer nbsubpil = 0; // ... et tellement plus rapide !
1750 for (num = 1; num <= nbdirec; num++) {
1752 if (nr == 0) continue; // pas un objet ou une sous-liste
1753 Standard_Integer nba = NbParams(num);
1754 for (Standard_Integer na = nba; na > 0; na--) {
1755 // On lit depuis la fin : cela permet de traiter les sous-listes dans la foulee
1756 // Sinon, on devrait noter qu il y a eu des sous-listes et reprendre ensuite
1758 Interface_FileParameter& FP = ChangeParam(num, na);
1759 Interface_ParamType letype = FP.ParamType();
1760 if (letype == Interface_ParamSub) {
1761 // parametre type sous-liste : numero de la sous-liste lu par depilement
1762 FP.SetEntityNumber(subpile->Value(nbsubpil));
1763 nbsubpil--; // subpile->Remove(nbsubpil);
1765 } else if (letype == Interface_ParamIdent) {
1766 // parametre type ident (reference une entite) : chercher ident demande
1767 Standard_Integer id = -FP.EntityNumber();
1768 if (id < 0) continue; // deja resolu en tete
1770 // Voila : on va chercher id dans ndi; algorithme de balayage
1771 Standard_Integer pass, sens, nok, n0, irec; pass = sens = nok = 0;
1772 if (!iamap) pass = 1; // si map non disponible
1776 if (pass == 1) { // MAP DISPONIBLE
1777 Standard_Integer indmap = imap.FindIndex(id);
1778 if (indmap > 0) { // la map a trouve
1780 if (nok < 0) continue; // CONFLIT -> faut resoudre ...
1785 // 1re Passe : REMONTEE -> Debut fichier
1786 if (sens == 0 && nr > 1) {
1788 if (indi(n0) == -3) n0--; // si on suit juste un ENDSCOPE
1791 if (irec == id) { // trouve
1794 // ENDSCOPE : Attention a EXPORT sinon sauter
1796 if (indx.IsNull()) n0 = inds(n0);
1798 // EXPORT, il faut regarder
1799 nok = FindEntityNumber(indx->Value(n0), id);
1801 n0 = inds(n0); // ENDSCOPE : le sauter
1806 // 2me Passe : DESCENTE -> Fin fichier
1807 } else if (nr < nbseq) { // descente -> fin fichier
1809 while (n0 <= nbseq) {
1811 if (irec == id) { // trouve
1814 // SCOPE : Attention a EXPORT sinon sauter
1816 if (indx.IsNull()) n0 = inds(n0);
1818 // EXPORT, il faut regarder
1819 nok = FindEntityNumber(indx->Value(n0), id);
1821 n0 = inds(n0); // SCOPE : le sauter
1828 sens = 1 - sens; // passe suivante
1830 // ici on a nok, numero trouve
1832 Standard_Integer num0 = inds(nok);
1833 FP.SetEntityNumber(num0); // ET VOILA, on a resolu
1835 // pas trouve : le signaler
1837 // Alimenter le Check ... Pour cela, determiner n0 Entite et Ident
1839 Standard_Integer nument = 0;
1840 Standard_Integer n0ent; // svv Jan11 2000 : porting on DEC
1841 for (n0ent = 1; n0ent <= nr; n0ent++) {
1842 if (indi(n0ent) > 0) nument++;
1844 Standard_Integer ident = RecordIdent(num);
1846 for (n0ent = num + 1; n0ent <= nbdirec; n0ent++) {
1847 ident = RecordIdent(n0ent); if (ident > 0) break;
1850 // ... Construire le Check ...
1852 "Unresolved Reference, Ent.n0 %d (Id.#%d) Param.n0 %d (Id.#%d)",
1853 nument, ident, na, id);
1854 thecheck->AddFail(failmess, "Unresolved Reference");
1855 // ... Et sortir message un peu plus complet
1856 sout << "*** ERR StepReaderData *** Pour Entite " << nument
1857 << ", a " << (nr * 100) / nbseq << "% de DATA : #" << ident
1858 << "\n Type:" << RecordType(num)
1859 << " Param.n0 " << na << ": #" << id << " Non trouve" << Message_EndLine;
1860 FP.SetEntityNumber(0); // -> Reference non resolue
1864 // Si ce record est lui-meme une sous-liste, empiler !
1865 if (inds(nr) != num) {
1866 if (nbsubpil >= maxsubpil) {
1867 maxsubpil = maxsubpil + 30;
1868 Handle(TColStd_HArray1OfInteger) newsubpil =
1869 new TColStd_HArray1OfInteger(1, maxsubpil);
1870 for (Standard_Integer bidpil = 1; bidpil <= maxsubpil - 30; bidpil++)
1871 newsubpil->SetValue(bidpil, subpile->Value(bidpil));
1872 subpile = newsubpil;
1875 subpile->SetValue(nbsubpil, num); // Append(num);
1881 // ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1882 // .... Gestion du Header : Preparation, lecture ....
1885 //=======================================================================
1886 //function : FindNextHeaderRecord
1888 //=======================================================================
1890 Standard_Integer StepData_StepReaderData::FindNextHeaderRecord
1891 (const Standard_Integer num) const
1893 // retourne, sur un numero d enregistrement donne (par num), le suivant qui
1894 // definit une entite, ou 0 si c est fini :
1895 // Opere comme FindNextRecord mais ne balaie que le Header
1897 if (num < 0) return 0;
1898 Standard_Integer num1 = num + 1;
1899 Standard_Integer max = thenbhead;
1901 while (num1 <= max) {
1902 // SCOPE,ENDSCOPE et Sous-Liste ont un identifieur negatif
1903 // Ne retenir que les Idents positifs ou nuls (nul : pas d Ident dans Header)
1904 if (RecordIdent(num1) >= 0) return num1;
1911 //=======================================================================
1912 //function : PrepareHeader
1914 //=======================================================================
1916 void StepData_StepReaderData::PrepareHeader()
1918 // Resolution des references : ne concerne que les sous-listes
1919 // deja faite par SetEntityNumbers donc pas de souci a se faire
1922 // Algorithme repris et adapte de SetEntityNumbers
1923 // Traitement des sous-listes : se fait dans la foulee, par gestion d une pile
1924 // basee sur la constitution des sous-listes
1925 TColStd_SequenceOfInteger subpile;
1926 Standard_Integer nbsubpil = 0; // profondeur de pile mais plus rapide ...
1928 for (Standard_Integer num = 1 ; num <= thenbhead ; num ++) {
1929 Standard_Integer nba = NbParams(num) ;
1930 for (Standard_Integer na = nba ; na > 0 ; na --) {
1931 .. On lit depuis la fin : cela permet de traiter les sous-listes dans la foulee
1932 .. Sinon, on devrait noter qu il y a eu des sous-listes et reprendre ensuite
1934 Interface_FileParameter& FP = ChangeParam(num,na);
1935 Interface_ParamType letype = FP.ParamType();
1936 if (letype == Interface_ParamSub) {
1937 .. parametre type sous-liste : numero de la sous-liste lu par depilement
1938 FP.SetEntityNumber(subpile.Last());
1939 .. .. SetParam(num,na,FP);
1940 subpile.Remove(nbsubpil);
1944 .. Si c est une sous-liste, empiler
1945 if (RecordIdent(num) < -2) {
1946 subpile.Append(num);
1954 //=======================================================================
1955 //function : GlobalCheck
1957 //=======================================================================
1959 const Handle(Interface_Check) StepData_StepReaderData::GlobalCheck() const