mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-06 18:26:22 +03:00
License statement text corrected; compiler warnings caused by Bison 2.41 disabled for MSVC; a few other compiler warnings on 54-bit Windows eliminated by appropriate type cast Wrong license statements corrected in several files. Copyright and license statements added in XSD and GLSL files. Copyright year updated in some files. Obsolete documentation files removed from DrawResources.
1922 lines
74 KiB
C++
1922 lines
74 KiB
C++
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
// abv 09.04.99 S4136: eliminate parameter step.readaccept.void
|
|
// sln 04,10.2001. BUC61003. Prevent exception which may occur during reading of complex entity (if entity's items are not in alphabetical order)
|
|
#include <StepData_StepReaderData.ixx>
|
|
#include <StepData_StepModel.hxx>
|
|
#include <Interface_FileParameter.hxx>
|
|
#include <Interface_ParamList.hxx>
|
|
#include <Message_Messenger.hxx>
|
|
#include <Message.hxx>
|
|
#include <Interface_Static.hxx>
|
|
#include <Interface_Macros.hxx>
|
|
|
|
#include <TColStd_SequenceOfInteger.hxx>
|
|
#include <TColStd_HArray1OfInteger.hxx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TColStd_IndexedMapOfInteger.hxx>
|
|
#include <TCollection_HAsciiString.hxx>
|
|
|
|
#include <TColStd_HArray1OfTransient.hxx>
|
|
#include <TColStd_HArray1OfReal.hxx>
|
|
#include <Interface_HArray1OfHAsciiString.hxx>
|
|
#include <StepData_SelectMember.hxx>
|
|
#include <StepData_SelectNamed.hxx>
|
|
#include <StepData_SelectReal.hxx>
|
|
#include <StepData_SelectInt.hxx>
|
|
#include <TColStd_HSequenceOfReal.hxx>
|
|
#include <StepData_SelectArrReal.hxx>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
// Le Header est constitue d entites analogues dans leur principe a celles
|
|
// du Data, a ceci pres qu elles sont sans identifieur, et ne peuvent ni
|
|
// referencer, ni etre referencees (que ce soit avec Header ou avec Data)
|
|
// Ainsi, dans StepReaderData, le Header est constitue des "thenbhead" 1res Entites
|
|
|
|
|
|
// #########################################################################
|
|
// .... Creation et Acces de base aux donnees atomiques du fichier ....
|
|
|
|
typedef TCollection_HAsciiString String;
|
|
typedef Handle(TCollection_HAsciiString) Handle(String);
|
|
static char txtmes[200]; // plus commode que redeclarer partout
|
|
|
|
|
|
static Standard_Boolean initstr = Standard_False;
|
|
|
|
#define Maxlst 64
|
|
//static TCollection_AsciiString subl[Maxlst]; // Maxlst : minimum 10
|
|
|
|
static Standard_Integer acceptvoid = 0;
|
|
|
|
// ---------- Fonctions Utilitaires ----------
|
|
|
|
//=======================================================================
|
|
//function : CleanText
|
|
//purpose :
|
|
//=======================================================================
|
|
static void CleanText (const Handle(TCollection_HAsciiString)& val)
|
|
{
|
|
Standard_Integer n = val->Length(); // avant reduction
|
|
val->Remove(n);
|
|
val->Remove(1);
|
|
// Ne pas oublier de traiter les caracteres speciaux
|
|
for (Standard_Integer i = n-2; i > 0; i --) {
|
|
char uncar = val->Value(i);
|
|
if (uncar == '\n')
|
|
{ val->Remove(i); if (i < n-2) uncar = val->Value(i); }
|
|
if (uncar == '\'' && i < n-2) {
|
|
if (val->Value(i+1) == '\'') { val->Remove(i+1); continue; }
|
|
}
|
|
if (uncar == '\\' && i < n-2) {
|
|
if (val->Value(i+1) == '\\') { val->Remove(i+1); continue; }
|
|
}
|
|
else if (uncar == '\\' && i < n-3) {
|
|
if (val->Value(i+2) == '\\') {
|
|
if (val->Value(i+1) == 'N')
|
|
{ val->SetValue(i,'\n'); val->Remove(i+1,2); continue; }
|
|
if (val->Value(i+1) == 'T')
|
|
{ val->SetValue(i,'\t'); val->Remove(i+1,2); continue; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ------------- METHODES -------------
|
|
|
|
//=======================================================================
|
|
//function : StepData_StepReaderData
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
StepData_StepReaderData::StepData_StepReaderData
|
|
(const Standard_Integer nbheader, const Standard_Integer nbtotal,
|
|
const Standard_Integer nbpar)
|
|
: Interface_FileReaderData (nbtotal,nbpar), theidents (1,nbtotal),
|
|
thetypes (1,nbtotal) //, themults (1,nbtotal)
|
|
{
|
|
// char textnum[10];
|
|
thenbscop = 0; thenbents = 0; thelastn = 0; thenbhead = nbheader;
|
|
//themults.Init(0);
|
|
thecheck = new Interface_Check;
|
|
//:S4136 acceptvoid = Interface_Static::IVal("step.readaccept.void");
|
|
if (initstr) return;
|
|
//for (Standard_Integer i = 0; i < Maxlst; i ++) {
|
|
// sprintf(textnum,"$%d",i+1);
|
|
// subl[i].AssignCat(textnum);
|
|
//}
|
|
initstr = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SetRecord
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepReaderData::SetRecord (const Standard_Integer num,
|
|
const Standard_CString ident,
|
|
const Standard_CString type,
|
|
const Standard_Integer /* nbpar */)
|
|
{
|
|
Standard_Integer numlst;
|
|
/*
|
|
if (strcmp(type,"/ * (SUB) * /") == 0) { // defini dans recfile.pc
|
|
thetypes.SetValue (num,sublist);
|
|
} else {
|
|
thenbents ++; // total de termes propres du fichier
|
|
thetypes.SetValue(num,TCollection_AsciiString(type));
|
|
// if (strcmp(ident,"SCOPE") != 0) thenbscop ++; // ?? a verifier
|
|
}
|
|
*/
|
|
if (type[0] != '(') thenbents ++; // total de termes propres du fichier
|
|
|
|
//thetypes.ChangeValue(num).SetValue(1,type); gka memory
|
|
//============================================
|
|
Standard_Integer index = 0;
|
|
TCollection_AsciiString strtype(type);
|
|
if(thenametypes.Contains(type))
|
|
index = thenametypes.FindIndex(strtype);
|
|
else index = thenametypes.Add(strtype);
|
|
thetypes.ChangeValue(num) = index;
|
|
//===========================================
|
|
|
|
if (ident[0] == '$') {
|
|
if (strlen(ident) > 2) numlst = atoi(&ident[1]);
|
|
else numlst = ident[1] - 48;
|
|
if (thelastn < numlst) thelastn = numlst; // plus fort n0 de sous-liste
|
|
theidents.SetValue(num,-2-numlst);
|
|
} else if (ident[0] == '#') {
|
|
numlst = atoi(&ident[1]);
|
|
theidents.SetValue(num,numlst);
|
|
if (numlst == 0 && num > thenbhead) {
|
|
// Header, ou bien Type Complexe ...
|
|
// Si Type Complexe, retrouver Type Precedent (on considere que c est rare)
|
|
// On chaine le type precedent sur le suivant
|
|
// VERIFICATION que les types sont en ordre alphabetique
|
|
for (Standard_Integer prev = num-1; prev > thenbhead; prev --) {
|
|
if (theidents(prev) >= 0) {
|
|
|
|
//themults.SetValue(prev,num);
|
|
themults.Bind(prev,num);
|
|
if(thenametypes.FindKey(thetypes.Value(num)).IsLess(thenametypes.FindKey(thetypes.Value(prev)))) {
|
|
//if (thetypes.Value(num).IsLess(thetypes.Value(prev)))
|
|
|
|
// ERREUR : Type complexe pas en ordre alphabetique. On enregistre.
|
|
TCollection_AsciiString errm("Complex Type incorrect : ");
|
|
errm.AssignCat(thenametypes.FindKey(thetypes.Value(prev)));
|
|
errm.AssignCat(" / ");
|
|
errm.AssignCat(thenametypes.FindKey(thetypes.Value(num)));
|
|
errm.AssignCat(" ... ");
|
|
thecheck->AddFail(errm.ToCString(),"Complex Type incorrect : ");
|
|
// On Affiche a l ecran, le plus de donnees possibles
|
|
while (theidents(prev) <= 0) {
|
|
prev --; if (prev <= 0) break;
|
|
}
|
|
Handle(Message_Messenger) sout = Message::DefaultMessenger();
|
|
sout << " *** Error on Record " << num << " (on " << NbRecords()
|
|
<< " -> " << num*100/NbRecords() << " % in File) ***";
|
|
if (prev > 0) sout << " Ident #" << theidents(prev);
|
|
sout << "\n" << errm << endl;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (!strcmp(ident,"SCOPE")) {
|
|
theidents.SetValue(num,-1); // SCOPE
|
|
thenbscop ++;
|
|
}
|
|
else if (!strcmp(ident,"ENDSCOPE")) theidents.SetValue(num,-2); // ENDSCOPE
|
|
// Reste 0
|
|
|
|
// InitParams(num);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : AddStepParam
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepReaderData::AddStepParam (const Standard_Integer num,
|
|
const Standard_CString aval,
|
|
const Interface_ParamType atype,
|
|
const Standard_Integer nument)
|
|
{
|
|
if (atype == Interface_ParamSub) {
|
|
Standard_Integer numid = 0;
|
|
if (aval[2] != '\0') {
|
|
numid = atoi(&aval[1]);
|
|
// if (numid <= Maxlst) Interface_FileReaderData::AddParam
|
|
// (num,subl[numid-1].ToCString(),atype,numid);
|
|
Interface_FileReaderData::AddParam (num,aval,atype,numid);
|
|
} else {
|
|
char *numlstchar = (char *)(aval+1);
|
|
numid = (*numlstchar) - 48; // -48 ('0') -1 (adresse [] depuis 0)
|
|
// Interface_FileReaderData::AddParam (num,subl[numid].ToCString(),atype,numid);
|
|
Interface_FileReaderData::AddParam (num,aval,atype,numid);
|
|
}
|
|
} else if (atype == Interface_ParamIdent) {
|
|
Standard_Integer numid = atoi(&aval[1]);
|
|
Interface_FileReaderData::AddParam (num,aval,atype,numid);
|
|
} else {
|
|
Interface_FileReaderData::AddParam (num,aval,atype,nument);
|
|
}
|
|
|
|
// Interface_FileReaderData::AddParam (num,parval,atype,numid);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : RecordType
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TCollection_AsciiString& StepData_StepReaderData::RecordType
|
|
(const Standard_Integer num) const
|
|
{
|
|
return thenametypes.FindKey(thetypes.Value(num));
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CType
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_CString StepData_StepReaderData::CType(const Standard_Integer num) const
|
|
{
|
|
return thenametypes.FindKey(thetypes.Value(num)).ToCString();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : RecordIdent
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::RecordIdent (const Standard_Integer num) const
|
|
{
|
|
return theidents(num);
|
|
}
|
|
|
|
|
|
// ########################################################################
|
|
// .... Aides a la lecture des parametres, adaptees a STEP ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : SubListNumber
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::SubListNumber (const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_Boolean aslast) const
|
|
{
|
|
if (nump == 0 || nump > NbParams(num)) return 0;
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() != Interface_ParamSub) return 0;
|
|
if (aslast) { if(nump != NbParams(num)) return 0; }
|
|
return FP.EntityNumber();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsComplex
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::IsComplex(const Standard_Integer num) const
|
|
{
|
|
//return (themults(num) != 0);
|
|
return themults.IsBound(num);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ComplexType
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepReaderData::ComplexType(const Standard_Integer num,
|
|
TColStd_SequenceOfAsciiString& types) const
|
|
{
|
|
if (theidents(num) < 0) return;
|
|
for (Standard_Integer i = num; i > 0; i = NextForComplex(i)) {
|
|
types.Append(RecordType(i));
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextForComplex
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::NextForComplex
|
|
(const Standard_Integer num) const
|
|
{
|
|
Standard_Integer next =0;
|
|
if(themults.IsBound(num))
|
|
next = themults.Find(num);
|
|
return next;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : stepstrcmp
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Boolean stepstrcmp(const Standard_CString type,
|
|
const Standard_CString name)
|
|
{
|
|
// name peut etre d un tenant ou de deux : auquel cas il a une partie LONGUE
|
|
// et une partie COURTE separees par un blanc
|
|
// Attention : False pour dire OK, True sinon (car remplace strcmp)
|
|
Standard_Integer i,j = 0; Standard_Boolean res = Standard_False;
|
|
for (i = 0; name[i] != '\0' && type[i] != '\0' && !res ; i ++) {
|
|
if (name[i] == ' ' && type[i] == '\0') { j = i; break; }
|
|
if (type[i] != name[i]) res = Standard_True;
|
|
}
|
|
if (!res || (j == 0)) return res;
|
|
// Pas trouve et un blanc suit : on continue
|
|
for (i = j+1; name[i] != '\0'; i ++) {
|
|
if (type[i-j-1] != name[i]) return Standard_True;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NamedForComplex
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::NamedForComplex
|
|
(const Standard_CString name, const Standard_Integer num0,
|
|
Standard_Integer& num, Handle(Interface_Check)& ach) const
|
|
{
|
|
//Standard_Boolean stat = Standard_True;
|
|
Standard_Integer n = (num <= 0 ? num0 : NextForComplex(num));
|
|
// sln 04,10.2001. BUC61003. if(n==0) the next function is not called in order to avoid exception
|
|
if ((n!=0) && (!stepstrcmp (RecordType(n).ToCString(),name)))
|
|
{ num = n; return Standard_True; }
|
|
|
|
if (n == 0) /*stat =*/ NamedForComplex (name,num0,n,ach); // on a rembobine
|
|
// Pas dans l ordre alphabetique : boucler
|
|
Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
|
|
sprintf (txtmes,errmess->ToCString(),num0,name);
|
|
for (n = num0; n > 0; n = NextForComplex(n)) {
|
|
if (!stepstrcmp (RecordType(n).ToCString(),name)) {
|
|
num = n;
|
|
errmess = new String("Complex Record n0.%d, member type %s not in alphabetic order");
|
|
sprintf (txtmes,errmess->ToCString(),num0,name);
|
|
ach->AddWarning(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
}
|
|
num = 0;
|
|
errmess = new String("Complex Record n0.%d, member type %s not found");
|
|
sprintf (txtmes,errmess->ToCString(),num0,name);
|
|
ach->AddFail (txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
|
|
|
|
//=======================================================================
|
|
//function : CheckNbParams
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::CheckNbParams(const Standard_Integer num,
|
|
const Standard_Integer nbreq,
|
|
Handle(Interface_Check)& ach,
|
|
const Standard_CString mess) const
|
|
{
|
|
if (NbParams(num) == nbreq) return Standard_True;
|
|
Handle(String) errmess;
|
|
if (mess[0] == '\0') errmess = new String("Count of Parameters is not %d");
|
|
else errmess = new String("Count of Parameters is not %d for %s");
|
|
sprintf (txtmes,errmess->ToCString(),nbreq,mess);
|
|
ach->AddFail (txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadSubList
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadSubList(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Integer& numsub,
|
|
const Standard_Boolean optional,
|
|
const Standard_Integer /* lenmin */,
|
|
const Standard_Integer /* lenmax */) const
|
|
{
|
|
numsub = SubListNumber (num,nump,Standard_False);
|
|
if (numsub > 0) return Standard_True;
|
|
// Si optionel indefini, on passe l eponge
|
|
numsub = 0;
|
|
Standard_Boolean isvoid = (Param(num,nump).ParamType() == Interface_ParamVoid);
|
|
if (isvoid && optional) return Standard_False;
|
|
|
|
Handle(String) errmess = new String("Parameter n0.%d (%s) not a LIST");
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (acceptvoid && isvoid) ach->AddWarning(txtmes,errmess->ToCString());
|
|
else { ach->AddFail(txtmes,errmess->ToCString()); return Standard_False; }
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
// ... Facilites pour LateBinding
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadSub
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::ReadSub(const Standard_Integer numsub,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
const Handle(StepData_PDescr)& descr,
|
|
Handle(Standard_Transient)& val) const
|
|
{
|
|
Standard_Integer nbp = NbParams(numsub);
|
|
if (nbp == 0) return 0; // liste vide = Handle Null
|
|
const TCollection_AsciiString& rectyp = RecordType (numsub);
|
|
if (nbp == 1 && rectyp.ToCString()[0] != '(') {
|
|
// c est un type avec un parametre -> SelectNamed
|
|
// cf ReadSelect mais ici, on est deja sur le contenu du parametre
|
|
Handle(StepData_SelectNamed) sn = new StepData_SelectNamed;
|
|
val = sn;
|
|
sn->SetName (rectyp.ToCString());
|
|
if (ReadAny (numsub,1,mess,ach,descr,sn)) return sn->Kind();
|
|
else return 0;
|
|
}
|
|
|
|
// cas courant : faire un HArray1 de ... de ... de quoi au fait
|
|
const Interface_FileParameter& FP0 = Param(numsub,1);
|
|
Interface_ParamType FT, FT0 = FP0.ParamType();
|
|
Standard_CString str = FP0.CValue();
|
|
Handle(TColStd_HArray1OfTransient) htr;
|
|
Handle(TColStd_HArray1OfInteger) hin;
|
|
Handle(TColStd_HArray1OfReal) hre;
|
|
Handle(Interface_HArray1OfHAsciiString) hst;
|
|
Standard_Integer kod = 0;
|
|
switch (FT0) {
|
|
case Interface_ParamMisc : return -1;
|
|
case Interface_ParamInteger : kod = 1; break;
|
|
case Interface_ParamReal : kod = 5; break;
|
|
case Interface_ParamIdent : kod = 7; break;
|
|
case Interface_ParamVoid : kod = 0; break;
|
|
case Interface_ParamText : kod = 6; break;
|
|
case Interface_ParamEnum : kod = 4; break; // a confirmer(logical)
|
|
/* kod = 4;
|
|
if ( str[0] == '.' && str[2] == '.' && str[3] == '\0' &&
|
|
(str[1] == 'T' || str[1] == 'F' || str[1] == 'U') ) kod = 3;
|
|
break; */ // svv #2
|
|
case Interface_ParamLogical : return -1;
|
|
case Interface_ParamSub : kod = 0; break;
|
|
case Interface_ParamHexa : return -1;
|
|
case Interface_ParamBinary : return -1;
|
|
default : return -1;
|
|
}
|
|
if (kod == 1 || kod == 3) { hin = new TColStd_HArray1OfInteger (1,nbp); val = hin; }
|
|
else if (kod == 5) { hre = new TColStd_HArray1OfReal (1,nbp); val = hre; }
|
|
else if (kod == 6) { hst = new Interface_HArray1OfHAsciiString (1,nbp); val = hst; }
|
|
else { htr = new TColStd_HArray1OfTransient (1,nbp); val = htr; }
|
|
// Attention : si type variable, faudra changer son fusil d epaule -> htr
|
|
|
|
for (Standard_Integer ip = 1; ip <= nbp; ip ++) {
|
|
const Interface_FileParameter& FP = Param(numsub,ip);
|
|
str = FP.CValue();
|
|
FT = FP.ParamType();
|
|
switch (kod) {
|
|
case 1 : {
|
|
if (FT != Interface_ParamInteger) { kod = 0; break; }
|
|
hin->SetValue (ip,atoi(str)); break;
|
|
}
|
|
case 2 :
|
|
case 3 : {
|
|
if (FT != Interface_ParamEnum) { kod = 0; break; }
|
|
if (!strcmp(str,".F.")) hin->SetValue (ip,0);
|
|
else if (!strcmp(str,".T.")) hin->SetValue (ip,1);
|
|
else if (!strcmp(str,".U.")) hin->SetValue (ip,2);
|
|
else kod = 0;
|
|
break;
|
|
}
|
|
case 4 : {
|
|
if (FT != Interface_ParamEnum) { kod = 0; break; }
|
|
Handle(StepData_SelectNamed) sn = new StepData_SelectNamed;
|
|
sn->SetEnum (-1,str);
|
|
htr->SetValue (ip,sn); break;
|
|
}
|
|
case 5 : {
|
|
if (FT != Interface_ParamReal) { kod = 0; break; }
|
|
hre->SetValue (ip,Interface_FileReaderData::Fastof(str)); break;
|
|
}
|
|
case 6 : {
|
|
if (FT != Interface_ParamText) { kod = 0; break; }
|
|
Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
|
|
CleanText (txt); hst->SetValue (ip,txt); break;
|
|
}
|
|
case 7 : {
|
|
Handle(Standard_Transient) ent = BoundEntity (FP.EntityNumber());
|
|
htr->SetValue (ip,ent); break;
|
|
}
|
|
default : break;
|
|
}
|
|
// Restent les autres cas ... tout est possible. cf le type du Param
|
|
if (kod > 0) continue;
|
|
// Il faut passer au transient ...
|
|
if (htr.IsNull()) {
|
|
htr = new TColStd_HArray1OfTransient (1,nbp); val = htr;
|
|
Standard_Integer jp;
|
|
if (!hin.IsNull()) {
|
|
for (jp = 1; jp < ip; jp ++) {
|
|
Handle(StepData_SelectInt) sin = new StepData_SelectInt;
|
|
sin->SetInt (hin->Value(jp));
|
|
htr->SetValue (jp,sin);
|
|
}
|
|
}
|
|
if (!hre.IsNull()) {
|
|
for (jp = 1; jp < ip; jp ++) {
|
|
Handle(StepData_SelectReal) sre = new StepData_SelectReal;
|
|
sre->SetReal (hre->Value(jp));
|
|
htr->SetValue (jp,sre);
|
|
}
|
|
}
|
|
if (!hst.IsNull()) {
|
|
for (jp = 1; jp < ip; jp ++) {
|
|
htr->SetValue (jp,hst->Value(jp));
|
|
}
|
|
}
|
|
}
|
|
// A present, faut y aller : lire le champ et le mettre en place
|
|
// Ce qui suit ressemble fortement a ReadAny ...
|
|
|
|
switch (FT) {
|
|
case Interface_ParamMisc : break;
|
|
case Interface_ParamInteger : {
|
|
Handle(StepData_SelectInt) sin = new StepData_SelectInt;
|
|
sin->SetInteger (atoi(str));
|
|
htr->SetValue (ip,sin); break;
|
|
}
|
|
case Interface_ParamReal : {
|
|
Handle(StepData_SelectReal) sre = new StepData_SelectReal;
|
|
sre->SetReal (Interface_FileReaderData::Fastof(str)); break;
|
|
//htr->SetValue (ip,sre); break; svv #2: unreachable
|
|
}
|
|
case Interface_ParamIdent : htr->SetValue (ip,BoundEntity (FP.EntityNumber())); break;
|
|
case Interface_ParamVoid : break;
|
|
case Interface_ParamEnum : {
|
|
Handle(StepData_SelectInt) sin;
|
|
Handle(StepData_SelectNamed) sna;
|
|
Standard_Integer logic = -1;
|
|
// PTV 16.09.2000
|
|
// set the default value of StepData_Logical
|
|
StepData_Logical slog = StepData_LUnknown;
|
|
if ( str[0] == '.' && str[2] == '.' && str[3] == '\0') {
|
|
if (str[1] == 'F') { slog = StepData_LFalse; logic = 0; }
|
|
else if (str[1] == 'T') { slog = StepData_LTrue; logic = 1; }
|
|
else if (str[1] == 'U') { slog = StepData_LUnknown; logic = 2; }
|
|
}
|
|
if (logic >= 0)
|
|
{ sin = new StepData_SelectInt; sin->SetLogical(slog); htr->SetValue(ip,sin); }
|
|
else { sna = new StepData_SelectNamed;
|
|
sna->SetEnum (logic,str); htr->SetValue (ip,sna); }
|
|
break;
|
|
}
|
|
case Interface_ParamLogical : break;
|
|
case Interface_ParamText : {
|
|
Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
|
|
CleanText (txt); htr->SetValue (ip,txt); break;
|
|
}
|
|
case Interface_ParamSub : {
|
|
Handle(Standard_Transient) sub;
|
|
Standard_Integer nent = FP.EntityNumber();
|
|
Standard_Integer kind = ReadSub (nent,mess,ach,descr,sub); if (kind < 0) break;
|
|
htr->SetValue(ip,sub); break;
|
|
}
|
|
case Interface_ParamHexa : break;
|
|
case Interface_ParamBinary : break;
|
|
default : break;
|
|
}
|
|
return -1;
|
|
}
|
|
return 8; // pour Any
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadMember
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadMember(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Handle(StepData_SelectMember)& val) const
|
|
{
|
|
Handle(Standard_Transient) v = val;
|
|
Handle(StepData_PDescr) nuldescr;
|
|
if (v.IsNull()) return ReadAny (num,nump,mess,ach,nuldescr,val);
|
|
Standard_Boolean res = ReadAny (num,nump,mess,ach,nuldescr,v);
|
|
if (v == val) return res;
|
|
// changement -> refus
|
|
Handle(String) errmess =
|
|
new String("Parameter n0.%d (%s) : does not match SELECT clause");
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadField
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadField(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
const Handle(StepData_PDescr)& descr,
|
|
StepData_Field& fild) const
|
|
{
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
Standard_CString str = FP.CValue();
|
|
Standard_Boolean OK = Standard_True;
|
|
Standard_Integer nent, kind;
|
|
Handle(TCollection_HAsciiString) txt;
|
|
Handle(Standard_Transient) sub;
|
|
Interface_ParamType FT = FP.ParamType();
|
|
switch (FT) {
|
|
case Interface_ParamMisc : OK = Standard_False; break;
|
|
case Interface_ParamInteger : fild.SetInteger (atoi(str)); break;
|
|
case Interface_ParamReal :
|
|
fild.SetReal (Interface_FileReaderData::Fastof(str)); break;
|
|
case Interface_ParamIdent :
|
|
nent = FP.EntityNumber();
|
|
if (nent > 0) fild.SetEntity (BoundEntity(nent));
|
|
break;
|
|
case Interface_ParamVoid : break;
|
|
case Interface_ParamText :
|
|
txt = new TCollection_HAsciiString(str);
|
|
CleanText (txt); fild.Set (txt); break;
|
|
case Interface_ParamEnum :
|
|
if (!strcmp(str,".T.")) fild.SetLogical (StepData_LTrue);
|
|
else if (!strcmp(str,".F.")) fild.SetLogical (StepData_LFalse);
|
|
else if (!strcmp(str,".U.")) fild.SetLogical (StepData_LUnknown);
|
|
else fild.SetEnum (-1,str);
|
|
break;
|
|
case Interface_ParamLogical : OK = Standard_False; break;
|
|
case Interface_ParamSub :
|
|
nent = FP.EntityNumber();
|
|
kind = ReadSub (nent,mess,ach,descr,sub); if (kind < 0) break;
|
|
fild.Clear(kind); fild.Set (sub); break;
|
|
case Interface_ParamHexa : OK = Standard_False; break;
|
|
case Interface_ParamBinary : OK = Standard_False; break;
|
|
default : OK = Standard_False; break;
|
|
}
|
|
|
|
if (!OK) {
|
|
if (!strcmp(str,"*")) fild.SetDerived();
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadList
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadList(const Standard_Integer num,
|
|
Handle(Interface_Check)& ach,
|
|
const Handle(StepData_ESDescr)& descr,
|
|
StepData_FieldList& list) const
|
|
{
|
|
// controler nbs egaux
|
|
Standard_Integer i,nb = list.NbFields();
|
|
if (!CheckNbParams (num,nb,ach,descr->TypeName())) return Standard_False;
|
|
for (i = 1; i <= nb; i ++) {
|
|
Handle(StepData_PDescr) pde = descr->Field(i);
|
|
StepData_Field& fild = list.CField(i);
|
|
ReadField (num,i,pde->Name(),ach,pde,fild);
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadAny
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadAny(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
const Handle(StepData_PDescr)& descr,
|
|
Handle(Standard_Transient)& val) const
|
|
{
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
Standard_CString str = FP.CValue();
|
|
Interface_ParamType FT = FP.ParamType();
|
|
|
|
// A present, faut y aller : lire le champ et le mettre en place
|
|
switch (FT) {
|
|
case Interface_ParamMisc : break;
|
|
case Interface_ParamInteger : {
|
|
if (!val.IsNull()) {
|
|
DeclareAndCast(StepData_SelectMember,sm,val);
|
|
sm->SetInteger(atoi(str));
|
|
return Standard_True;
|
|
}
|
|
Handle(StepData_SelectInt) sin = new StepData_SelectInt;
|
|
sin->SetInteger (atoi(str));
|
|
val = sin;
|
|
return Standard_True;
|
|
}
|
|
case Interface_ParamReal : {
|
|
if (!val.IsNull()) {
|
|
DeclareAndCast(StepData_SelectMember,sm,val);
|
|
sm->SetReal (Interface_FileReaderData::Fastof(str));
|
|
return Standard_True;
|
|
}
|
|
Handle(StepData_SelectReal) sre = new StepData_SelectReal;
|
|
sre->SetReal (Interface_FileReaderData::Fastof(str));
|
|
val = sre;
|
|
return Standard_True;
|
|
}
|
|
case Interface_ParamIdent : {
|
|
Standard_Integer nent = FP.EntityNumber();
|
|
if (nent > 0) val = BoundEntity(nent);
|
|
return (!val.IsNull());
|
|
}
|
|
case Interface_ParamVoid : break;
|
|
case Interface_ParamEnum : {
|
|
Handle(StepData_SelectMember) sm;
|
|
if (!val.IsNull()) sm = GetCasted(StepData_SelectMember,val);
|
|
Handle(StepData_SelectInt) sin;
|
|
Handle(StepData_SelectNamed) sna;
|
|
Standard_Integer logic = -1;
|
|
|
|
// PTV 16.09.2000
|
|
// set the default value of StepData_Logical
|
|
StepData_Logical slog = StepData_LUnknown;
|
|
if ( str[0] == '.' && str[2] == '.' && str[3] == '\0') {
|
|
if (str[1] == 'F') { slog = StepData_LFalse; logic = 0; }
|
|
else if (str[1] == 'T') { slog = StepData_LTrue; logic = 1; }
|
|
else if (str[1] == 'U') { slog = StepData_LUnknown; logic = 2; }
|
|
}
|
|
if (logic >= 0) {
|
|
if (!sm.IsNull()) sm->SetLogical(slog);
|
|
else {
|
|
sin = new StepData_SelectInt; val = sin;
|
|
sin->SetLogical(slog);
|
|
}
|
|
}
|
|
else {
|
|
if (!sm.IsNull()) sm->SetEnum (logic,str);
|
|
else {
|
|
sna = new StepData_SelectNamed; val = sna; // Named sans nom...
|
|
sna->SetEnum (logic,str);
|
|
}
|
|
} // -> Select general
|
|
return Standard_True;
|
|
}
|
|
case Interface_ParamLogical : break;
|
|
case Interface_ParamText : {
|
|
Handle(TCollection_HAsciiString) txt = new TCollection_HAsciiString(str);
|
|
CleanText (txt);
|
|
|
|
// PDN May 2000: for reading SOURCE_ITEM (external references)
|
|
if (!val.IsNull()) {
|
|
DeclareAndCast(StepData_SelectMember,sm,val);
|
|
sm->SetString (txt->ToCString());
|
|
return Standard_True;
|
|
}
|
|
|
|
val = txt;
|
|
return Standard_True;
|
|
}
|
|
case Interface_ParamSub : {
|
|
Standard_Integer numsub = SubListNumber (num,nump,Standard_False);
|
|
Standard_Integer nbp = NbParams(numsub);
|
|
if (nbp == 0) return Standard_False; // liste vide = Handle Null
|
|
const TCollection_AsciiString& rectyp = RecordType (numsub);
|
|
if (nbp == 1 && rectyp.ToCString()[0] != '(') {
|
|
// SelectNamed because Field !!!
|
|
// skl 15.01.2003 (for members with array of real)
|
|
DeclareAndCast(StepData_SelectArrReal,sma,val);
|
|
if(!sma.IsNull()) {
|
|
Standard_Integer numsub2 = SubListNumber (numsub,1,Standard_False);
|
|
Standard_Integer nbp2 = NbParams(numsub2);
|
|
if(nbp2>1) {
|
|
if( Param(numsub2,1).ParamType() == Interface_ParamReal ) {
|
|
if (!sma->SetName (rectyp.ToCString())) return Standard_False;
|
|
Handle(TColStd_HSequenceOfReal) aSeq = new TColStd_HSequenceOfReal;
|
|
for(Standard_Integer i=1; i<=nbp2; i++) {
|
|
if( Param(numsub2,i).ParamType() != Interface_ParamReal ) continue;
|
|
Handle(StepData_SelectReal) sm1 = new StepData_SelectReal;
|
|
if( !ReadAny(numsub2,i,mess,ach,descr,sm1) ) continue;
|
|
aSeq->Append(sm1->Real());
|
|
}
|
|
Handle(TColStd_HArray1OfReal) anArr = new TColStd_HArray1OfReal(1,aSeq->Length());
|
|
for(Standard_Integer nr=1; nr<=aSeq->Length(); nr++) {
|
|
anArr->SetValue(nr,aSeq->Value(nr));
|
|
}
|
|
sma->SetArrReal(anArr);
|
|
return Standard_True;
|
|
}
|
|
}
|
|
}
|
|
DeclareAndCast(StepData_SelectMember,sm,val);
|
|
if (sm.IsNull()) {
|
|
sm = new StepData_SelectNamed;
|
|
val = sm;
|
|
}
|
|
if (!sm->SetName (rectyp.ToCString())) return Standard_False; // loupe
|
|
return ReadAny (numsub,1,mess,ach,descr,val);
|
|
}
|
|
}
|
|
default : break;
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
// ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadXY
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadXY(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Real& X, Standard_Real& Y) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Integer numsub = SubListNumber(num,nump,Standard_False);
|
|
if (numsub != 0) {
|
|
if (NbParams(numsub) == 2) {
|
|
const Interface_FileParameter& FPX = Param(numsub,1);
|
|
if (FPX.ParamType() == Interface_ParamReal) X =
|
|
Interface_FileReaderData::Fastof(FPX.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y) X not a Real");
|
|
|
|
const Interface_FileParameter& FPY = Param(numsub,2);
|
|
if (FPY.ParamType() == Interface_ParamReal) Y =
|
|
Interface_FileReaderData::Fastof( FPY.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y) Y not a Real");
|
|
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y) has not 2 params");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y) not a SubList");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadXYZ
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadXYZ(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Real& X, Standard_Real& Y,
|
|
Standard_Real& Z) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Integer numsub = SubListNumber(num,nump,Standard_False);
|
|
if (numsub != 0) {
|
|
if (NbParams(numsub) == 3) {
|
|
const Interface_FileParameter& FPX = Param(numsub,1);
|
|
if (FPX.ParamType() == Interface_ParamReal) X =
|
|
Interface_FileReaderData::Fastof(FPX.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) X not a Real");
|
|
|
|
const Interface_FileParameter& FPY = Param(numsub,2);
|
|
if (FPY.ParamType() == Interface_ParamReal) Y =
|
|
Interface_FileReaderData::Fastof(FPY.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) Y not a Real");
|
|
|
|
const Interface_FileParameter& FPZ = Param(numsub,3);
|
|
if (FPZ.ParamType() == Interface_ParamReal) Z =
|
|
Interface_FileReaderData::Fastof(FPZ.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) Z not a Real");
|
|
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) has not 3 params");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) : (X,Y,Z) not a SubList");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadReal
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadReal(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Real& val) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamReal) val =
|
|
Interface_FileReaderData::Fastof(FP.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) not a Real");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadEntity
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
const Handle(Standard_Type)& atype,
|
|
Handle(Standard_Transient)& ent) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Boolean warn = Standard_False;
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
Standard_Integer nent = FP.EntityNumber();
|
|
if (FP.ParamType() == Interface_ParamIdent) {
|
|
warn = (acceptvoid > 0);
|
|
if (nent > 0) {
|
|
Handle(Standard_Transient) entent = BoundEntity(nent);
|
|
if (entent.IsNull() || !entent->IsKind(atype))
|
|
errmess = new String("Parameter n0.%d (%s) : Entity has illegal type");
|
|
else ent = entent;
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) : Unresolved reference");
|
|
}
|
|
else {
|
|
if (acceptvoid && FP.ParamType() == Interface_ParamVoid) warn = Standard_True;
|
|
errmess = new String("Parameter n0.%d (%s) not an Entity");
|
|
}
|
|
}
|
|
else {
|
|
warn = (acceptvoid > 0);
|
|
errmess = new String("Parameter n0.%d (%s) absent");
|
|
}
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (warn) ach->AddWarning(txtmes,errmess->ToCString());
|
|
else ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadEntity
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
StepData_SelectType& sel) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Boolean warn = Standard_False;
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
Standard_Integer nent = FP.EntityNumber();
|
|
if (FP.ParamType() == Interface_ParamIdent) {
|
|
warn = (acceptvoid > 0);
|
|
if (nent > 0) {
|
|
Handle(Standard_Transient) entent = BoundEntity(nent);
|
|
if (!sel.Matches(entent))
|
|
errmess = new String("Parameter n0.%d (%s) : Entity has illegal type");
|
|
else
|
|
sel.SetValue(entent);
|
|
}
|
|
else
|
|
errmess = new String("Parameter n0.%d (%s) : Unresolved reference");
|
|
}
|
|
else if (FP.ParamType() == Interface_ParamVoid) {
|
|
if (acceptvoid) warn = Standard_True;
|
|
errmess = new String("Parameter n0.%d (%s) not an Entity");
|
|
}
|
|
else {
|
|
// Cas restant : on s interesse en fait au SelectMember ...
|
|
Handle(Standard_Transient) sm = sel.NewMember();
|
|
// SelectMember qui assure ce role. Peut etre specialise
|
|
if (!ReadAny (num,nump,mess,ach,sel.Description(),sm))
|
|
errmess = new String("Parameter n0.%d (%s) : could not be read");
|
|
if (!sel.Matches(sm))
|
|
errmess = new String("Parameter n0.%d (%s) : illegal parameter type");
|
|
else
|
|
sel.SetValue(sm);
|
|
}
|
|
}
|
|
else {
|
|
warn = (acceptvoid > 0);
|
|
errmess = new String("Parameter n0.%d (%s) absent");
|
|
}
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (warn) ach->AddWarning(txtmes,errmess->ToCString());
|
|
else ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadInteger
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadInteger(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Integer& val) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamInteger) val = atoi(FP.CValue());
|
|
else errmess = new String("Parameter n0.%d (%s) not an Integer");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadBoolean
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadBoolean(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Boolean& flag) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamEnum) {
|
|
Standard_CString txt = FP.CValue();
|
|
if (!strcmp(txt,".T.")) flag = Standard_True;
|
|
else if (!strcmp(txt,".F.")) flag = Standard_False;
|
|
else errmess = new String("Parameter n0.%d (%s) : Incorrect Boolean Value");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) not a Boolean");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadLogical
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadLogical(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
StepData_Logical& flag) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamEnum) {
|
|
Standard_CString txt = FP.CValue();
|
|
if (!strcmp(txt,".T.")) flag = StepData_LTrue;
|
|
else if (!strcmp(txt,".F.")) flag = StepData_LFalse;
|
|
else if (!strcmp(txt,".U.")) flag = StepData_LUnknown;
|
|
else errmess = new String("Parameter n0.%d (%s) : Incorrect Logical Value");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) not a Logical");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadString
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadString(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Handle(TCollection_HAsciiString)& val) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Boolean warn = Standard_False;
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamText) {
|
|
/*Standard_CString anStr = FP.CValue();
|
|
if(strlen(anStr) < 3)
|
|
val = new TCollection_HAsciiString("");
|
|
else {
|
|
val = new TCollection_HAsciiString(FP.CValue());
|
|
CleanText (val);
|
|
}*/
|
|
val = new TCollection_HAsciiString(FP.CValue());
|
|
CleanText (val);
|
|
} else {
|
|
if (acceptvoid && FP.ParamType() == Interface_ParamVoid) warn = Standard_True;
|
|
errmess = new String("Parameter n0.%d (%s) not a quoted String");
|
|
}
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (warn) ach->AddWarning(txtmes,errmess->ToCString());
|
|
else ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadEnumParam
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadEnumParam(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_CString& text) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Boolean warn = Standard_False;
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamEnum) {
|
|
text = FP.CValue();
|
|
warn = (acceptvoid > 0);
|
|
} else if (FP.ParamType() == Interface_ParamVoid) {
|
|
errmess =
|
|
new String("Parameter n0.%d (%s) : Undefined Enumeration not allowed");
|
|
warn = (acceptvoid > 0);
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) not an Enumeration");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (warn) ach->AddWarning(txtmes,errmess->ToCString());
|
|
else ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FailEnumValue
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepReaderData::FailEnumValue(const Standard_Integer /* num */,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach) const
|
|
{
|
|
Handle(String) errmess =
|
|
new String("Parameter n0.%d (%s) : Incorrect Enumeration Value");
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadEnum
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadEnum(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
const StepData_EnumTool& enumtool,
|
|
Standard_Integer& val) const
|
|
{
|
|
// reprendre avec ReadEnumParam ?
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Boolean warn = Standard_False;
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() == Interface_ParamEnum) {
|
|
val = enumtool.Value (FP.CValue());
|
|
if (val >= 0) return Standard_True;
|
|
else errmess = new String("Parameter n0.%d (%s) : Incorrect Enumeration Value");
|
|
warn = (acceptvoid > 0);
|
|
}
|
|
else if (FP.ParamType() == Interface_ParamVoid) {
|
|
val = enumtool.NullValue();
|
|
if (val < 0) errmess =
|
|
new String("Parameter n0.%d (%s) : Undefined Enumeration not allowed");
|
|
warn = (acceptvoid > 0);
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) not an Enumeration");
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (warn)
|
|
ach->AddWarning(txtmes,errmess->ToCString());
|
|
else
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReadTypedParam
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::ReadTypedParam(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_Boolean mustbetyped,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
Standard_Integer& numr,
|
|
Standard_Integer& numrp,
|
|
TCollection_AsciiString& typ) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
const Interface_FileParameter& FP = Param(num,nump);
|
|
if (FP.ParamType() != Interface_ParamSub) {
|
|
// Pas une sous-liste : OK si admis
|
|
numr = num; numrp = nump; typ.Clear();
|
|
if (mustbetyped) {
|
|
errmess = new String("Parameter n0.%d (%s) : single, not typed");
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
numr = FP.EntityNumber(); numrp = 1;
|
|
if (NbParams(numr) != 1) errmess =
|
|
new String("Parameter n0.%d (%s) : SubList, not typed");
|
|
typ = RecordType(numr);
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
ach->AddFail(txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CheckDerived
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean StepData_StepReaderData::CheckDerived(const Standard_Integer num,
|
|
const Standard_Integer nump,
|
|
const Standard_CString mess,
|
|
Handle(Interface_Check)& ach,
|
|
const Standard_Boolean errstat) const
|
|
{
|
|
Handle(String) errmess; // Null si pas d erreur
|
|
Standard_Boolean warn = !errstat;
|
|
if (nump > 0 && nump <= NbParams(num)) {
|
|
if (!strcmp(Param(num,nump).CValue(),"*")) return Standard_True;
|
|
else errmess = new String("Parameter n0.%d (%s) not Derived");
|
|
if (acceptvoid) warn = Standard_True;
|
|
}
|
|
else errmess = new String("Parameter n0.%d (%s) absent");
|
|
|
|
if (errmess.IsNull()) return Standard_True;
|
|
sprintf (txtmes,errmess->ToCString(),nump,mess);
|
|
if (warn) ach->AddWarning (txtmes,errmess->ToCString());
|
|
else ach->AddFail (txtmes,errmess->ToCString());
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
// #########################################################################
|
|
// .... Methodes specifiques (demandees par FileReaderData) .... //
|
|
|
|
|
|
//=======================================================================
|
|
//function : NbEntities
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::NbEntities () const // redefined
|
|
{
|
|
return thenbents;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindNextRecord
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::FindNextRecord
|
|
(const Standard_Integer num) const
|
|
{
|
|
// retourne, sur un numero d enregistrement donne (par num), le suivant qui
|
|
// definit une entite, ou 0 si c est fini :
|
|
// passe le Header (nbhend premiers records) et
|
|
// saute les enregistrements SCOPE et ENDSCOPE et les SOUS-LISTES
|
|
|
|
if (num < 0) return 0 ;
|
|
Standard_Integer num1 = num + 1 ; if (num == 0) num1 = thenbhead + 1;
|
|
Standard_Integer max = NbRecords() ;
|
|
|
|
while (num1 <= max ) {
|
|
if (theidents(num1) > 0) return num1;
|
|
|
|
// SCOPE,ENDSCOPE et Sous-Liste ont un identifieur fictif: -1,-2 respectivement
|
|
// et SUBLIST ont un negatif. Seule une vraie entite a un Ident positif
|
|
num1 ++ ;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindEntityNumber
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::FindEntityNumber(const Standard_Integer num,
|
|
const Standard_Integer id) const
|
|
{
|
|
// Soit un "Id" : recherche dans les Parametres de type Ident de <num>,
|
|
// si un d eux designe #Id justement. Si oui, retourne son EntityNumber
|
|
if (num == 0) return 0;
|
|
Standard_Integer nb = NbParams(num);
|
|
for (Standard_Integer i = 1; i <= nb; i ++) {
|
|
const Interface_FileParameter& FP = Param(num,i);
|
|
if (FP.ParamType() != Interface_ParamIdent) continue;
|
|
Standard_Integer ixp = atoi( &FP.CValue()[1] );
|
|
if (ixp == id) return FP.EntityNumber();
|
|
}
|
|
return 0; // ici, pas trouve
|
|
}
|
|
|
|
|
|
// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
// .... La fonction qui suit merite une attention speciale ....
|
|
|
|
|
|
// Cette methode precharge les EntityNumbers dans les Params : ils designent
|
|
// les Entites proprement dites dans la liste lue par BoundEntity
|
|
// Interet : adresse de meme les sous-listes (Num->no record dans le Direc)
|
|
// resultat exploite par ParamEntity et ParamNumber
|
|
|
|
// En l absence de SCOPE, ou si les "ident" sont strictement ordonnes, a coup
|
|
// sur ils ne sont pas dupliques, on peut utiliser une IndexedMap en toute
|
|
// confiance. Sinon, il faut balayer dans le fichier, mais avec les SCOPES
|
|
// cela va beaucoup plus vite (s ils sont assez gros) : on s y retrouve.
|
|
|
|
// Pour la recherche par balayage, On opere en plusieurs etapes
|
|
// Avant toute chose, le chargement a deja fait une preparation : les idents
|
|
// (Entity, SubList) sont deja en entiers (rapidite de lecture), en particulier
|
|
// dans les EntityNumber : ainsi, on lit cet ident, on le traite, et on remet
|
|
// a la place un vrai numero de Record
|
|
//
|
|
// D abord, on passe le directory en table d entiers, sous-listes expurgees
|
|
// en // , table inverse vers cette table, car les sous-listes peuvent par
|
|
// contre designer des objets ...
|
|
|
|
// Pour les sous-listes, on exploite leur mode de construction : elles sont
|
|
// enregistrees AVANT d etre referencees. Un tableau "subn" note donc pour
|
|
// chaque numero de sous-liste (relatif a une entite qui suit, et reference
|
|
// par elle ou une autre sous-liste qui suit egalement), son n0 de record
|
|
// REMARQUE : ceci marche aussi pour le Header, traite par l occasion
|
|
|
|
|
|
//=======================================================================
|
|
//function : SetEntityNumbers
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepReaderData::SetEntityNumbers(const Standard_Boolean withmap)
|
|
{
|
|
Handle(Message_Messenger) sout = Message::DefaultMessenger();
|
|
// Passe initiale : Resolution directe par Map
|
|
// si tout passe (pas de collision), OK. Sinon, autres passes a prevoir
|
|
// On resoud du meme coup les sous-listes
|
|
Standard_Integer nbdirec = NbRecords() ;
|
|
TColStd_Array1OfInteger subn(0, thelastn);
|
|
|
|
Standard_Boolean pbmap = Standard_False; // au moins un conflit
|
|
Standard_Integer nbmap = 0;
|
|
TColStd_IndexedMapOfInteger imap(thenbents);
|
|
TColStd_Array1OfInteger indm(0, nbdirec); // Index Map -> Record Number (seulement si map)
|
|
|
|
Standard_Integer num; // svv Jan11 2000 : porting on DEC
|
|
for (num = 1 ; num <= nbdirec ; num ++) {
|
|
Standard_Integer ident = theidents(num);
|
|
if (ident > 0) { // Ident normal -> Map ?
|
|
// Map : si Recouvrement, l inhiber. Sinon, noter index
|
|
Standard_Integer indmap = imap.Add(ident);
|
|
if (indmap <= nbmap) {
|
|
indmap = imap.FindIndex(ident); // plus sur
|
|
indm(indmap) = -1; // Map -> pb
|
|
pbmap = Standard_True;
|
|
// pbmap signifie qu une autre passe sera necessaire ...
|
|
} else {
|
|
nbmap = indmap;
|
|
indm(indmap) = num; // Map ->ident
|
|
}
|
|
}
|
|
}
|
|
|
|
for (num = 1 ; num <= nbdirec ; num ++) {
|
|
Standard_Integer ident = theidents(num);
|
|
if (ident < -2) subn(-(ident+2)) = num; // toujours a jour ...
|
|
|
|
Standard_Integer nba = NbParams(num) ;
|
|
Standard_Integer nda = (num == 1 ? 0 : ParamFirstRank(num-1));
|
|
|
|
for (Standard_Integer na = nba ; na > 0 ; na --) {
|
|
// On traite : les sous-listes (sf subn), les idents (si Map dit OK ...)
|
|
Interface_FileParameter& FP = ChangeParameter (nda+na);
|
|
// Interface_FileParameter& FP = ChangeParam (num,na);
|
|
Interface_ParamType letype = FP.ParamType();
|
|
if (letype == Interface_ParamSub) {
|
|
Standard_Integer numsub = FP.EntityNumber();
|
|
if (numsub > thelastn) {
|
|
sout<<"Bad Sub.N0, Record "<<num<<" Param "<<na<<":$"<<numsub<<endl;
|
|
continue;
|
|
}
|
|
FP.SetEntityNumber(subn(numsub));
|
|
} else if (letype == Interface_ParamIdent) {
|
|
Standard_Integer id = FP.EntityNumber();
|
|
Standard_Integer indmap = imap.FindIndex(id);
|
|
if (indmap > 0) { // la map a trouve
|
|
Standard_Integer num0 = indm(indmap);
|
|
if (num0 > 0) FP.SetEntityNumber(num0); // ET VOILA, on a resolu
|
|
else FP.SetEntityNumber(-id); // CONFLIT -> faudra resoudre ...
|
|
} else { // NON RESOLU, si pas pbmap, le dire
|
|
FP.SetEntityNumber(-id);
|
|
if (pbmap) continue; // pbmap : on se retrouvera
|
|
char failmess[100];
|
|
// ... Construire le Check ...
|
|
sprintf(failmess,
|
|
"Unresolved Reference, Ent.Id.#%d Param.n0 %d (Id.#%d)",
|
|
ident,na,id);
|
|
thecheck->AddFail(failmess,"Unresolved Reference");
|
|
// ... Et sortir message un peu plus complet
|
|
sout << "*** ERR StepReaderData *** Pour Entite #"<< ident
|
|
<< "\n Type:" << RecordType(num)
|
|
<< " Param.n0 " << na << ": #" << id << " Non trouve" << endl ;
|
|
} // FIN Mapping
|
|
} // FIN Traitement Reference
|
|
} // FIN Boucle Parametres
|
|
} // FIN Boucle Repertoires
|
|
|
|
if (!pbmap) {
|
|
return;
|
|
}
|
|
sout << " -- 2nd pass required --";
|
|
|
|
Standard_Integer nbseq = thenbents+2*thenbscop;
|
|
TColStd_Array1OfInteger inds(0, nbseq); // n0 Record/Entite
|
|
TColStd_Array1OfInteger indi(0, nbseq); // Idents/scopes
|
|
TColStd_Array1OfInteger indr(0, nbdirec); // inverse de nds
|
|
Handle(TColStd_HArray1OfInteger) indx; // pour EXPORT (silya)
|
|
|
|
imap.Clear();
|
|
Standard_Boolean iamap = withmap; // (par defaut True)
|
|
nbmap = 0;
|
|
|
|
TColStd_SequenceOfInteger scopile; // chainage des scopes note par pile
|
|
Standard_Integer nr = 0 ;
|
|
for (num = 1 ; num <= nbdirec ; num ++) {
|
|
Standard_Integer ident = theidents(num);
|
|
if (ident < -2) { // SOUS-LISTE (cas le plus courant)
|
|
indr(num) = nr + 1; // recherche basee sur nr (objet qui suit)
|
|
} else if (ident >= 0) { // Ident normal
|
|
nr ++; inds(nr) = num; indi(nr) = ident; indr(num) = nr;
|
|
if (ident > 0) { // et non (iamap && ident > 0)
|
|
// Map : si Recouvrement, l inhiber. Sinon, noter index
|
|
Standard_Integer indmap = imap.Add(ident);
|
|
if (indmap <= nbmap) {
|
|
Standard_Boolean errorscope = Standard_False;
|
|
indmap = imap.FindIndex(ident); // plus sur
|
|
pbmap = Standard_True;
|
|
if (thenbscop == 0) errorscope = Standard_True;
|
|
// Numeros identiques alors quilnya pas de SCOPE ? ERREUR !
|
|
// (Bien sur, silya des SCOPES, on passe au travers, mais bon...)
|
|
else {
|
|
// Silya des SCOPES, tachons d y voir de plus pres pour signaler un probleme
|
|
// Erreur si MEME groupe SCOPE
|
|
// ATTENTION, on recherche, non dans tous les records, mais dans les records
|
|
// CHAINES, cf nr et non num (pas de sous-liste, chainage scope-endscope)
|
|
Standard_Integer fromscope = nr;
|
|
Standard_Integer toscope = indm(indmap);
|
|
if (toscope < 0) toscope = -toscope;
|
|
for(;;) {
|
|
fromscope --; // iteration de base
|
|
if (fromscope <= toscope) {
|
|
errorscope = Standard_True; // BANG, on est dessus
|
|
break;
|
|
}
|
|
Standard_Integer idtest = indi(fromscope);
|
|
if (idtest >= 0) continue; // le suivant (enfin, le precedent)
|
|
if (idtest == -1) break; // pas meme niveau, donc c est OK
|
|
if (idtest == -3) {
|
|
fromscope = inds(fromscope);
|
|
if (fromscope < toscope) break; // on sort, pas en meme niveau
|
|
}
|
|
}
|
|
}
|
|
if (errorscope) {
|
|
// On est dedans : le signaler
|
|
char ligne[80];
|
|
sprintf(ligne,"Ident defined SEVERAL TIMES : #%d",ident);
|
|
thecheck->AddFail(ligne,"Ident defined SEVERAL TIMES : #%d");
|
|
sout << "StepReaderData:SetEntityNumbers, " << ligne << endl;
|
|
}
|
|
if (indm(indmap) > 0) indm(indmap) = -indm(indmap); // Pas pour Map
|
|
// Cas Normal pour la Map
|
|
} else {
|
|
nbmap = indmap;
|
|
indm(indmap) = nr; // Map ->(indm)->inds
|
|
}
|
|
}
|
|
} else if (ident == -1) { // SCOPE
|
|
nr ++; inds(nr) = num; indi(nr) = -1; indr(num) = 0;
|
|
scopile.Append(nr) ;
|
|
} else if (ident == -2) { // ENDSCOPE
|
|
Standard_Integer nscop = scopile.Last() ; // chainage SCOPE-ENDSCOPE
|
|
scopile.Remove(scopile.Length()) ;
|
|
nr ++; inds(nr) = nscop; indi(nr) = -3; indr(num) = 0; inds(nscop) = nr;
|
|
if (NbParams(num) > 0) {
|
|
// EXPORT : traitement special greffe sur celui de SCOPE (sans le perturber)
|
|
if (indx.IsNull()) {
|
|
indx = new TColStd_HArray1OfInteger(0, nbseq);
|
|
for (Standard_Integer ixp = 0; ixp <= nbseq; ixp ++) indx->ChangeValue(ixp) = 0;
|
|
}
|
|
indx->ChangeValue(nr) = num; indx->ChangeValue(nscop) = num;
|
|
}
|
|
} else if (ident == 0) { // HEADER
|
|
indr(num) = 0;
|
|
}
|
|
}
|
|
|
|
// .. Resolution des EXPORT, silyena et silya besoin ..
|
|
// Pour chaque valeur de EXPORT qui n a pas ete resolue par la MAP,
|
|
// determiner sa position locale par recherche en arriere depuis ENDSCOPE
|
|
if ((!iamap || pbmap) && !indx.IsNull()) {
|
|
for (nr = 0; nr <= nbseq; nr ++) {
|
|
if (indx->Value(nr) == 0 && indi(nr) != -3) continue; // ENDSCOPE + EXPORT
|
|
num = indx->Value(nr);
|
|
Standard_Integer nba = NbParams(num);
|
|
for (Standard_Integer na = 1; na <= nba; na ++) {
|
|
Interface_FileParameter& FP = ChangeParam (num,na);
|
|
if (FP.ParamType() != Interface_ParamIdent) continue;
|
|
Standard_Integer id = - FP.EntityNumber();
|
|
if (id < 0) continue; // deja resolu en tete
|
|
/* if (imap.Contains(id)) { et voila
|
|
FP.SetEntityNumber(indm(imap.FindIndex(id)));
|
|
continue;
|
|
} */
|
|
|
|
// Recherche du Id demande : si EXPORT imbrique, deja resolu mais il faut
|
|
// regarder ! (inutile par contre d aller y voir : c est deja fait, car
|
|
// un EXPORT imbrique a ete traite AVANT celui qui imbrique)
|
|
Standard_Integer n0 = nr-1 ;
|
|
if (indi(n0) == -3) n0 --; // si on suit juste un ENDSCOPE
|
|
while (n0 > 0) {
|
|
Standard_Integer irec = indi(n0);
|
|
if (irec == id) { // trouve
|
|
FP.SetEntityNumber(inds(n0));
|
|
break ;
|
|
}
|
|
if (irec == -1) break; // SCOPE : fin de ce SCOPE/ENDSCOPE
|
|
if (irec == -3) {
|
|
// gare a EXPORT : si un EXPORT detient Id, noter son Numero deja calcule
|
|
// Attention : Id a lire depuis CValue car EntityNumber deja resolu
|
|
Standard_Integer nok = FindEntityNumber (indx->Value(n0),id);
|
|
if (nok > 0) {
|
|
FP.SetEntityNumber(nok);
|
|
break;
|
|
}
|
|
n0 = inds(n0); // ENDSCOPE ou EXPORT infructueux : le sauter
|
|
} // fin traitement sur un ENDSCOPE ou EXPORT
|
|
n0 -- ;
|
|
} // fin resolution d un Parametre EXPORT
|
|
} // fin resolution de la liste d un EXPORT
|
|
} // fin bouclage sur les EXPORT
|
|
}
|
|
|
|
// Exploitation de la table : bouclage porte sur la table
|
|
|
|
// Traitement des sous-listes : se fait dans la foulee, par gestion d une pile
|
|
// basee sur la constitution des sous-listes
|
|
Standard_Integer maxsubpil = 30; // pile simulee avec un Array : tres fort
|
|
Handle(TColStd_HArray1OfInteger) subpile = // ... gagne de la memoire ...
|
|
new TColStd_HArray1OfInteger (1,maxsubpil);
|
|
Standard_Integer nbsubpil = 0; // ... et tellement plus rapide !
|
|
|
|
for (num = 1 ; num <= nbdirec ; num ++) {
|
|
nr = indr(num);
|
|
if (nr == 0) continue; // pas un objet ou une sous-liste
|
|
Standard_Integer nba = NbParams(num) ;
|
|
for (Standard_Integer na = nba ; na > 0 ; na --) {
|
|
// On lit depuis la fin : cela permet de traiter les sous-listes dans la foulee
|
|
// Sinon, on devrait noter qu il y a eu des sous-listes et reprendre ensuite
|
|
|
|
Interface_FileParameter& FP = ChangeParam (num,na);
|
|
Interface_ParamType letype = FP.ParamType();
|
|
if (letype == Interface_ParamSub) {
|
|
// parametre type sous-liste : numero de la sous-liste lu par depilement
|
|
FP.SetEntityNumber(subpile->Value(nbsubpil));
|
|
nbsubpil --; // subpile->Remove(nbsubpil);
|
|
|
|
} else if (letype == Interface_ParamIdent) {
|
|
// parametre type ident (reference une entite) : chercher ident demande
|
|
Standard_Integer id = - FP.EntityNumber();
|
|
if (id < 0) continue; // deja resolu en tete
|
|
|
|
// Voila : on va chercher id dans ndi; algorithme de balayage
|
|
Standard_Integer pass, sens, nok, n0,irec; pass = sens = nok = 0;
|
|
if (!iamap) pass = 1; // si map non disponible
|
|
while (pass < 3) {
|
|
pass ++ ;
|
|
// MAP disponible
|
|
if (pass == 1) { // MAP DISPONIBLE
|
|
Standard_Integer indmap = imap.FindIndex(id);
|
|
if (indmap > 0) { // la map a trouve
|
|
nok = indm(indmap);
|
|
if (nok < 0) continue; // CONFLIT -> faut resoudre ...
|
|
break;
|
|
}
|
|
else continue;
|
|
}
|
|
// 1re Passe : REMONTEE -> Debut fichier
|
|
if (sens == 0 && nr > 1) {
|
|
n0 = nr-1 ;
|
|
if (indi(n0) == -3) n0 --; // si on suit juste un ENDSCOPE
|
|
while (n0 > 0) {
|
|
irec = indi(n0);
|
|
if (irec == id) { // trouve
|
|
nok = n0 ; break ;
|
|
}
|
|
// ENDSCOPE : Attention a EXPORT sinon sauter
|
|
if (irec == -3) {
|
|
if (indx.IsNull()) n0 = inds(n0);
|
|
else {
|
|
// EXPORT, il faut regarder
|
|
nok = FindEntityNumber (indx->Value(n0),id);
|
|
if (nok > 0) break;
|
|
n0 = inds(n0); // ENDSCOPE : le sauter
|
|
}
|
|
}
|
|
n0 -- ;
|
|
}
|
|
// 2me Passe : DESCENTE -> Fin fichier
|
|
} else if (nr < nbseq) { // descente -> fin fichier
|
|
n0 = nr+1 ;
|
|
while (n0 <= nbseq) {
|
|
irec = indi(n0);
|
|
if (irec == id) { // trouve
|
|
nok = n0 ; break ;
|
|
}
|
|
// SCOPE : Attention a EXPORT sinon sauter
|
|
if (irec == -1) {
|
|
if (indx.IsNull()) n0 = inds(n0);
|
|
else {
|
|
// EXPORT, il faut regarder
|
|
nok = FindEntityNumber (indx->Value(n0),id);
|
|
if (nok > 0) break;
|
|
n0 = inds(n0); // SCOPE : le sauter
|
|
}
|
|
}
|
|
n0 ++ ;
|
|
}
|
|
}
|
|
if (nok > 0) break ;
|
|
sens = 1 - sens ; // passe suivante
|
|
}
|
|
// ici on a nok, numero trouve
|
|
if (nok > 0) {
|
|
Standard_Integer num0 = inds(nok);
|
|
FP.SetEntityNumber(num0); // ET VOILA, on a resolu
|
|
|
|
// pas trouve : le signaler
|
|
} else {
|
|
// Alimenter le Check ... Pour cela, determiner n0 Entite et Ident
|
|
char failmess[100];
|
|
Standard_Integer nument = 0;
|
|
Standard_Integer n0ent; // svv Jan11 2000 : porting on DEC
|
|
for (n0ent = 1; n0ent <= nr; n0ent ++) {
|
|
if (indi(n0ent) > 0) nument ++;
|
|
}
|
|
Standard_Integer ident = RecordIdent(num);
|
|
if (ident < 0) {
|
|
for (n0ent = num + 1; n0ent <= nbdirec; n0ent ++) {
|
|
ident = RecordIdent(n0ent); if (ident > 0) break;
|
|
}
|
|
}
|
|
// ... Construire le Check ...
|
|
sprintf(failmess,
|
|
"Unresolved Reference, Ent.n0 %d (Id.#%d) Param.n0 %d (Id.#%d)",
|
|
nument,ident,na,id);
|
|
thecheck->AddFail(failmess,"Unresolved Reference");
|
|
// ... Et sortir message un peu plus complet
|
|
sout << "*** ERR StepReaderData *** Pour Entite "<<nument
|
|
<<", a "<< (nr*100)/nbseq<<"% de DATA : #"<< ident
|
|
<< "\n Type:" << RecordType(num)
|
|
<< " Param.n0 " << na << ": #" << id << " Non trouve" << endl ;
|
|
FP.SetEntityNumber(0); // -> Reference non resolue
|
|
}
|
|
}
|
|
}
|
|
// Si ce record est lui-meme une sous-liste, empiler !
|
|
if (inds(nr) != num) {
|
|
if (nbsubpil >= maxsubpil) {
|
|
maxsubpil = maxsubpil+30;
|
|
Handle(TColStd_HArray1OfInteger) newsubpil =
|
|
new TColStd_HArray1OfInteger (1,maxsubpil);
|
|
for (Standard_Integer bidpil = 1; bidpil <= maxsubpil - 30; bidpil ++)
|
|
newsubpil->SetValue(bidpil,subpile->Value(bidpil));
|
|
subpile = newsubpil;
|
|
}
|
|
nbsubpil ++;
|
|
subpile->SetValue(nbsubpil,num); // Append(num);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
// .... Gestion du Header : Preparation, lecture ....
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindNextHeaderRecord
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Integer StepData_StepReaderData::FindNextHeaderRecord
|
|
(const Standard_Integer num) const
|
|
{
|
|
// retourne, sur un numero d enregistrement donne (par num), le suivant qui
|
|
// definit une entite, ou 0 si c est fini :
|
|
// Opere comme FindNextRecord mais ne balaie que le Header
|
|
|
|
if (num < 0) return 0 ;
|
|
Standard_Integer num1 = num + 1 ;
|
|
Standard_Integer max = thenbhead;
|
|
|
|
while (num1 <= max ) {
|
|
// SCOPE,ENDSCOPE et Sous-Liste ont un identifieur negatif
|
|
// Ne retenir que les Idents positifs ou nuls (nul : pas d Ident dans Header)
|
|
if ( RecordIdent(num1) >= 0) return num1 ;
|
|
num1 ++ ;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : PrepareHeader
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void StepData_StepReaderData::PrepareHeader ()
|
|
{
|
|
// Resolution des references : ne concerne que les sous-listes
|
|
// deja faite par SetEntityNumbers donc pas de souci a se faire
|
|
|
|
/*
|
|
// Algorithme repris et adapte de SetEntityNumbers
|
|
// Traitement des sous-listes : se fait dans la foulee, par gestion d une pile
|
|
// basee sur la constitution des sous-listes
|
|
TColStd_SequenceOfInteger subpile;
|
|
Standard_Integer nbsubpil = 0; // profondeur de pile mais plus rapide ...
|
|
|
|
for (Standard_Integer num = 1 ; num <= thenbhead ; num ++) {
|
|
Standard_Integer nba = NbParams(num) ;
|
|
for (Standard_Integer na = nba ; na > 0 ; na --) {
|
|
.. On lit depuis la fin : cela permet de traiter les sous-listes dans la foulee
|
|
.. Sinon, on devrait noter qu il y a eu des sous-listes et reprendre ensuite
|
|
|
|
Interface_FileParameter& FP = ChangeParam(num,na);
|
|
Interface_ParamType letype = FP.ParamType();
|
|
if (letype == Interface_ParamSub) {
|
|
.. parametre type sous-liste : numero de la sous-liste lu par depilement
|
|
FP.SetEntityNumber(subpile.Last());
|
|
.. .. SetParam(num,na,FP);
|
|
subpile.Remove(nbsubpil);
|
|
nbsubpil --;
|
|
}
|
|
}
|
|
.. Si c est une sous-liste, empiler
|
|
if (RecordIdent(num) < -2) {
|
|
subpile.Append(num);
|
|
nbsubpil ++;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : GlobalCheck
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const Handle(Interface_Check) StepData_StepReaderData::GlobalCheck () const
|
|
{
|
|
return thecheck;
|
|
}
|