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