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