--- /dev/null
+/*
+ Copyright (c) 1999-2020 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.
+*/
+
+#include <StepFile_ReadData.hxx>
+
+// Constant litterales
+namespace TextValue
+{
+ static char SubList[] = "/* (SUB) */";
+ static char Scope[] = "SCOPE";
+ static char Nil[] = " ";
+ static char Sub1[] = "$1"; /* optimisation ... */
+ static char Sub2[] = "$2";
+ static char ArgType1[] = "(IF#TnEHBx"; /* types arguments (2 1es lettres) */
+ static char ArgType2[] = ")nlIxdnxix";
+ static char IdZero[] = "#0";
+}
+
+class StepFile_ReadData::CharactersPage {
+
+public:
+
+ CharactersPage(const Standard_Integer theMaxCar) :myNext(NULL), myUsed(0)
+ {
+ myCharacters = new char[theMaxCar];
+ }
+
+ ~CharactersPage()
+ {
+ if (myCharacters != NULL)
+ {
+ delete[] myCharacters;
+ myCharacters = NULL;
+ }
+ }
+
+public:
+
+ CharactersPage* myNext; //!< Chaining of character pages
+ char* myCharacters; //!< Own characters page
+ int myUsed; //!< Counter employed characters
+};
+
+class StepFile_ReadData::Argument {
+
+public:
+ // Standard OCCT memory allocation stuff
+ DEFINE_STANDARD_ALLOC
+
+public:
+
+ Argument() :myNext(NULL), myValue(NULL), myType(ArgumentType_Sub) {}
+
+ ~Argument() {}
+
+public:
+
+ Argument* myNext; //!< Next argument in the list for this record
+ char* myValue; //!< Character value of the argument
+ ArgumentType myType; //!< Type of the argument
+};
+
+class StepFile_ReadData::ArgumentsPage {
+
+public:
+ // Standard OCCT memory allocation stuff
+ DEFINE_STANDARD_ALLOC
+
+public:
+
+ ArgumentsPage(Standard_Integer theMaxArg) :myNext(NULL), myUsed(0)
+ {
+ myArgs = new Argument[theMaxArg];
+ }
+
+ ~ArgumentsPage()
+ {
+ delete[] myArgs;
+ myArgs = NULL;
+ }
+
+public:
+
+ ArgumentsPage* myNext; //!< Chaining of arguments pages
+ Argument* myArgs; //!< Own arguments page
+ int myUsed; //!< Counter employed arguments
+};
+
+class StepFile_ReadData::Record {
+
+public:
+ // Standard OCCT memory allocation stuff
+ DEFINE_STANDARD_ALLOC
+
+public:
+
+ Record() :myNext(NULL), myFirst(NULL), myIdent(NULL), myType(NULL) {}
+
+ ~Record() {}
+
+public:
+
+ Record* myNext; //!< Next record in the list
+ Argument* myFirst; //!< First argument in the record
+ char* myIdent; //!< Record identifier (Example: "#12345") or scope-end
+ char* myType; //!< Type of the record
+};
+
+class StepFile_ReadData::Scope {
+
+public:
+ // Standard OCCT memory allocation stuff
+ DEFINE_STANDARD_ALLOC
+
+public:
+
+ Scope() :myPrevious(NULL), myRecord(NULL) {}
+
+ ~Scope()
+ {
+ if (myRecord != NULL)
+ {
+ delete[] myRecord;
+ myRecord = NULL;
+ }
+ }
+
+public:
+
+ Scope* myPrevious; //!< Previous scope, to which it will be necessary to return
+ Record* myRecord; //!< Record interrupted by the scope (to resume)
+};
+
+
+class StepFile_ReadData::RecordsPage
+{
+
+public:
+
+ RecordsPage(const Standard_Integer theMaxRec) :myNext(NULL), myUsed(0)
+ {
+ myRecords = new Record[theMaxRec];
+ }
+
+ ~RecordsPage()
+ {
+ if (myRecords != NULL)
+ {
+ delete[] myRecords;
+ myRecords = NULL;
+ }
+ }
+
+public:
+
+ RecordsPage* myNext; //!< Chaining of records pages
+ Record* myRecords; //!< Own records page
+ int myUsed; //!< Counter employed records
+};
+
+//=======================================================================
+//function : StepFile_ReadData
+//purpose :
+//=======================================================================
+
+StepFile_ReadData::StepFile_ReadData()
+ :myMaxChar(50000), myMaxRec(5000), myMaxArg(10000), myModePrint(0),
+ myNbRec(0), myNbHead(0), myNbPar(0), myYaRec(0),
+ myNumSub(0), myErrorArg(Standard_False), myResText(NULL), myCurrType(TextValue::SubList),
+ mySubArg(NULL), myTypeArg(ArgumentType_Sub), myCurrArg(NULL), myFirstRec(NULL),
+ myCurRec(NULL), myLastRec(NULL), myCurScope(NULL)
+{
+ myOneCharPage = new CharactersPage(myMaxChar);
+ myOneArgPage = new ArgumentsPage(myMaxArg);
+ myOneRecPage = new RecordsPage(myMaxRec);
+};
+
+//=======================================================================
+//function : CreateNewText
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::CreateNewText(const char* theNewText, int theLenText)
+{
+ // Optimization for most frequent entity, CARTESIAN_POINT
+ static char aTextOfCarPnt[] = "CARTESIAN_POINT";
+ if (strcmp(theNewText, aTextOfCarPnt) == 0) {
+ myResText = aTextOfCarPnt;
+ return;
+ }
+ // If error argument exists - prepare size to new text value and old result text
+ int aLenght = (myErrorArg) ? theLenText + (int)strlen(myResText) : theLenText;
+
+ if (myOneCharPage->myUsed > myMaxChar - aLenght - 1)
+ {
+ int aSizeOfPage = myMaxChar + 1;
+ if (aLenght >= myMaxChar) aSizeOfPage += (aLenght + 1 - myMaxChar);
+ CharactersPage* aNewPage = new CharactersPage(aSizeOfPage);
+ aNewPage->myNext = myOneCharPage;
+ myOneCharPage = aNewPage;
+ myOneCharPage->myUsed = 0;
+ }
+
+ char* anOldResText = myResText;
+
+ myResText = myOneCharPage->myCharacters + myOneCharPage->myUsed;
+ myOneCharPage->myUsed += (aLenght + 1);
+
+ // If error argument exists - append new text to old result text
+ // Else create new result text
+ if (myErrorArg)
+ {
+ strcpy(myResText, anOldResText);
+ strcpy(myResText + (int)strlen(anOldResText), theNewText);
+ return;
+ }
+ strcpy(myResText, theNewText);
+}
+
+//=======================================================================
+//function : RecordNewEntity
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::RecordNewEntity()
+{
+ myErrorArg = Standard_False; // Reset error argument mod
+ AddNewRecord(myCurRec);
+ SetTypeArg(ArgumentType_Sub);
+ mySubArg = myCurRec->myIdent;
+ myCurRec = myCurRec->myNext;
+ myLastRec->myNext = NULL;
+}
+
+//=======================================================================
+//function : RecordIdent
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::RecordIdent()
+{
+ myCurRec = CreateNewRecord();
+ GetResultText(&myCurRec->myIdent);
+ myCurRec->myNext = NULL;
+ myCurRec->myFirst = NULL;
+ myYaRec = 1;
+}
+
+//=======================================================================
+//function : RecordType
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::RecordType()
+{
+ if (!myYaRec)
+ {
+ myCurRec = CreateNewRecord();
+ myCurRec->myIdent = TextValue::IdZero;
+ myCurRec->myNext = NULL;
+ myCurRec->myFirst = NULL;
+ }
+ GetResultText(&myCurRec->myType);
+ myYaRec = myNumSub = 0;
+}
+
+//=======================================================================
+//function : RecordListStart
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::RecordListStart()
+{
+ if (myNumSub > 0)
+ {
+ Record* aSubRec;
+ aSubRec = CreateNewRecord();
+ switch (myNumSub)
+ {
+ case 1:
+ aSubRec->myIdent = TextValue::Sub1; break;
+ case 2:
+ aSubRec->myIdent = TextValue::Sub2; break;
+ default:
+ {
+ char aBufSub[10];
+ if (myNumSub > 9) Sprintf(aBufSub, "$%d", myNumSub);
+ else { aBufSub[0] = '$'; aBufSub[1] = (char)(myNumSub + 48); aBufSub[2] = '\0'; }
+ aSubRec->myIdent = RecordNewText(aBufSub);
+ }
+ }
+ aSubRec->myType = myCurrType;
+ myCurrType = TextValue::SubList;
+ aSubRec->myNext = myCurRec;
+ aSubRec->myFirst = NULL;
+ myCurRec = aSubRec;
+ }
+ myErrorArg = Standard_False; // Reset error arguments mode
+ myNumSub++;
+}
+
+
+//=======================================================================
+//function : CreateNewArg
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::CreateNewArg()
+{
+ Argument* aNewArg;
+ myNbPar++;
+ if (myOneArgPage->myUsed >= myMaxArg)
+ {
+ ArgumentsPage* aNewArgPage;
+ aNewArgPage = new ArgumentsPage(myMaxArg);
+ aNewArgPage->myNext = myOneArgPage;
+ myOneArgPage = aNewArgPage;
+ }
+ aNewArg = &myOneArgPage->myArgs[myOneArgPage->myUsed];
+ myOneArgPage->myUsed++;
+ aNewArg->myType = myTypeArg;
+ if (myTypeArg == ArgumentType_Sub)
+ aNewArg->myValue = mySubArg;
+ else
+ GetResultText(&aNewArg->myValue);
+
+ if (myTypeArg == ArgumentType_Misc)
+ myErrorArg = Standard_True;
+
+ if (myCurRec->myFirst == NULL)
+ {
+ myCurRec->myFirst = aNewArg;
+ }
+ else
+ {
+ Argument* aNextArg = myCurRec->myFirst;
+ while (aNextArg->myNext != NULL)
+ aNextArg = aNextArg->myNext;
+ aNextArg->myNext = aNewArg;
+ }
+ aNewArg->myNext = NULL;
+}
+
+//=======================================================================
+//function : CreateErrorArg
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::CreateErrorArg()
+{
+
+ // If already exists - update text value
+ if (!myErrorArg)
+ {
+ SetTypeArg(ArgumentType_Misc);
+ CreateNewArg();
+ myErrorArg = Standard_True;
+ return;
+ }
+
+ Argument* aCurrArg = myCurRec->myFirst;
+ while (aCurrArg->myNext != NULL)
+ aCurrArg = aCurrArg->myNext;
+
+ GetResultText(&aCurrArg->myValue);
+}
+
+//=======================================================================
+//function : AddNewScope
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::AddNewScope()
+{
+ Scope* aNewScope;
+ Record* aRecord;
+ aNewScope = new Scope;
+ aNewScope->myRecord = myCurRec;
+ aNewScope->myPrevious = myCurScope;
+ myCurScope = aNewScope;
+ aRecord = CreateNewRecord();
+ aRecord->myIdent = TextValue::Scope;
+ aRecord->myType = TextValue::Nil;
+ aRecord->myFirst = NULL;
+ AddNewRecord(aRecord);
+}
+
+//=======================================================================
+//function : FinalOfScope
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::FinalOfScope()
+{
+ Scope* anOldScope;
+ Record* aRecord;
+ if (myCurScope == NULL) return;
+
+ aRecord = CreateNewRecord();
+ aRecord->myIdent = TextValue::Scope;
+ aRecord->myType = TextValue::Nil;
+ aRecord->myFirst = NULL;
+
+ if (mySubArg[0] == '$')
+ {
+ if (myModePrint > 0)
+ {
+ Printf("Export List : (List in Record n0 %d) -- ", myNbRec);
+ PrintRecord(myLastRec);
+ }
+ myCurRec = aRecord;
+ myTypeArg = ArgumentType_Sub;
+ CreateNewArg();
+ }
+
+ AddNewRecord(aRecord);
+
+ myCurRec = myCurScope->myRecord;
+ myYaRec = 1;
+ anOldScope = myCurScope;
+ myCurScope = anOldScope->myPrevious;
+ delete anOldScope;
+}
+
+//=======================================================================
+//function : ClearRecorder
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::ClearRecorder(const Standard_Integer theMode)
+{
+ if (theMode & 1)
+ {
+ while (myOneRecPage != NULL)
+ {
+ RecordsPage* aNewPage;
+ aNewPage = myOneRecPage->myNext;
+ delete myOneRecPage;
+ myOneRecPage = NULL;
+ myOneRecPage = aNewPage;
+ }
+ while (myOneArgPage != NULL) {
+ ArgumentsPage* aNewPage; aNewPage = myOneArgPage->myNext;
+ delete myOneArgPage;
+ myOneArgPage = NULL;
+ myOneArgPage = aNewPage;
+ }
+ }
+ if (theMode & 2)
+ {
+ while (myOneCharPage != NULL)
+ {
+ CharactersPage* aNewPage; aNewPage = myOneCharPage->myNext;
+ delete myOneCharPage;
+ myOneCharPage = NULL;
+ myOneCharPage = aNewPage;
+ }
+ }
+}
+
+//=======================================================================
+//function : GetArgDescription
+//purpose :
+//=======================================================================
+
+Standard_Boolean StepFile_ReadData::GetArgDescription(ArgumentType* theType, char** theValue)
+{
+ if (myCurrArg == NULL)
+ return Standard_False;
+ *theType = myCurrArg->myType;
+ *theValue = myCurrArg->myValue;
+ myCurrArg = myCurrArg->myNext;
+ return Standard_True;
+}
+
+//=======================================================================
+//function : GetFileNbR
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::GetFileNbR(Standard_Integer* theNbHead,
+ Standard_Integer* theNbRec,
+ Standard_Integer* theNbPage)
+{
+ myCurRec = myFirstRec;
+ *theNbHead = myNbHead;
+ *theNbRec = myNbRec;
+ *theNbPage = myNbPar;
+}
+
+//=======================================================================
+//function : GetRecordDescription
+//purpose :
+//=======================================================================
+
+Standard_Boolean StepFile_ReadData::GetRecordDescription(char** theIdent,
+ char** theType,
+ int* theNbArg)
+{
+ if (myCurRec == NULL)
+ return Standard_False;
+ *theIdent = myCurRec->myIdent;
+ *theType = myCurRec->myType;
+ *theNbArg = (myCurRec->myFirst != NULL);
+ myCurrArg = myCurRec->myFirst;
+ return Standard_True;
+}
+
+//=======================================================================
+//function : RecordTypeText
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::RecordTypeText()
+{
+ GetResultText(&myCurrType);
+}
+
+//=======================================================================
+//function : NextRecord
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::NextRecord()
+{
+ myCurRec = myCurRec->myNext;
+}
+
+//=======================================================================
+//function : PrintRecord
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::PrintCurrentRecord()
+{
+ PrintRecord(myCurRec);
+}
+
+//=======================================================================
+//function : PrepareNewArg
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::PrepareNewArg()
+{
+ myErrorArg = Standard_False;
+}
+
+//=======================================================================
+//function : FinalOfHead
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::FinalOfHead()
+{
+ myNbHead = myNbRec;
+}
+
+//=======================================================================
+//function : SetTypeArg
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::SetTypeArg(const ArgumentType theArgType)
+{
+ myTypeArg = theArgType;
+}
+
+//=======================================================================
+//function : SetModePrint
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::SetModePrint(const Standard_Integer theMode)
+{
+ myModePrint = theMode;
+}
+
+//=======================================================================
+//function : GetModePrint
+//purpose :
+//=======================================================================
+
+Standard_Integer StepFile_ReadData::GetModePrint() const
+{
+ return myModePrint;
+}
+
+//=======================================================================
+//function : GetNbRecord
+//purpose :
+//=======================================================================
+
+Standard_Integer StepFile_ReadData::GetNbRecord() const
+{
+ return myNbRec;
+}
+
+//=======================================================================
+//function : RecordNewText
+//purpose :
+//=======================================================================
+
+char* StepFile_ReadData::RecordNewText(char* theText)
+{
+ char* aSavResText;
+ char* aNewText;
+ aSavResText = myResText;
+ CreateNewText(theText, (int)strlen(theText));
+ aNewText = myResText;
+ myResText = aSavResText;
+ return aNewText;
+}
+
+//=======================================================================
+//function : GetResultText
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::GetResultText(char** theText)
+{
+ *theText = myResText;
+}
+
+//=======================================================================
+//function : AddNewRecord
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::AddNewRecord(Record* theNewRecord)
+{
+ myNbRec++;
+ if (myFirstRec == NULL) myFirstRec = theNewRecord;
+ if (myLastRec != NULL) myLastRec->myNext = theNewRecord;
+ myLastRec = theNewRecord;
+}
+
+//=======================================================================
+//function : CreateNewRecord
+//purpose :
+//=======================================================================
+
+StepFile_ReadData::Record* StepFile_ReadData::CreateNewRecord()
+{
+ Record* aNewRecord;
+ if (myOneRecPage->myUsed >= myMaxRec)
+ {
+ RecordsPage* aNewRecPage;
+ aNewRecPage = new RecordsPage(myMaxRec);
+ aNewRecPage->myNext = myOneRecPage;
+ myOneRecPage = aNewRecPage;
+ }
+ aNewRecord = &myOneRecPage->myRecords[myOneRecPage->myUsed];
+ myOneRecPage->myUsed++;
+
+ return aNewRecord;
+}
+
+//=======================================================================
+//function : PrintRecord
+//purpose :
+//=======================================================================
+
+void StepFile_ReadData::PrintRecord(Record* theRecord)
+{
+ int aNumArg = 0;
+ int aNumLen = 0;
+ int anArgLen = 0;
+ if (theRecord == NULL) { Printf("Non defini\n"); return; }
+ Printf("Ident : %s Type : %s Nb.Arg.s : %s\n",
+ theRecord->myIdent, theRecord->myType,
+ (theRecord->myFirst ? theRecord->myFirst->myValue : ""));
+ if (myModePrint < 2) return;
+ myCurrArg = theRecord->myFirst;
+ while (myCurrArg != NULL)
+ {
+ aNumArg++;
+ anArgLen = (int)strlen(myCurrArg->myValue) + 18;
+ aNumLen += anArgLen;
+ if (aNumLen > 132) { Printf("\n"); aNumLen = anArgLen; }
+ Printf(" - Arg.%d[%c%c] : %s",
+ aNumArg, TextValue::ArgType1[myCurrArg->myType],
+ TextValue::ArgType2[myCurrArg->myType], myCurrArg->myValue);
+ myCurrArg = myCurrArg->myNext;
+ }
+ if (anArgLen > 0) Printf("\n");
+}