0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / StepData / StepData_StepReaderData.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 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)
42cf5bc1 16
17#include <Interface_Check.hxx>
7fd59977 18#include <Interface_FileParameter.hxx>
42cf5bc1 19#include <Interface_HArray1OfHAsciiString.hxx>
20#include <Interface_Macros.hxx>
7fd59977 21#include <Interface_ParamList.hxx>
7fd59977 22#include <Interface_Static.hxx>
42cf5bc1 23#include <Message.hxx>
24#include <Message_Messenger.hxx>
25#include <Standard_Transient.hxx>
26#include <Standard_Type.hxx>
27#include <StepData_EnumTool.hxx>
28#include <StepData_ESDescr.hxx>
29#include <StepData_Field.hxx>
30#include <StepData_FieldList.hxx>
31#include <StepData_PDescr.hxx>
32#include <StepData_SelectArrReal.hxx>
33#include <StepData_SelectInt.hxx>
7fd59977 34#include <StepData_SelectMember.hxx>
35#include <StepData_SelectNamed.hxx>
36#include <StepData_SelectReal.hxx>
42cf5bc1 37#include <StepData_SelectType.hxx>
38#include <StepData_StepModel.hxx>
39#include <StepData_StepReaderData.hxx>
40#include <TCollection_AsciiString.hxx>
41#include <TCollection_HAsciiString.hxx>
42#include <TColStd_Array1OfInteger.hxx>
43#include <TColStd_HArray1OfInteger.hxx>
44#include <TColStd_HArray1OfReal.hxx>
45#include <TColStd_HArray1OfTransient.hxx>
7fd59977 46#include <TColStd_HSequenceOfReal.hxx>
42cf5bc1 47#include <TColStd_IndexedMapOfInteger.hxx>
48#include <TColStd_SequenceOfInteger.hxx>
7fd59977 49
50#include <stdio.h>
92efcf78 51IMPLEMENT_STANDARD_RTTIEXT(StepData_StepReaderData,Interface_FileReaderData)
52
7fd59977 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
7fd59977 57// #########################################################################
58// .... Creation et Acces de base aux donnees atomiques du fichier ....
7fd59977 59typedef TCollection_HAsciiString String;
7fd59977 60static char txtmes[200]; // plus commode que redeclarer partout
61
62
63static Standard_Boolean initstr = Standard_False;
64
65#define Maxlst 64
66//static TCollection_AsciiString subl[Maxlst]; // Maxlst : minimum 10
67
68static Standard_Integer acceptvoid = 0;
69
70// ---------- Fonctions Utilitaires ----------
71
72//=======================================================================
73//function : CleanText
74//purpose :
75//=======================================================================
76static void CleanText (const Handle(TCollection_HAsciiString)& val)
77{
78 Standard_Integer n = val->Length(); // avant reduction
79 val->Remove(n);
80 val->Remove(1);
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);
84 if (uncar == '\n')
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; }
88 }
89 if (uncar == '\\' && i < n-2) {
90 if (val->Value(i+1) == '\\') { val->Remove(i+1); continue; }
91 }
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; }
98 }
99 }
100 }
101}
102
103// ------------- METHODES -------------
104
105//=======================================================================
106//function : StepData_StepReaderData
107//purpose :
108//=======================================================================
109
110StepData_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)
115{
116// char textnum[10];
117 thenbscop = 0; thenbents = 0; thelastn = 0; thenbhead = nbheader;
118 //themults.Init(0);
119 thecheck = new Interface_Check;
120//:S4136 acceptvoid = Interface_Static::IVal("step.readaccept.void");
121 if (initstr) return;
122 //for (Standard_Integer i = 0; i < Maxlst; i ++) {
123 // sprintf(textnum,"$%d",i+1);
124 // subl[i].AssignCat(textnum);
125 //}
126 initstr = Standard_True;
127}
128
129
130//=======================================================================
131//function : SetRecord
132//purpose :
133//=======================================================================
134
135void StepData_StepReaderData::SetRecord (const Standard_Integer num,
136 const Standard_CString ident,
137 const Standard_CString type,
138 const Standard_Integer /* nbpar */)
139{
140 Standard_Integer numlst;
141/*
142 if (strcmp(type,"/ * (SUB) * /") == 0) { // defini dans recfile.pc
143 thetypes.SetValue (num,sublist);
144 } else {
145 thenbents ++; // total de termes propres du fichier
146 thetypes.SetValue(num,TCollection_AsciiString(type));
147// if (strcmp(ident,"SCOPE") != 0) thenbscop ++; // ?? a verifier
148 }
149*/
150 if (type[0] != '(') thenbents ++; // total de termes propres du fichier
151
152 //thetypes.ChangeValue(num).SetValue(1,type); gka memory
153 //============================================
154 Standard_Integer index = 0;
155 TCollection_AsciiString strtype(type);
156 if(thenametypes.Contains(type))
157 index = thenametypes.FindIndex(strtype);
158 else index = thenametypes.Add(strtype);
159 thetypes.ChangeValue(num) = index;
160 //===========================================
161
162 if (ident[0] == '$') {
163 if (strlen(ident) > 2) numlst = atoi(&ident[1]);
164 else numlst = ident[1] - 48;
165 if (thelastn < numlst) thelastn = numlst; // plus fort n0 de sous-liste
166 theidents.SetValue(num,-2-numlst);
167 } else if (ident[0] == '#') {
168 numlst = atoi(&ident[1]);
169 theidents.SetValue(num,numlst);
170 if (numlst == 0 && num > thenbhead) {
171// Header, ou bien Type Complexe ...
172// Si Type Complexe, retrouver Type Precedent (on considere que c est rare)
173// On chaine le type precedent sur le suivant
174// VERIFICATION que les types sont en ordre alphabetique
175 for (Standard_Integer prev = num-1; prev > thenbhead; prev --) {
176 if (theidents(prev) >= 0) {
177
178 //themults.SetValue(prev,num);
179 themults.Bind(prev,num);
180 if(thenametypes.FindKey(thetypes.Value(num)).IsLess(thenametypes.FindKey(thetypes.Value(prev)))) {
181 //if (thetypes.Value(num).IsLess(thetypes.Value(prev)))
182
183// ERREUR : Type complexe pas en ordre alphabetique. On enregistre.
184 TCollection_AsciiString errm("Complex Type incorrect : ");
185 errm.AssignCat(thenametypes.FindKey(thetypes.Value(prev)));
186 errm.AssignCat(" / ");
187 errm.AssignCat(thenametypes.FindKey(thetypes.Value(num)));
188 errm.AssignCat(" ... ");
189 thecheck->AddFail(errm.ToCString(),"Complex Type incorrect : ");
190// On Affiche a l ecran, le plus de donnees possibles
191 while (theidents(prev) <= 0) {
192 prev --; if (prev <= 0) break;
193 }
194 Handle(Message_Messenger) sout = Message::DefaultMessenger();
195 sout << " *** Error on Record " << num << " (on " << NbRecords()
196 << " -> " << num*100/NbRecords() << " % in File) ***";
197 if (prev > 0) sout << " Ident #" << theidents(prev);
198 sout << "\n" << errm << endl;
199 }
200 break;
201 }
202 }
203 }
204 }
205 else if (!strcmp(ident,"SCOPE")) {
206 theidents.SetValue(num,-1); // SCOPE
207 thenbscop ++;
208 }
209 else if (!strcmp(ident,"ENDSCOPE")) theidents.SetValue(num,-2); // ENDSCOPE
210// Reste 0
211
212 // InitParams(num);
213}
214
215
216//=======================================================================
217//function : AddStepParam
218//purpose :
219//=======================================================================
220
221void StepData_StepReaderData::AddStepParam (const Standard_Integer num,
222 const Standard_CString aval,
223 const Interface_ParamType atype,
224 const Standard_Integer nument)
225{
226 if (atype == Interface_ParamSub) {
227 Standard_Integer numid = 0;
228 if (aval[2] != '\0') {
229 numid = atoi(&aval[1]);
230// if (numid <= Maxlst) Interface_FileReaderData::AddParam
231// (num,subl[numid-1].ToCString(),atype,numid);
232 Interface_FileReaderData::AddParam (num,aval,atype,numid);
233 } else {
234 char *numlstchar = (char *)(aval+1);
235 numid = (*numlstchar) - 48; // -48 ('0') -1 (adresse [] depuis 0)
236// Interface_FileReaderData::AddParam (num,subl[numid].ToCString(),atype,numid);
237 Interface_FileReaderData::AddParam (num,aval,atype,numid);
238 }
239 } else if (atype == Interface_ParamIdent) {
240 Standard_Integer numid = atoi(&aval[1]);
241 Interface_FileReaderData::AddParam (num,aval,atype,numid);
242 } else {
243 Interface_FileReaderData::AddParam (num,aval,atype,nument);
244 }
245
246// Interface_FileReaderData::AddParam (num,parval,atype,numid);
247}
248
249
250//=======================================================================
251//function : RecordType
252//purpose :
253//=======================================================================
254
255const TCollection_AsciiString& StepData_StepReaderData::RecordType
256 (const Standard_Integer num) const
257{
258 return thenametypes.FindKey(thetypes.Value(num));
259}
260
261
262//=======================================================================
263//function : CType
264//purpose :
265//=======================================================================
266
267Standard_CString StepData_StepReaderData::CType(const Standard_Integer num) const
268{
269 return thenametypes.FindKey(thetypes.Value(num)).ToCString();
270}
271
272
273//=======================================================================
274//function : RecordIdent
275//purpose :
276//=======================================================================
277
278Standard_Integer StepData_StepReaderData::RecordIdent (const Standard_Integer num) const
279{
280 return theidents(num);
281}
282
283
284// ########################################################################
285// .... Aides a la lecture des parametres, adaptees a STEP ....
286
287
288//=======================================================================
289//function : SubListNumber
290//purpose :
291//=======================================================================
292
293Standard_Integer StepData_StepReaderData::SubListNumber (const Standard_Integer num,
294 const Standard_Integer nump,
295 const Standard_Boolean aslast) const
296{
297 if (nump == 0 || nump > NbParams(num)) return 0;
298 const Interface_FileParameter& FP = Param(num,nump);
299 if (FP.ParamType() != Interface_ParamSub) return 0;
300 if (aslast) { if(nump != NbParams(num)) return 0; }
301 return FP.EntityNumber();
302}
303
304
305//=======================================================================
306//function : IsComplex
307//purpose :
308//=======================================================================
309
310Standard_Boolean StepData_StepReaderData::IsComplex(const Standard_Integer num) const
311{
312 //return (themults(num) != 0);
313 return themults.IsBound(num);
314}
315
316
317//=======================================================================
318//function : ComplexType
319//purpose :
320//=======================================================================
321
322void StepData_StepReaderData::ComplexType(const Standard_Integer num,
323 TColStd_SequenceOfAsciiString& types) const
324{
325 if (theidents(num) < 0) return;
326 for (Standard_Integer i = num; i > 0; i = NextForComplex(i)) {
327 types.Append(RecordType(i));
328 }
329}
330
331
332//=======================================================================
333//function : NextForComplex
334//purpose :
335//=======================================================================
336
337Standard_Integer StepData_StepReaderData::NextForComplex
338 (const Standard_Integer num) const
339{
340 Standard_Integer next =0;
341 if(themults.IsBound(num))
342 next = themults.Find(num);
343 return next;
344}
345
346
347//=======================================================================
348//function : stepstrcmp
349//purpose :
350//=======================================================================
351static Standard_Boolean stepstrcmp(const Standard_CString type,
352 const Standard_CString name)
353{
354// name peut etre d un tenant ou de deux : auquel cas il a une partie LONGUE
355// et une partie COURTE separees par un blanc
356// Attention : False pour dire OK, True sinon (car remplace strcmp)
357 Standard_Integer i,j = 0; Standard_Boolean res = Standard_False;
358 for (i = 0; name[i] != '\0' && type[i] != '\0' && !res ; i ++) {
d029c7ef 359 if (name[i] == ' ' && type[i] == '\0') { j = i; break; }
7fd59977 360 if (type[i] != name[i]) res = Standard_True;
361 }
362 if (!res || (j == 0)) return res;
363// Pas trouve et un blanc suit : on continue
364 for (i = j+1; name[i] != '\0'; i ++) {
365 if (type[i-j-1] != name[i]) return Standard_True;
366 }
367 return Standard_False;
368}
369
370
371//=======================================================================
372//function : NamedForComplex
373//purpose :
374//=======================================================================
375
376Standard_Boolean StepData_StepReaderData::NamedForComplex
377 (const Standard_CString name, const Standard_Integer num0,
378 Standard_Integer& num, Handle(Interface_Check)& ach) const
379{
380 //Standard_Boolean stat = Standard_True;
381 Standard_Integer n = (num <= 0 ? num0 : NextForComplex(num));
382 // sln 04,10.2001. BUC61003. if(n==0) the next function is not called in order to avoid exception
383 if ((n!=0) && (!stepstrcmp (RecordType(n).ToCString(),name)))
384 { num = n; return Standard_True; }
385
386 if (n == 0) /*stat =*/ NamedForComplex (name,num0,n,ach); // on a rembobine
387// Pas dans l ordre alphabetique : boucler
388 Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
389 sprintf (txtmes,errmess->ToCString(),num0,name);
390 for (n = num0; n > 0; n = NextForComplex(n)) {
391 if (!stepstrcmp (RecordType(n).ToCString(),name)) {
392 num = n;
393 errmess = new String("Complex Record n0.%d, member type %s not in alphabetic order");
394 sprintf (txtmes,errmess->ToCString(),num0,name);
395 ach->AddWarning(txtmes,errmess->ToCString());
396 return Standard_False;
397 }
398 }
399 num = 0;
400 errmess = new String("Complex Record n0.%d, member type %s not found");
401 sprintf (txtmes,errmess->ToCString(),num0,name);
402 ach->AddFail (txtmes,errmess->ToCString());
403 return Standard_False;
404}
405
a7197ef3 406//=======================================================================
407//function : NamedForComplex
408//purpose :
409//=======================================================================
410
411Standard_Boolean StepData_StepReaderData::NamedForComplex
412 (const Standard_CString theName, const Standard_CString theShortName,
413 const Standard_Integer num0, Standard_Integer& num,
414 Handle(Interface_Check)& ach) const
415{
416 Standard_Integer n = (num <= 0 ? num0 : NextForComplex(num));
417 if ((n!=0) && !(stepstrcmp(RecordType(n).ToCString(),theName) &&
418 stepstrcmp(RecordType(n).ToCString(), theShortName)))
419 { num = n; return Standard_True; }
420
421 if (n == 0)
422 NamedForComplex (theName, theShortName, num0, n, ach);
423 //entities are not in alphabetical order
424 Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
425 sprintf (txtmes,errmess->ToCString(), num0, theName);
426 for (n = num0; n > 0; n = NextForComplex(n)) {
427 if (!(stepstrcmp(RecordType(n).ToCString(),theName) &&
428 stepstrcmp(RecordType(n).ToCString(), theShortName))) {
429 num = n;
430 errmess = new String("Complex Record n0.%d, member type %s not in alphabetic order");
431 sprintf (txtmes,errmess->ToCString(), num0, theName);
432 ach->AddWarning(txtmes,errmess->ToCString());
433 return Standard_False;
434 }
435 }
436 num = 0;
437 errmess = new String("Complex Record n0.%d, member type %s not found");
438 sprintf (txtmes,errmess->ToCString(), num0, theName);
439 ach->AddFail (txtmes,errmess->ToCString());
440 return Standard_False;
441}
442
7fd59977 443// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
444
445
446//=======================================================================
447//function : CheckNbParams
448//purpose :
449//=======================================================================
450
451Standard_Boolean StepData_StepReaderData::CheckNbParams(const Standard_Integer num,
452 const Standard_Integer nbreq,
453 Handle(Interface_Check)& ach,
454 const Standard_CString mess) const
455{
456 if (NbParams(num) == nbreq) return Standard_True;
457 Handle(String) errmess;
458 if (mess[0] == '\0') errmess = new String("Count of Parameters is not %d");
459 else errmess = new String("Count of Parameters is not %d for %s");
460 sprintf (txtmes,errmess->ToCString(),nbreq,mess);
461 ach->AddFail (txtmes,errmess->ToCString());
462 return Standard_False;
463}
464
465
466//=======================================================================
467//function : ReadSubList
468//purpose :
469//=======================================================================
470
471Standard_Boolean StepData_StepReaderData::ReadSubList(const Standard_Integer num,
472 const Standard_Integer nump,
473 const Standard_CString mess,
474 Handle(Interface_Check)& ach,
475 Standard_Integer& numsub,
476 const Standard_Boolean optional,
477 const Standard_Integer /* lenmin */,
478 const Standard_Integer /* lenmax */) const
479{
480 numsub = SubListNumber (num,nump,Standard_False);
481 if (numsub > 0) return Standard_True;
482// Si optionel indefini, on passe l eponge
483 numsub = 0;
484 Standard_Boolean isvoid = (Param(num,nump).ParamType() == Interface_ParamVoid);
485 if (isvoid && optional) return Standard_False;
486
487 Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
488 sprintf (txtmes,errmess->ToCString(),nump,mess);
489 if (acceptvoid && isvoid) ach->AddWarning(txtmes,errmess->ToCString());
490 else { ach->AddFail(txtmes,errmess->ToCString()); return Standard_False; }
491 return Standard_True;
492}
493
494
495// ... Facilites pour LateBinding
496
497
498//=======================================================================
499//function : ReadSub
500//purpose :
501//=======================================================================
502
503Standard_Integer StepData_StepReaderData::ReadSub(const Standard_Integer numsub,
504 const Standard_CString mess,
505 Handle(Interface_Check)& ach,
506 const Handle(StepData_PDescr)& descr,
507 Handle(Standard_Transient)& val) const
508{
509 Standard_Integer nbp = NbParams(numsub);
510 if (nbp == 0) return 0; // liste vide = Handle Null
511 const TCollection_AsciiString& rectyp = RecordType (numsub);
512 if (nbp == 1 && rectyp.ToCString()[0] != '(') {
513 // c est un type avec un parametre -> SelectNamed
514 // cf ReadSelect mais ici, on est deja sur le contenu du parametre
515 Handle(StepData_SelectNamed) sn = new StepData_SelectNamed;
516 val = sn;
517 sn->SetName (rectyp.ToCString());
518 if (ReadAny (numsub,1,mess,ach,descr,sn)) return sn->Kind();
519 else return 0;
520 }
521
522 // cas courant : faire un HArray1 de ... de ... de quoi au fait
523 const Interface_FileParameter& FP0 = Param(numsub,1);
524 Interface_ParamType FT, FT0 = FP0.ParamType();
525 Standard_CString str = FP0.CValue();
526 Handle(TColStd_HArray1OfTransient) htr;
527 Handle(TColStd_HArray1OfInteger) hin;
528 Handle(TColStd_HArray1OfReal) hre;
529 Handle(Interface_HArray1OfHAsciiString) hst;
530 Standard_Integer kod = 0;
531 switch (FT0) {
532 case Interface_ParamMisc : return -1;
533 case Interface_ParamInteger : kod = 1; break;
534 case Interface_ParamReal : kod = 5; break;
535 case Interface_ParamIdent : kod = 7; break;
536 case Interface_ParamVoid : kod = 0; break;
537 case Interface_ParamText : kod = 6; break;
538 case Interface_ParamEnum : kod = 4; break; // a confirmer(logical)
539 /* kod = 4;
540 if ( str[0] == '.' && str[2] == '.' && str[3] == '\0' &&
541 (str[1] == 'T' || str[1] == 'F' || str[1] == 'U') ) kod = 3;
542 break; */ // svv #2
543 case Interface_ParamLogical : return -1;
544 case Interface_ParamSub : kod = 0; break;
545 case Interface_ParamHexa : return -1;
546 case Interface_ParamBinary : return -1;
547 default : return -1;
548 }
549 if (kod == 1 || kod == 3) { hin = new TColStd_HArray1OfInteger (1,nbp); val = hin; }
550 else if (kod == 5) { hre = new TColStd_HArray1OfReal (1,nbp); val = hre; }
551 else if (kod == 6) { hst = new Interface_HArray1OfHAsciiString (1,nbp); val = hst; }
552 else { htr = new TColStd_HArray1OfTransient (1,nbp); val = htr; }
553// Attention : si type variable, faudra changer son fusil d epaule -> htr
554
555 for (Standard_Integer ip = 1; ip <= nbp; ip ++) {
556 const Interface_FileParameter& FP = Param(numsub,ip);
557 str = FP.CValue();
558 FT = FP.ParamType();
559 switch (kod) {
560 case 1 : {
561 if (FT != Interface_ParamInteger) { kod = 0; break; }
562 hin->SetValue (ip,atoi(str)); break;
563 }
564 case 2 :
565 case 3 : {
566 if (FT != Interface_ParamEnum) { kod = 0; break; }
567 if (!strcmp(str,".F.")) hin->SetValue (ip,0);
568 else if (!strcmp(str,".T.")) hin->SetValue (ip,1);
569 else if (!strcmp(str,".U.")) hin->SetValue (ip,2);
570 else kod = 0;
571 break;
572 }
573 case 4 : {
574 if (FT != Interface_ParamEnum) { kod = 0; break; }
575 Handle(StepData_SelectNamed) sn = new StepData_SelectNamed;
576 sn->SetEnum (-1,str);
577 htr->SetValue (ip,sn); break;
578 }
579 case 5 : {
580 if (FT != Interface_ParamReal) { kod = 0; break; }
581 hre->SetValue (ip,Interface_FileReaderData::Fastof(str)); break;
582 }
583 case 6 : {
584 if (FT != Interface_ParamText) { kod = 0; break; }
585 Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
586 CleanText (txt); hst->SetValue (ip,txt); break;
587 }
588 case 7 : {
589 Handle(Standard_Transient) ent = BoundEntity (FP.EntityNumber());
590 htr->SetValue (ip,ent); break;
591 }
592 default : break;
593 }
594// Restent les autres cas ... tout est possible. cf le type du Param
595 if (kod > 0) continue;
596// Il faut passer au transient ...
597 if (htr.IsNull()) {
598 htr = new TColStd_HArray1OfTransient (1,nbp); val = htr;
599 Standard_Integer jp;
600 if (!hin.IsNull()) {
601 for (jp = 1; jp < ip; jp ++) {
602 Handle(StepData_SelectInt) sin = new StepData_SelectInt;
603 sin->SetInt (hin->Value(jp));
604 htr->SetValue (jp,sin);
605 }
606 }
607 if (!hre.IsNull()) {
608 for (jp = 1; jp < ip; jp ++) {
609 Handle(StepData_SelectReal) sre = new StepData_SelectReal;
610 sre->SetReal (hre->Value(jp));
611 htr->SetValue (jp,sre);
612 }
613 }
614 if (!hst.IsNull()) {
615 for (jp = 1; jp < ip; jp ++) {
616 htr->SetValue (jp,hst->Value(jp));
617 }
618 }
619 }
620// A present, faut y aller : lire le champ et le mettre en place
621// Ce qui suit ressemble fortement a ReadAny ...
622
623 switch (FT) {
624 case Interface_ParamMisc : break;
625 case Interface_ParamInteger : {
626 Handle(StepData_SelectInt) sin = new StepData_SelectInt;
627 sin->SetInteger (atoi(str));
628 htr->SetValue (ip,sin); break;
629 }
630 case Interface_ParamReal : {
631 Handle(StepData_SelectReal) sre = new StepData_SelectReal;
632 sre->SetReal (Interface_FileReaderData::Fastof(str)); break;
633 //htr->SetValue (ip,sre); break; svv #2: unreachable
634 }
635 case Interface_ParamIdent : htr->SetValue (ip,BoundEntity (FP.EntityNumber())); break;
636 case Interface_ParamVoid : break;
637 case Interface_ParamEnum : {
638 Handle(StepData_SelectInt) sin;
639 Handle(StepData_SelectNamed) sna;
640 Standard_Integer logic = -1;
641// PTV 16.09.2000
642// set the default value of StepData_Logical
643 StepData_Logical slog = StepData_LUnknown;
644 if ( str[0] == '.' && str[2] == '.' && str[3] == '\0') {
645 if (str[1] == 'F') { slog = StepData_LFalse; logic = 0; }
646 else if (str[1] == 'T') { slog = StepData_LTrue; logic = 1; }
647 else if (str[1] == 'U') { slog = StepData_LUnknown; logic = 2; }
648 }
649 if (logic >= 0)
650 { sin = new StepData_SelectInt; sin->SetLogical(slog); htr->SetValue(ip,sin); }
651 else { sna = new StepData_SelectNamed;
652 sna->SetEnum (logic,str); htr->SetValue (ip,sna); }
653 break;
654 }
655 case Interface_ParamLogical : break;
656 case Interface_ParamText : {
657 Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
658 CleanText (txt); htr->SetValue (ip,txt); break;
659 }
660 case Interface_ParamSub : {
661 Handle(Standard_Transient) sub;
662 Standard_Integer nent = FP.EntityNumber();
663 Standard_Integer kind = ReadSub (nent,mess,ach,descr,sub); if (kind < 0) break;
664 htr->SetValue(ip,sub); break;
665 }
666 case Interface_ParamHexa : break;
667 case Interface_ParamBinary : break;
668 default : break;
669 }
670 return -1;
671 }
672 return 8; // pour Any
673}
674
675
676//=======================================================================
677//function : ReadMember
678//purpose :
679//=======================================================================
680
681Standard_Boolean StepData_StepReaderData::ReadMember(const Standard_Integer num,
682 const Standard_Integer nump,
683 const Standard_CString mess,
684 Handle(Interface_Check)& ach,
685 Handle(StepData_SelectMember)& val) const
686{
687 Handle(Standard_Transient) v = val;
688 Handle(StepData_PDescr) nuldescr;
689 if (v.IsNull()) return ReadAny (num,nump,mess,ach,nuldescr,val);
690 Standard_Boolean res = ReadAny (num,nump,mess,ach,nuldescr,v);
691 if (v == val) return res;
692 // changement -> refus
693 Handle(String) errmess =
694 new String("Parameter n0.%d (%s) : does not match SELECT clause");
695 sprintf (txtmes,errmess->ToCString(),nump,mess);
696 ach->AddFail(txtmes,errmess->ToCString());
697 return Standard_False;
698}
699
700
701//=======================================================================
702//function : ReadField
703//purpose :
704//=======================================================================
705
706Standard_Boolean StepData_StepReaderData::ReadField(const Standard_Integer num,
707 const Standard_Integer nump,
708 const Standard_CString mess,
709 Handle(Interface_Check)& ach,
710 const Handle(StepData_PDescr)& descr,
711 StepData_Field& fild) const
712{
713 const Interface_FileParameter& FP = Param(num,nump);
714 Standard_CString str = FP.CValue();
715 Standard_Boolean OK = Standard_True;
716 Standard_Integer nent, kind;
717 Handle(TCollection_HAsciiString) txt;
718 Handle(Standard_Transient) sub;
719 Interface_ParamType FT = FP.ParamType();
720 switch (FT) {
721 case Interface_ParamMisc : OK = Standard_False; break;
722 case Interface_ParamInteger : fild.SetInteger (atoi(str)); break;
723 case Interface_ParamReal :
724 fild.SetReal (Interface_FileReaderData::Fastof(str)); break;
725 case Interface_ParamIdent :
726 nent = FP.EntityNumber();
727 if (nent > 0) fild.SetEntity (BoundEntity(nent));
728 break;
729 case Interface_ParamVoid : break;
730 case Interface_ParamText :
731 txt = new TCollection_HAsciiString(str);
732 CleanText (txt); fild.Set (txt); break;
733 case Interface_ParamEnum :
734 if (!strcmp(str,".T.")) fild.SetLogical (StepData_LTrue);
735 else if (!strcmp(str,".F.")) fild.SetLogical (StepData_LFalse);
736 else if (!strcmp(str,".U.")) fild.SetLogical (StepData_LUnknown);
737 else fild.SetEnum (-1,str);
738 break;
739 case Interface_ParamLogical : OK = Standard_False; break;
740 case Interface_ParamSub :
741 nent = FP.EntityNumber();
742 kind = ReadSub (nent,mess,ach,descr,sub); if (kind < 0) break;
743 fild.Clear(kind); fild.Set (sub); break;
744 case Interface_ParamHexa : OK = Standard_False; break;
745 case Interface_ParamBinary : OK = Standard_False; break;
746 default : OK = Standard_False; break;
747 }
748
749 if (!OK) {
750 if (!strcmp(str,"*")) fild.SetDerived();
751 }
752 return Standard_True;
753}
754
755
756//=======================================================================
757//function : ReadList
758//purpose :
759//=======================================================================
760
761Standard_Boolean StepData_StepReaderData::ReadList(const Standard_Integer num,
762 Handle(Interface_Check)& ach,
763 const Handle(StepData_ESDescr)& descr,
764 StepData_FieldList& list) const
765{
766 // controler nbs egaux
767 Standard_Integer i,nb = list.NbFields();
768 if (!CheckNbParams (num,nb,ach,descr->TypeName())) return Standard_False;
769 for (i = 1; i <= nb; i ++) {
770 Handle(StepData_PDescr) pde = descr->Field(i);
771 StepData_Field& fild = list.CField(i);
772 ReadField (num,i,pde->Name(),ach,pde,fild);
773 }
774 return Standard_True;
775}
776
777
778//=======================================================================
779//function : ReadAny
780//purpose :
781//=======================================================================
782
783Standard_Boolean StepData_StepReaderData::ReadAny(const Standard_Integer num,
784 const Standard_Integer nump,
785 const Standard_CString mess,
786 Handle(Interface_Check)& ach,
787 const Handle(StepData_PDescr)& descr,
788 Handle(Standard_Transient)& val) const
789{
790 const Interface_FileParameter& FP = Param(num,nump);
791 Standard_CString str = FP.CValue();
792 Interface_ParamType FT = FP.ParamType();
793
794// A present, faut y aller : lire le champ et le mettre en place
795 switch (FT) {
796 case Interface_ParamMisc : break;
797 case Interface_ParamInteger : {
798 if (!val.IsNull()) {
799 DeclareAndCast(StepData_SelectMember,sm,val);
800 sm->SetInteger(atoi(str));
801 return Standard_True;
802 }
803 Handle(StepData_SelectInt) sin = new StepData_SelectInt;
804 sin->SetInteger (atoi(str));
805 val = sin;
806 return Standard_True;
807 }
808 case Interface_ParamReal : {
809 if (!val.IsNull()) {
810 DeclareAndCast(StepData_SelectMember,sm,val);
811 sm->SetReal (Interface_FileReaderData::Fastof(str));
812 return Standard_True;
813 }
814 Handle(StepData_SelectReal) sre = new StepData_SelectReal;
815 sre->SetReal (Interface_FileReaderData::Fastof(str));
816 val = sre;
817 return Standard_True;
818 }
819 case Interface_ParamIdent : {
820 Standard_Integer nent = FP.EntityNumber();
821 if (nent > 0) val = BoundEntity(nent);
822 return (!val.IsNull());
823 }
824 case Interface_ParamVoid : break;
825 case Interface_ParamEnum : {
826 Handle(StepData_SelectMember) sm;
827 if (!val.IsNull()) sm = GetCasted(StepData_SelectMember,val);
828 Handle(StepData_SelectInt) sin;
829 Handle(StepData_SelectNamed) sna;
830 Standard_Integer logic = -1;
831
832 // PTV 16.09.2000
833 // set the default value of StepData_Logical
834 StepData_Logical slog = StepData_LUnknown;
835 if ( str[0] == '.' && str[2] == '.' && str[3] == '\0') {
836 if (str[1] == 'F') { slog = StepData_LFalse; logic = 0; }
837 else if (str[1] == 'T') { slog = StepData_LTrue; logic = 1; }
838 else if (str[1] == 'U') { slog = StepData_LUnknown; logic = 2; }
839 }
840 if (logic >= 0) {
841 if (!sm.IsNull()) sm->SetLogical(slog);
842 else {
843 sin = new StepData_SelectInt; val = sin;
844 sin->SetLogical(slog);
845 }
846 }
847 else {
848 if (!sm.IsNull()) sm->SetEnum (logic,str);
849 else {
850 sna = new StepData_SelectNamed; val = sna; // Named sans nom...
851 sna->SetEnum (logic,str);
852 }
853 } // -> Select general
854 return Standard_True;
855 }
856 case Interface_ParamLogical : break;
857 case Interface_ParamText : {
858 Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
859 CleanText (txt);
860
861 // PDN May 2000: for reading SOURCE_ITEM (external references)
862 if (!val.IsNull()) {
863 DeclareAndCast(StepData_SelectMember,sm,val);
864 sm->SetString (txt->ToCString());
865 return Standard_True;
866 }
867
868 val = txt;
869 return Standard_True;
870 }
871 case Interface_ParamSub : {
872 Standard_Integer numsub = SubListNumber (num,nump,Standard_False);
873 Standard_Integer nbp = NbParams(numsub);
874 if (nbp == 0) return Standard_False; // liste vide = Handle Null
875 const TCollection_AsciiString& rectyp = RecordType (numsub);
876 if (nbp == 1 && rectyp.ToCString()[0] != '(') {
877 // SelectNamed because Field !!!
878 // skl 15.01.2003 (for members with array of real)
879 DeclareAndCast(StepData_SelectArrReal,sma,val);
880 if(!sma.IsNull()) {
881 Standard_Integer numsub2 = SubListNumber (numsub,1,Standard_False);
882 Standard_Integer nbp2 = NbParams(numsub2);
883 if(nbp2>1) {
884 if( Param(numsub2,1).ParamType() == Interface_ParamReal ) {
885 if (!sma->SetName (rectyp.ToCString())) return Standard_False;
886 Handle(TColStd_HSequenceOfReal) aSeq = new TColStd_HSequenceOfReal;
887 for(Standard_Integer i=1; i<=nbp2; i++) {
888 if( Param(numsub2,i).ParamType() != Interface_ParamReal ) continue;
889 Handle(StepData_SelectReal) sm1 = new StepData_SelectReal;
890 if( !ReadAny(numsub2,i,mess,ach,descr,sm1) ) continue;
891 aSeq->Append(sm1->Real());
892 }
893 Handle(TColStd_HArray1OfReal) anArr = new TColStd_HArray1OfReal(1,aSeq->Length());
894 for(Standard_Integer nr=1; nr<=aSeq->Length(); nr++) {
895 anArr->SetValue(nr,aSeq->Value(nr));
896 }
897 sma->SetArrReal(anArr);
898 return Standard_True;
899 }
900 }
901 }
902 DeclareAndCast(StepData_SelectMember,sm,val);
903 if (sm.IsNull()) {
904 sm = new StepData_SelectNamed;
905 val = sm;
906 }
907 if (!sm->SetName (rectyp.ToCString())) return Standard_False; // loupe
908 return ReadAny (numsub,1,mess,ach,descr,val);
909 }
910 }
911 default : break;
912 }
913 return Standard_False;
914}
915
916
917// ....
918
919
920//=======================================================================
921//function : ReadXY
922//purpose :
923//=======================================================================
924
925Standard_Boolean StepData_StepReaderData::ReadXY(const Standard_Integer num,
926 const Standard_Integer nump,
927 const Standard_CString mess,
928 Handle(Interface_Check)& ach,
929 Standard_Real& X, Standard_Real& Y) const
930{
931 Handle(String) errmess; // Null si pas d erreur
932 Standard_Integer numsub = SubListNumber(num,nump,Standard_False);
933 if (numsub != 0) {
934 if (NbParams(numsub) == 2) {
935 const Interface_FileParameter& FPX = Param(numsub,1);
936 if (FPX.ParamType() == Interface_ParamReal) X =
937 Interface_FileReaderData::Fastof(FPX.CValue());
938 else errmess = new String("Parameter n0.%d (%s) : (X,Y) X not a Real");
939
940 const Interface_FileParameter& FPY = Param(numsub,2);
941 if (FPY.ParamType() == Interface_ParamReal) Y =
942 Interface_FileReaderData::Fastof( FPY.CValue());
943 else errmess = new String("Parameter n0.%d (%s) : (X,Y) Y not a Real");
944
945 }
946 else errmess = new String("Parameter n0.%d (%s) : (X,Y) has not 2 params");
947 }
948 else errmess = new String("Parameter n0.%d (%s) : (X,Y) not a SubList");
949
950 if (errmess.IsNull()) return Standard_True;
951 sprintf (txtmes,errmess->ToCString(),nump,mess);
952 ach->AddFail(txtmes,errmess->ToCString());
953 return Standard_False;
954}
955
956
957//=======================================================================
958//function : ReadXYZ
959//purpose :
960//=======================================================================
961
962Standard_Boolean StepData_StepReaderData::ReadXYZ(const Standard_Integer num,
963 const Standard_Integer nump,
964 const Standard_CString mess,
965 Handle(Interface_Check)& ach,
966 Standard_Real& X, Standard_Real& Y,
967 Standard_Real& Z) const
968{
969 Handle(String) errmess; // Null si pas d erreur
970 Standard_Integer numsub = SubListNumber(num,nump,Standard_False);
971 if (numsub != 0) {
972 if (NbParams(numsub) == 3) {
973 const Interface_FileParameter& FPX = Param(numsub,1);
974 if (FPX.ParamType() == Interface_ParamReal) X =
975 Interface_FileReaderData::Fastof(FPX.CValue());
976 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) X not a Real");
977
978 const Interface_FileParameter& FPY = Param(numsub,2);
979 if (FPY.ParamType() == Interface_ParamReal) Y =
980 Interface_FileReaderData::Fastof(FPY.CValue());
981 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) Y not a Real");
982
983 const Interface_FileParameter& FPZ = Param(numsub,3);
984 if (FPZ.ParamType() == Interface_ParamReal) Z =
985 Interface_FileReaderData::Fastof(FPZ.CValue());
986 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) Z not a Real");
987
988 }
989 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) has not 3 params");
990 }
991 else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) not a SubList");
992
993 if (errmess.IsNull()) return Standard_True;
994 sprintf (txtmes,errmess->ToCString(),nump,mess);
995 ach->AddFail(txtmes,errmess->ToCString());
996 return Standard_False;
997}
998
999
1000//=======================================================================
1001//function : ReadReal
1002//purpose :
1003//=======================================================================
1004
1005Standard_Boolean StepData_StepReaderData::ReadReal(const Standard_Integer num,
1006 const Standard_Integer nump,
1007 const Standard_CString mess,
1008 Handle(Interface_Check)& ach,
1009 Standard_Real& val) const
1010{
1011 Handle(String) errmess; // Null si pas d erreur
1012 if (nump > 0 && nump <= NbParams(num)) {
1013 const Interface_FileParameter& FP = Param(num,nump);
1014 if (FP.ParamType() == Interface_ParamReal) val =
1015 Interface_FileReaderData::Fastof(FP.CValue());
1016 else errmess = new String("Parameter n0.%d (%s) not a Real");
1017 }
1018 else errmess = new String("Parameter n0.%d (%s) absent");
1019
1020 if (errmess.IsNull()) return Standard_True;
1021 sprintf (txtmes,errmess->ToCString(),nump,mess);
1022 ach->AddFail(txtmes,errmess->ToCString());
1023 return Standard_False;
1024}
1025
1026
1027// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1028
1029
1030//=======================================================================
1031//function : ReadEntity
1032//purpose :
1033//=======================================================================
1034
1035Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num,
1036 const Standard_Integer nump,
1037 const Standard_CString mess,
1038 Handle(Interface_Check)& ach,
1039 const Handle(Standard_Type)& atype,
1040 Handle(Standard_Transient)& ent) const
1041{
1042 Handle(String) errmess; // Null si pas d erreur
1043 Standard_Boolean warn = Standard_False;
1044 if (nump > 0 && nump <= NbParams(num)) {
1045 const Interface_FileParameter& FP = Param(num,nump);
1046 Standard_Integer nent = FP.EntityNumber();
1047 if (FP.ParamType() == Interface_ParamIdent) {
1048 warn = (acceptvoid > 0);
1049 if (nent > 0) {
1050 Handle(Standard_Transient) entent = BoundEntity(nent);
1051 if (entent.IsNull() || !entent->IsKind(atype))
1052 errmess = new String("Parameter n0.%d (%s) : Entity has illegal type");
1053 else ent = entent;
1054 }
1055 else errmess = new String("Parameter n0.%d (%s) : Unresolved reference");
1056 }
1057 else {
1058 if (acceptvoid && FP.ParamType() == Interface_ParamVoid) warn = Standard_True;
1059 errmess = new String("Parameter n0.%d (%s) not an Entity");
1060 }
1061 }
1062 else {
1063 warn = (acceptvoid > 0);
1064 errmess = new String("Parameter n0.%d (%s) absent");
1065 }
1066
1067 if (errmess.IsNull()) return Standard_True;
1068 sprintf (txtmes,errmess->ToCString(),nump,mess);
1069 if (warn) ach->AddWarning(txtmes,errmess->ToCString());
1070 else ach->AddFail(txtmes,errmess->ToCString());
1071 return Standard_False;
1072}
1073
1074
1075//=======================================================================
1076//function : ReadEntity
1077//purpose :
1078//=======================================================================
1079
1080Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num,
1081 const Standard_Integer nump,
1082 const Standard_CString mess,
1083 Handle(Interface_Check)& ach,
1084 StepData_SelectType& sel) const
1085{
1086 Handle(String) errmess; // Null si pas d erreur
1087 Standard_Boolean warn = Standard_False;
1088 if (nump > 0 && nump <= NbParams(num)) {
1089 const Interface_FileParameter& FP = Param(num,nump);
1090 Standard_Integer nent = FP.EntityNumber();
1091 if (FP.ParamType() == Interface_ParamIdent) {
1092 warn = (acceptvoid > 0);
1093 if (nent > 0) {
1094 Handle(Standard_Transient) entent = BoundEntity(nent);
1095 if (!sel.Matches(entent))
1096 errmess = new String("Parameter n0.%d (%s) : Entity has illegal type");
1097 else
1098 sel.SetValue(entent);
1099 }
1100 else
1101 errmess = new String("Parameter n0.%d (%s) : Unresolved reference");
1102 }
1103 else if (FP.ParamType() == Interface_ParamVoid) {
1104 if (acceptvoid) warn = Standard_True;
1105 errmess = new String("Parameter n0.%d (%s) not an Entity");
1106 }
1107 else {
1108 // Cas restant : on s interesse en fait au SelectMember ...
1109 Handle(Standard_Transient) sm = sel.NewMember();
1110 // SelectMember qui assure ce role. Peut etre specialise
1111 if (!ReadAny (num,nump,mess,ach,sel.Description(),sm))
1112 errmess = new String("Parameter n0.%d (%s) : could not be read");
1113 if (!sel.Matches(sm))
1114 errmess = new String("Parameter n0.%d (%s) : illegal parameter type");
1115 else
1116 sel.SetValue(sm);
1117 }
1118 }
1119 else {
1120 warn = (acceptvoid > 0);
1121 errmess = new String("Parameter n0.%d (%s) absent");
1122 }
1123
1124 if (errmess.IsNull()) return Standard_True;
1125 sprintf (txtmes,errmess->ToCString(),nump,mess);
1126 if (warn) ach->AddWarning(txtmes,errmess->ToCString());
1127 else ach->AddFail(txtmes,errmess->ToCString());
1128 return Standard_False;
1129}
1130
1131
1132// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1133
1134
1135//=======================================================================
1136//function : ReadInteger
1137//purpose :
1138//=======================================================================
1139
1140Standard_Boolean StepData_StepReaderData::ReadInteger(const Standard_Integer num,
1141 const Standard_Integer nump,
1142 const Standard_CString mess,
1143 Handle(Interface_Check)& ach,
1144 Standard_Integer& val) const
1145{
1146 Handle(String) errmess; // Null si pas d erreur
1147 if (nump > 0 && nump <= NbParams(num)) {
1148 const Interface_FileParameter& FP = Param(num,nump);
1149 if (FP.ParamType() == Interface_ParamInteger) val = atoi(FP.CValue());
1150 else errmess = new String("Parameter n0.%d (%s) not an Integer");
1151 }
1152 else errmess = new String("Parameter n0.%d (%s) absent");
1153
1154 if (errmess.IsNull()) return Standard_True;
1155 sprintf (txtmes,errmess->ToCString(),nump,mess);
1156 ach->AddFail(txtmes,errmess->ToCString());
1157 return Standard_False;
1158}
1159
1160
1161//=======================================================================
1162//function : ReadBoolean
1163//purpose :
1164//=======================================================================
1165
1166Standard_Boolean StepData_StepReaderData::ReadBoolean(const Standard_Integer num,
1167 const Standard_Integer nump,
1168 const Standard_CString mess,
1169 Handle(Interface_Check)& ach,
1170 Standard_Boolean& flag) const
1171{
1172 Handle(String) errmess; // Null si pas d erreur
1173 if (nump > 0 && nump <= NbParams(num)) {
1174 const Interface_FileParameter& FP = Param(num,nump);
1175 if (FP.ParamType() == Interface_ParamEnum) {
1176 Standard_CString txt = FP.CValue();
1177 if (!strcmp(txt,".T.")) flag = Standard_True;
1178 else if (!strcmp(txt,".F.")) flag = Standard_False;
1179 else errmess = new String("Parameter n0.%d (%s) : Incorrect Boolean Value");
1180 }
1181 else errmess = new String("Parameter n0.%d (%s) not a Boolean");
1182 }
1183 else errmess = new String("Parameter n0.%d (%s) absent");
1184
1185 if (errmess.IsNull()) return Standard_True;
1186 sprintf (txtmes,errmess->ToCString(),nump,mess);
1187 ach->AddFail(txtmes,errmess->ToCString());
1188 return Standard_False;
1189}
1190
1191
1192//=======================================================================
1193//function : ReadLogical
1194//purpose :
1195//=======================================================================
1196
1197Standard_Boolean StepData_StepReaderData::ReadLogical(const Standard_Integer num,
1198 const Standard_Integer nump,
1199 const Standard_CString mess,
1200 Handle(Interface_Check)& ach,
1201 StepData_Logical& flag) const
1202{
1203 Handle(String) errmess; // Null si pas d erreur
1204 if (nump > 0 && nump <= NbParams(num)) {
1205 const Interface_FileParameter& FP = Param(num,nump);
1206 if (FP.ParamType() == Interface_ParamEnum) {
1207 Standard_CString txt = FP.CValue();
1208 if (!strcmp(txt,".T.")) flag = StepData_LTrue;
1209 else if (!strcmp(txt,".F.")) flag = StepData_LFalse;
1210 else if (!strcmp(txt,".U.")) flag = StepData_LUnknown;
1211 else errmess = new String("Parameter n0.%d (%s) : Incorrect Logical Value");
1212 }
1213 else errmess = new String("Parameter n0.%d (%s) not a Logical");
1214 }
1215 else errmess = new String("Parameter n0.%d (%s) absent");
1216
1217 if (errmess.IsNull()) return Standard_True;
1218 sprintf (txtmes,errmess->ToCString(),nump,mess);
1219 ach->AddFail(txtmes,errmess->ToCString());
1220 return Standard_False;
1221}
1222
1223
1224//=======================================================================
1225//function : ReadString
1226//purpose :
1227//=======================================================================
1228
1229Standard_Boolean StepData_StepReaderData::ReadString(const Standard_Integer num,
1230 const Standard_Integer nump,
1231 const Standard_CString mess,
1232 Handle(Interface_Check)& ach,
1233 Handle(TCollection_HAsciiString)& val) const
1234{
1235 Handle(String) errmess; // Null si pas d erreur
1236 Standard_Boolean warn = Standard_False;
1237 if (nump > 0 && nump <= NbParams(num)) {
1238 const Interface_FileParameter& FP = Param(num,nump);
1239 if (FP.ParamType() == Interface_ParamText) {
1240 /*Standard_CString anStr = FP.CValue();
1241 if(strlen(anStr) < 3)
1242 val = new TCollection_HAsciiString("");
1243 else {
1244 val = new TCollection_HAsciiString(FP.CValue());
1245 CleanText (val);
1246 }*/
1247 val = new TCollection_HAsciiString(FP.CValue());
1248 CleanText (val);
1249 } else {
1250 if (acceptvoid && FP.ParamType() == Interface_ParamVoid) warn = Standard_True;
1251 errmess = new String("Parameter n0.%d (%s) not a quoted String");
1252 }
1253 }
1254 else errmess = new String("Parameter n0.%d (%s) absent");
1255
1256 if (errmess.IsNull()) return Standard_True;
1257 sprintf (txtmes,errmess->ToCString(),nump,mess);
1258 if (warn) ach->AddWarning(txtmes,errmess->ToCString());
1259 else ach->AddFail(txtmes,errmess->ToCString());
1260 return Standard_False;
1261}
1262
1263
1264//=======================================================================
1265//function : ReadEnumParam
1266//purpose :
1267//=======================================================================
1268
1269Standard_Boolean StepData_StepReaderData::ReadEnumParam(const Standard_Integer num,
1270 const Standard_Integer nump,
1271 const Standard_CString mess,
1272 Handle(Interface_Check)& ach,
1273 Standard_CString& text) const
1274{
1275 Handle(String) errmess; // Null si pas d erreur
1276 Standard_Boolean warn = Standard_False;
1277 if (nump > 0 && nump <= NbParams(num)) {
1278 const Interface_FileParameter& FP = Param(num,nump);
1279 if (FP.ParamType() == Interface_ParamEnum) {
1280 text = FP.CValue();
1281 warn = (acceptvoid > 0);
1282 } else if (FP.ParamType() == Interface_ParamVoid) {
1283 errmess =
1284 new String("Parameter n0.%d (%s) : Undefined Enumeration not allowed");
1285 warn = (acceptvoid > 0);
1286 }
1287 else errmess = new String("Parameter n0.%d (%s) not an Enumeration");
1288 }
1289 else errmess = new String("Parameter n0.%d (%s) absent");
1290
1291 if (errmess.IsNull()) return Standard_True;
1292 sprintf (txtmes,errmess->ToCString(),nump,mess);
1293 if (warn) ach->AddWarning(txtmes,errmess->ToCString());
1294 else ach->AddFail(txtmes,errmess->ToCString());
1295 return Standard_False;
1296}
1297
1298
1299//=======================================================================
1300//function : FailEnumValue
1301//purpose :
1302//=======================================================================
1303
1304void StepData_StepReaderData::FailEnumValue(const Standard_Integer /* num */,
1305 const Standard_Integer nump,
1306 const Standard_CString mess,
1307 Handle(Interface_Check)& ach) const
1308{
1309 Handle(String) errmess =
1310 new String("Parameter n0.%d (%s) : Incorrect Enumeration Value");
1311 sprintf (txtmes,errmess->ToCString(),nump,mess);
1312 ach->AddFail(txtmes,errmess->ToCString());
1313}
1314
1315
1316//=======================================================================
1317//function : ReadEnum
1318//purpose :
1319//=======================================================================
1320
1321Standard_Boolean StepData_StepReaderData::ReadEnum(const Standard_Integer num,
1322 const Standard_Integer nump,
1323 const Standard_CString mess,
1324 Handle(Interface_Check)& ach,
1325 const StepData_EnumTool& enumtool,
1326 Standard_Integer& val) const
1327{
1328// reprendre avec ReadEnumParam ?
1329 Handle(String) errmess; // Null si pas d erreur
1330 Standard_Boolean warn = Standard_False;
1331 if (nump > 0 && nump <= NbParams(num)) {
1332 const Interface_FileParameter& FP = Param(num,nump);
1333 if (FP.ParamType() == Interface_ParamEnum) {
1334 val = enumtool.Value (FP.CValue());
1335 if (val >= 0) return Standard_True;
1336 else errmess = new String("Parameter n0.%d (%s) : Incorrect Enumeration Value");
1337 warn = (acceptvoid > 0);
1338 }
1339 else if (FP.ParamType() == Interface_ParamVoid) {
1340 val = enumtool.NullValue();
1341 if (val < 0) errmess =
1342 new String("Parameter n0.%d (%s) : Undefined Enumeration not allowed");
1343 warn = (acceptvoid > 0);
1344 }
1345 else errmess = new String("Parameter n0.%d (%s) not an Enumeration");
1346 }
1347 else errmess = new String("Parameter n0.%d (%s) absent");
1348
1349 if (errmess.IsNull()) return Standard_True;
1350 sprintf (txtmes,errmess->ToCString(),nump,mess);
1351 if (warn)
1352 ach->AddWarning(txtmes,errmess->ToCString());
1353 else
1354 ach->AddFail(txtmes,errmess->ToCString());
1355 return Standard_False;
1356}
1357
1358
1359//=======================================================================
1360//function : ReadTypedParam
1361//purpose :
1362//=======================================================================
1363
1364Standard_Boolean StepData_StepReaderData::ReadTypedParam(const Standard_Integer num,
1365 const Standard_Integer nump,
1366 const Standard_Boolean mustbetyped,
1367 const Standard_CString mess,
1368 Handle(Interface_Check)& ach,
1369 Standard_Integer& numr,
1370 Standard_Integer& numrp,
1371 TCollection_AsciiString& typ) const
1372{
1373 Handle(String) errmess; // Null si pas d erreur
1374 if (nump > 0 && nump <= NbParams(num)) {
1375 const Interface_FileParameter& FP = Param(num,nump);
1376 if (FP.ParamType() != Interface_ParamSub) {
1377 // Pas une sous-liste : OK si admis
1378 numr = num; numrp = nump; typ.Clear();
1379 if (mustbetyped) {
1380 errmess = new String("Parameter n0.%d (%s) : single, not typed");
1381 sprintf (txtmes,errmess->ToCString(),nump,mess);
1382 ach->AddFail(txtmes,errmess->ToCString());
1383 return Standard_False;
1384 }
1385 return Standard_True;
1386 }
1387 numr = FP.EntityNumber(); numrp = 1;
1388 if (NbParams(numr) != 1) errmess =
1389 new String("Parameter n0.%d (%s) : SubList, not typed");
1390 typ = RecordType(numr);
1391 }
1392 else errmess = new String("Parameter n0.%d (%s) absent");
1393
1394 if (errmess.IsNull()) return Standard_True;
1395 sprintf (txtmes,errmess->ToCString(),nump,mess);
1396 ach->AddFail(txtmes,errmess->ToCString());
1397 return Standard_False;
1398}
1399
1400
1401//=======================================================================
1402//function : CheckDerived
1403//purpose :
1404//=======================================================================
1405
1406Standard_Boolean StepData_StepReaderData::CheckDerived(const Standard_Integer num,
1407 const Standard_Integer nump,
1408 const Standard_CString mess,
1409 Handle(Interface_Check)& ach,
1410 const Standard_Boolean errstat) const
1411{
1412 Handle(String) errmess; // Null si pas d erreur
1413 Standard_Boolean warn = !errstat;
1414 if (nump > 0 && nump <= NbParams(num)) {
1415 if (!strcmp(Param(num,nump).CValue(),"*")) return Standard_True;
1416 else errmess = new String("Parameter n0.%d (%s) not Derived");
1417 if (acceptvoid) warn = Standard_True;
1418 }
1419 else errmess = new String("Parameter n0.%d (%s) absent");
1420
1421 if (errmess.IsNull()) return Standard_True;
1422 sprintf (txtmes,errmess->ToCString(),nump,mess);
1423 if (warn) ach->AddWarning (txtmes,errmess->ToCString());
1424 else ach->AddFail (txtmes,errmess->ToCString());
1425 return Standard_False;
1426}
1427
1428
1429// #########################################################################
1430// .... Methodes specifiques (demandees par FileReaderData) .... //
1431
1432
1433//=======================================================================
1434//function : NbEntities
1435//purpose :
1436//=======================================================================
1437
1438Standard_Integer StepData_StepReaderData::NbEntities () const // redefined
1439{
1440 return thenbents;
1441}
1442
1443
1444//=======================================================================
1445//function : FindNextRecord
1446//purpose :
1447//=======================================================================
1448
1449Standard_Integer StepData_StepReaderData::FindNextRecord
1450 (const Standard_Integer num) const
1451{
1452 // retourne, sur un numero d enregistrement donne (par num), le suivant qui
1453 // definit une entite, ou 0 si c est fini :
1454 // passe le Header (nbhend premiers records) et
1455 // saute les enregistrements SCOPE et ENDSCOPE et les SOUS-LISTES
1456
1457 if (num < 0) return 0 ;
1458 Standard_Integer num1 = num + 1 ; if (num == 0) num1 = thenbhead + 1;
1459 Standard_Integer max = NbRecords() ;
1460
1461 while (num1 <= max ) {
1462 if (theidents(num1) > 0) return num1;
1463
1464 // SCOPE,ENDSCOPE et Sous-Liste ont un identifieur fictif: -1,-2 respectivement
1465 // et SUBLIST ont un negatif. Seule une vraie entite a un Ident positif
1466 num1 ++ ;
1467 }
1468 return 0;
1469}
1470
1471
1472//=======================================================================
1473//function : FindEntityNumber
1474//purpose :
1475//=======================================================================
1476
1477Standard_Integer StepData_StepReaderData::FindEntityNumber(const Standard_Integer num,
1478 const Standard_Integer id) const
1479{
1480 // Soit un "Id" : recherche dans les Parametres de type Ident de <num>,
1481 // si un d eux designe #Id justement. Si oui, retourne son EntityNumber
1482 if (num == 0) return 0;
1483 Standard_Integer nb = NbParams(num);
1484 for (Standard_Integer i = 1; i <= nb; i ++) {
1485 const Interface_FileParameter& FP = Param(num,i);
1486 if (FP.ParamType() != Interface_ParamIdent) continue;
1487 Standard_Integer ixp = atoi( &FP.CValue()[1] );
1488 if (ixp == id) return FP.EntityNumber();
1489 }
1490 return 0; // ici, pas trouve
1491}
1492
1493
1494// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1495// .... La fonction qui suit merite une attention speciale ....
1496
1497
1498// Cette methode precharge les EntityNumbers dans les Params : ils designent
1499// les Entites proprement dites dans la liste lue par BoundEntity
1500// Interet : adresse de meme les sous-listes (Num->no record dans le Direc)
1501// resultat exploite par ParamEntity et ParamNumber
1502
1503// En l absence de SCOPE, ou si les "ident" sont strictement ordonnes, a coup
1504// sur ils ne sont pas dupliques, on peut utiliser une IndexedMap en toute
1505// confiance. Sinon, il faut balayer dans le fichier, mais avec les SCOPES
1506// cela va beaucoup plus vite (s ils sont assez gros) : on s y retrouve.
1507
1508// Pour la recherche par balayage, On opere en plusieurs etapes
1509// Avant toute chose, le chargement a deja fait une preparation : les idents
1510// (Entity, SubList) sont deja en entiers (rapidite de lecture), en particulier
1511// dans les EntityNumber : ainsi, on lit cet ident, on le traite, et on remet
1512// a la place un vrai numero de Record
1513//
1514// D abord, on passe le directory en table d entiers, sous-listes expurgees
1515// en // , table inverse vers cette table, car les sous-listes peuvent par
1516// contre designer des objets ...
1517
1518// Pour les sous-listes, on exploite leur mode de construction : elles sont
1519// enregistrees AVANT d etre referencees. Un tableau "subn" note donc pour
1520// chaque numero de sous-liste (relatif a une entite qui suit, et reference
1521// par elle ou une autre sous-liste qui suit egalement), son n0 de record
1522// REMARQUE : ceci marche aussi pour le Header, traite par l occasion
1523
1524
1525//=======================================================================
1526//function : SetEntityNumbers
1527//purpose :
1528//=======================================================================
1529
1530void StepData_StepReaderData::SetEntityNumbers(const Standard_Boolean withmap)
1531{
1532 Handle(Message_Messenger) sout = Message::DefaultMessenger();
1533// Passe initiale : Resolution directe par Map
1534// si tout passe (pas de collision), OK. Sinon, autres passes a prevoir
1535// On resoud du meme coup les sous-listes
1536 Standard_Integer nbdirec = NbRecords() ;
1d37eeb6 1537 TColStd_Array1OfInteger subn(0, thelastn);
7fd59977 1538
1539 Standard_Boolean pbmap = Standard_False; // au moins un conflit
1540 Standard_Integer nbmap = 0;
1541 TColStd_IndexedMapOfInteger imap(thenbents);
1d37eeb6 1542 TColStd_Array1OfInteger indm(0, nbdirec); // Index Map -> Record Number (seulement si map)
7fd59977 1543
1544 Standard_Integer num; // svv Jan11 2000 : porting on DEC
1545 for (num = 1 ; num <= nbdirec ; num ++) {
1546 Standard_Integer ident = theidents(num);
1547 if (ident > 0) { // Ident normal -> Map ?
1548// Map : si Recouvrement, l inhiber. Sinon, noter index
1549 Standard_Integer indmap = imap.Add(ident);
1550 if (indmap <= nbmap) {
1551 indmap = imap.FindIndex(ident); // plus sur
1d37eeb6 1552 indm(indmap) = -1; // Map -> pb
7fd59977 1553 pbmap = Standard_True;
1554// pbmap signifie qu une autre passe sera necessaire ...
1555 } else {
1556 nbmap = indmap;
1d37eeb6 1557 indm(indmap) = num; // Map ->ident
7fd59977 1558 }
1559 }
1560 }
1561
1562 for (num = 1 ; num <= nbdirec ; num ++) {
1563 Standard_Integer ident = theidents(num);
1d37eeb6 1564 if (ident < -2) subn(-(ident+2)) = num; // toujours a jour ...
7fd59977 1565
1566 Standard_Integer nba = NbParams(num) ;
1567 Standard_Integer nda = (num == 1 ? 0 : ParamFirstRank(num-1));
1568
1569 for (Standard_Integer na = nba ; na > 0 ; na --) {
1570// On traite : les sous-listes (sf subn), les idents (si Map dit OK ...)
1571 Interface_FileParameter& FP = ChangeParameter (nda+na);
1572// Interface_FileParameter& FP = ChangeParam (num,na);
1573 Interface_ParamType letype = FP.ParamType();
1574 if (letype == Interface_ParamSub) {
1575 Standard_Integer numsub = FP.EntityNumber();
1576 if (numsub > thelastn) {
1577 sout<<"Bad Sub.N0, Record "<<num<<" Param "<<na<<":$"<<numsub<<endl;
1578 continue;
1579 }
1d37eeb6 1580 FP.SetEntityNumber(subn(numsub));
7fd59977 1581 } else if (letype == Interface_ParamIdent) {
1582 Standard_Integer id = FP.EntityNumber();
1583 Standard_Integer indmap = imap.FindIndex(id);
1584 if (indmap > 0) { // la map a trouve
1d37eeb6 1585 Standard_Integer num0 = indm(indmap);
7fd59977 1586 if (num0 > 0) FP.SetEntityNumber(num0); // ET VOILA, on a resolu
1587 else FP.SetEntityNumber(-id); // CONFLIT -> faudra resoudre ...
1588 } else { // NON RESOLU, si pas pbmap, le dire
1589 FP.SetEntityNumber(-id);
1590 if (pbmap) continue; // pbmap : on se retrouvera
1591 char failmess[100];
1592// ... Construire le Check ...
1593 sprintf(failmess,
1594 "Unresolved Reference, Ent.Id.#%d Param.n0 %d (Id.#%d)",
1595 ident,na,id);
1596 thecheck->AddFail(failmess,"Unresolved Reference");
1597// ... Et sortir message un peu plus complet
1598 sout << "*** ERR StepReaderData *** Pour Entite #"<< ident
1599 << "\n Type:" << RecordType(num)
1600 << " Param.n0 " << na << ": #" << id << " Non trouve" << endl ;
1601 } // FIN Mapping
1602 } // FIN Traitement Reference
1603 } // FIN Boucle Parametres
1604 } // FIN Boucle Repertoires
1605
7fd59977 1606 if (!pbmap) {
1d37eeb6 1607 return;
7fd59977 1608 }
1609 sout << " -- 2nd pass required --";
1610
1611 Standard_Integer nbseq = thenbents+2*thenbscop;
1d37eeb6
D
1612 TColStd_Array1OfInteger inds(0, nbseq); // n0 Record/Entite
1613 TColStd_Array1OfInteger indi(0, nbseq); // Idents/scopes
1614 TColStd_Array1OfInteger indr(0, nbdirec); // inverse de nds
1615 Handle(TColStd_HArray1OfInteger) indx; // pour EXPORT (silya)
7fd59977 1616
1617 imap.Clear();
1618 Standard_Boolean iamap = withmap; // (par defaut True)
1619 nbmap = 0;
1620
1621 TColStd_SequenceOfInteger scopile; // chainage des scopes note par pile
1622 Standard_Integer nr = 0 ;
1623 for (num = 1 ; num <= nbdirec ; num ++) {
1624 Standard_Integer ident = theidents(num);
1625 if (ident < -2) { // SOUS-LISTE (cas le plus courant)
1d37eeb6 1626 indr(num) = nr + 1; // recherche basee sur nr (objet qui suit)
7fd59977 1627 } else if (ident >= 0) { // Ident normal
1d37eeb6 1628 nr ++; inds(nr) = num; indi(nr) = ident; indr(num) = nr;
7fd59977 1629 if (ident > 0) { // et non (iamap && ident > 0)
1630// Map : si Recouvrement, l inhiber. Sinon, noter index
1631 Standard_Integer indmap = imap.Add(ident);
1632 if (indmap <= nbmap) {
1633 Standard_Boolean errorscope = Standard_False;
1634 indmap = imap.FindIndex(ident); // plus sur
1635 pbmap = Standard_True;
1636 if (thenbscop == 0) errorscope = Standard_True;
1637// Numeros identiques alors quilnya pas de SCOPE ? ERREUR !
1638// (Bien sur, silya des SCOPES, on passe au travers, mais bon...)
1639 else {
1640// Silya des SCOPES, tachons d y voir de plus pres pour signaler un probleme
1641// Erreur si MEME groupe SCOPE
1642// ATTENTION, on recherche, non dans tous les records, mais dans les records
1643// CHAINES, cf nr et non num (pas de sous-liste, chainage scope-endscope)
1644 Standard_Integer fromscope = nr;
1d37eeb6 1645 Standard_Integer toscope = indm(indmap);
7fd59977 1646 if (toscope < 0) toscope = -toscope;
302f96fb 1647 for(;;) {
7fd59977 1648 fromscope --; // iteration de base
1649 if (fromscope <= toscope) {
1650 errorscope = Standard_True; // BANG, on est dessus
1651 break;
1652 }
1d37eeb6 1653 Standard_Integer idtest = indi(fromscope);
7fd59977 1654 if (idtest >= 0) continue; // le suivant (enfin, le precedent)
1655 if (idtest == -1) break; // pas meme niveau, donc c est OK
1656 if (idtest == -3) {
1d37eeb6 1657 fromscope = inds(fromscope);
7fd59977 1658 if (fromscope < toscope) break; // on sort, pas en meme niveau
1659 }
1660 }
1661 }
1662 if (errorscope) {
1663// On est dedans : le signaler
1664 char ligne[80];
1665 sprintf(ligne,"Ident defined SEVERAL TIMES : #%d",ident);
1666 thecheck->AddFail(ligne,"Ident defined SEVERAL TIMES : #%d");
1667 sout << "StepReaderData:SetEntityNumbers, " << ligne << endl;
1668 }
1d37eeb6 1669 if (indm(indmap) > 0) indm(indmap) = -indm(indmap); // Pas pour Map
7fd59977 1670// Cas Normal pour la Map
1671 } else {
1672 nbmap = indmap;
1d37eeb6 1673 indm(indmap) = nr; // Map ->(indm)->inds
7fd59977 1674 }
1675 }
1676 } else if (ident == -1) { // SCOPE
1d37eeb6 1677 nr ++; inds(nr) = num; indi(nr) = -1; indr(num) = 0;
7fd59977 1678 scopile.Append(nr) ;
1679 } else if (ident == -2) { // ENDSCOPE
1680 Standard_Integer nscop = scopile.Last() ; // chainage SCOPE-ENDSCOPE
1681 scopile.Remove(scopile.Length()) ;
1d37eeb6 1682 nr ++; inds(nr) = nscop; indi(nr) = -3; indr(num) = 0; inds(nscop) = nr;
7fd59977 1683 if (NbParams(num) > 0) {
1684// EXPORT : traitement special greffe sur celui de SCOPE (sans le perturber)
1d37eeb6
D
1685 if (indx.IsNull()) {
1686 indx = new TColStd_HArray1OfInteger(0, nbseq);
1687 for (Standard_Integer ixp = 0; ixp <= nbseq; ixp ++) indx->ChangeValue(ixp) = 0;
7fd59977 1688 }
1d37eeb6 1689 indx->ChangeValue(nr) = num; indx->ChangeValue(nscop) = num;
7fd59977 1690 }
1691 } else if (ident == 0) { // HEADER
1d37eeb6 1692 indr(num) = 0;
7fd59977 1693 }
1694 }
1695
1696// .. Resolution des EXPORT, silyena et silya besoin ..
1697// Pour chaque valeur de EXPORT qui n a pas ete resolue par la MAP,
1698// determiner sa position locale par recherche en arriere depuis ENDSCOPE
1d37eeb6 1699 if ((!iamap || pbmap) && !indx.IsNull()) {
7fd59977 1700 for (nr = 0; nr <= nbseq; nr ++) {
1d37eeb6
D
1701 if (indx->Value(nr) == 0 && indi(nr) != -3) continue; // ENDSCOPE + EXPORT
1702 num = indx->Value(nr);
7fd59977 1703 Standard_Integer nba = NbParams(num);
1704 for (Standard_Integer na = 1; na <= nba; na ++) {
1705 Interface_FileParameter& FP = ChangeParam (num,na);
1706 if (FP.ParamType() != Interface_ParamIdent) continue;
1707 Standard_Integer id = - FP.EntityNumber();
1708 if (id < 0) continue; // deja resolu en tete
1709/* if (imap.Contains(id)) { et voila
1d37eeb6 1710 FP.SetEntityNumber(indm(imap.FindIndex(id)));
7fd59977 1711 continue;
1712 } */
1713
1714// Recherche du Id demande : si EXPORT imbrique, deja resolu mais il faut
1715// regarder ! (inutile par contre d aller y voir : c est deja fait, car
1716// un EXPORT imbrique a ete traite AVANT celui qui imbrique)
1717 Standard_Integer n0 = nr-1 ;
1d37eeb6 1718 if (indi(n0) == -3) n0 --; // si on suit juste un ENDSCOPE
7fd59977 1719 while (n0 > 0) {
1d37eeb6 1720 Standard_Integer irec = indi(n0);
7fd59977 1721 if (irec == id) { // trouve
1d37eeb6 1722 FP.SetEntityNumber(inds(n0));
7fd59977 1723 break ;
1724 }
1725 if (irec == -1) break; // SCOPE : fin de ce SCOPE/ENDSCOPE
1726 if (irec == -3) {
1727// gare a EXPORT : si un EXPORT detient Id, noter son Numero deja calcule
1728// Attention : Id a lire depuis CValue car EntityNumber deja resolu
1d37eeb6 1729 Standard_Integer nok = FindEntityNumber (indx->Value(n0),id);
7fd59977 1730 if (nok > 0) {
1731 FP.SetEntityNumber(nok);
1732 break;
1733 }
1d37eeb6 1734 n0 = inds(n0); // ENDSCOPE ou EXPORT infructueux : le sauter
7fd59977 1735 } // fin traitement sur un ENDSCOPE ou EXPORT
1736 n0 -- ;
1737 } // fin resolution d un Parametre EXPORT
1738 } // fin resolution de la liste d un EXPORT
1739 } // fin bouclage sur les EXPORT
1740 }
1741
1742// Exploitation de la table : bouclage porte sur la table
1743
1744// Traitement des sous-listes : se fait dans la foulee, par gestion d une pile
1745// basee sur la constitution des sous-listes
1746 Standard_Integer maxsubpil = 30; // pile simulee avec un Array : tres fort
1747 Handle(TColStd_HArray1OfInteger) subpile = // ... gagne de la memoire ...
1748 new TColStd_HArray1OfInteger (1,maxsubpil);
1749 Standard_Integer nbsubpil = 0; // ... et tellement plus rapide !
1750
1751 for (num = 1 ; num <= nbdirec ; num ++) {
1d37eeb6 1752 nr = indr(num);
7fd59977 1753 if (nr == 0) continue; // pas un objet ou une sous-liste
1754 Standard_Integer nba = NbParams(num) ;
1755 for (Standard_Integer na = nba ; na > 0 ; na --) {
1756// On lit depuis la fin : cela permet de traiter les sous-listes dans la foulee
1757// Sinon, on devrait noter qu il y a eu des sous-listes et reprendre ensuite
1758
1759 Interface_FileParameter& FP = ChangeParam (num,na);
1760 Interface_ParamType letype = FP.ParamType();
1761 if (letype == Interface_ParamSub) {
1762// parametre type sous-liste : numero de la sous-liste lu par depilement
1763 FP.SetEntityNumber(subpile->Value(nbsubpil));
1764 nbsubpil --; // subpile->Remove(nbsubpil);
1765
1766 } else if (letype == Interface_ParamIdent) {
1767// parametre type ident (reference une entite) : chercher ident demande
1768 Standard_Integer id = - FP.EntityNumber();
1769 if (id < 0) continue; // deja resolu en tete
1770
1771// Voila : on va chercher id dans ndi; algorithme de balayage
1772 Standard_Integer pass, sens, nok, n0,irec; pass = sens = nok = 0;
1773 if (!iamap) pass = 1; // si map non disponible
1774 while (pass < 3) {
1775 pass ++ ;
1776// MAP disponible
1777 if (pass == 1) { // MAP DISPONIBLE
1778 Standard_Integer indmap = imap.FindIndex(id);
1779 if (indmap > 0) { // la map a trouve
1d37eeb6 1780 nok = indm(indmap);
7fd59977 1781 if (nok < 0) continue; // CONFLIT -> faut resoudre ...
1782 break;
1783 }
1784 else continue;
1785 }
1786// 1re Passe : REMONTEE -> Debut fichier
1787 if (sens == 0 && nr > 1) {
1788 n0 = nr-1 ;
1d37eeb6 1789 if (indi(n0) == -3) n0 --; // si on suit juste un ENDSCOPE
7fd59977 1790 while (n0 > 0) {
1d37eeb6 1791 irec = indi(n0);
7fd59977 1792 if (irec == id) { // trouve
1793 nok = n0 ; break ;
1794 }
1795// ENDSCOPE : Attention a EXPORT sinon sauter
1796 if (irec == -3) {
1d37eeb6 1797 if (indx.IsNull()) n0 = inds(n0);
7fd59977 1798 else {
1799// EXPORT, il faut regarder
1d37eeb6 1800 nok = FindEntityNumber (indx->Value(n0),id);
7fd59977 1801 if (nok > 0) break;
1d37eeb6 1802 n0 = inds(n0); // ENDSCOPE : le sauter
7fd59977 1803 }
1804 }
1805 n0 -- ;
1806 }
1807// 2me Passe : DESCENTE -> Fin fichier
1808 } else if (nr < nbseq) { // descente -> fin fichier
1809 n0 = nr+1 ;
1810 while (n0 <= nbseq) {
1d37eeb6 1811 irec = indi(n0);
7fd59977 1812 if (irec == id) { // trouve
1813 nok = n0 ; break ;
1814 }
1815// SCOPE : Attention a EXPORT sinon sauter
1816 if (irec == -1) {
1d37eeb6 1817 if (indx.IsNull()) n0 = inds(n0);
7fd59977 1818 else {
1819// EXPORT, il faut regarder
1d37eeb6 1820 nok = FindEntityNumber (indx->Value(n0),id);
7fd59977 1821 if (nok > 0) break;
1d37eeb6 1822 n0 = inds(n0); // SCOPE : le sauter
7fd59977 1823 }
1824 }
1825 n0 ++ ;
1826 }
1827 }
1828 if (nok > 0) break ;
1829 sens = 1 - sens ; // passe suivante
1830 }
1831 // ici on a nok, numero trouve
1832 if (nok > 0) {
1d37eeb6 1833 Standard_Integer num0 = inds(nok);
7fd59977 1834 FP.SetEntityNumber(num0); // ET VOILA, on a resolu
1835
1836 // pas trouve : le signaler
1837 } else {
1838// Alimenter le Check ... Pour cela, determiner n0 Entite et Ident
1839 char failmess[100];
1840 Standard_Integer nument = 0;
1841 Standard_Integer n0ent; // svv Jan11 2000 : porting on DEC
1842 for (n0ent = 1; n0ent <= nr; n0ent ++) {
1d37eeb6 1843 if (indi(n0ent) > 0) nument ++;
7fd59977 1844 }
1845 Standard_Integer ident = RecordIdent(num);
1846 if (ident < 0) {
1847 for (n0ent = num + 1; n0ent <= nbdirec; n0ent ++) {
1848 ident = RecordIdent(n0ent); if (ident > 0) break;
1849 }
1850 }
1851// ... Construire le Check ...
1852 sprintf(failmess,
1853 "Unresolved Reference, Ent.n0 %d (Id.#%d) Param.n0 %d (Id.#%d)",
1854 nument,ident,na,id);
1855 thecheck->AddFail(failmess,"Unresolved Reference");
1856// ... Et sortir message un peu plus complet
1857 sout << "*** ERR StepReaderData *** Pour Entite "<<nument
1858 <<", a "<< (nr*100)/nbseq<<"% de DATA : #"<< ident
1859 << "\n Type:" << RecordType(num)
1860 << " Param.n0 " << na << ": #" << id << " Non trouve" << endl ;
1861 FP.SetEntityNumber(0); // -> Reference non resolue
1862 }
1863 }
1864 }
1865// Si ce record est lui-meme une sous-liste, empiler !
1d37eeb6 1866 if (inds(nr) != num) {
7fd59977 1867 if (nbsubpil >= maxsubpil) {
1868 maxsubpil = maxsubpil+30;
1869 Handle(TColStd_HArray1OfInteger) newsubpil =
1870 new TColStd_HArray1OfInteger (1,maxsubpil);
1871 for (Standard_Integer bidpil = 1; bidpil <= maxsubpil - 30; bidpil ++)
1872 newsubpil->SetValue(bidpil,subpile->Value(bidpil));
1873 subpile = newsubpil;
1874 }
1875 nbsubpil ++;
1876 subpile->SetValue(nbsubpil,num); // Append(num);
1877 }
1878 }
7fd59977 1879}
1880
1881
1882// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1883// .... Gestion du Header : Preparation, lecture ....
1884
1885
1886//=======================================================================
1887//function : FindNextHeaderRecord
1888//purpose :
1889//=======================================================================
1890
1891Standard_Integer StepData_StepReaderData::FindNextHeaderRecord
1892 (const Standard_Integer num) const
1893{
1894// retourne, sur un numero d enregistrement donne (par num), le suivant qui
1895// definit une entite, ou 0 si c est fini :
1896// Opere comme FindNextRecord mais ne balaie que le Header
1897
1898 if (num < 0) return 0 ;
1899 Standard_Integer num1 = num + 1 ;
1900 Standard_Integer max = thenbhead;
1901
1902 while (num1 <= max ) {
1903// SCOPE,ENDSCOPE et Sous-Liste ont un identifieur negatif
1904// Ne retenir que les Idents positifs ou nuls (nul : pas d Ident dans Header)
1905 if ( RecordIdent(num1) >= 0) return num1 ;
1906 num1 ++ ;
1907 }
1908 return 0;
1909}
1910
1911
1912//=======================================================================
1913//function : PrepareHeader
1914//purpose :
1915//=======================================================================
1916
1917void StepData_StepReaderData::PrepareHeader ()
1918{
1919// Resolution des references : ne concerne que les sous-listes
1920// deja faite par SetEntityNumbers donc pas de souci a se faire
1921
1922/*
1923// Algorithme repris et adapte de SetEntityNumbers
1924// Traitement des sous-listes : se fait dans la foulee, par gestion d une pile
1925// basee sur la constitution des sous-listes
1926 TColStd_SequenceOfInteger subpile;
1927 Standard_Integer nbsubpil = 0; // profondeur de pile mais plus rapide ...
1928
1929 for (Standard_Integer num = 1 ; num <= thenbhead ; num ++) {
1930 Standard_Integer nba = NbParams(num) ;
1931 for (Standard_Integer na = nba ; na > 0 ; na --) {
1932.. On lit depuis la fin : cela permet de traiter les sous-listes dans la foulee
1933.. Sinon, on devrait noter qu il y a eu des sous-listes et reprendre ensuite
1934
1935 Interface_FileParameter& FP = ChangeParam(num,na);
1936 Interface_ParamType letype = FP.ParamType();
1937 if (letype == Interface_ParamSub) {
1938.. parametre type sous-liste : numero de la sous-liste lu par depilement
1939 FP.SetEntityNumber(subpile.Last());
1940.. .. SetParam(num,na,FP);
1941 subpile.Remove(nbsubpil);
1942 nbsubpil --;
1943 }
1944 }
1945.. Si c est une sous-liste, empiler
1946 if (RecordIdent(num) < -2) {
1947 subpile.Append(num);
1948 nbsubpil ++;
1949 }
1950 }
1951*/
1952}
1953
1954
1955//=======================================================================
1956//function : GlobalCheck
1957//purpose :
1958//=======================================================================
1959
1960const Handle(Interface_Check) StepData_StepReaderData::GlobalCheck () const
1961{
1962 return thecheck;
1963}