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