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