mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-06 18:26:22 +03:00
- Parser is corrected to handle case of missing arguments properly (report error without corruption of the next entity) - Added counter of entity arguments for appropriate error messages - Plain C tools and data structures (recfile.*, stepfile.*) are converted to C++ class (StepFile_ReadData) to avoid use of static variables, so that reader can be safely used in a multi-threaded environment
265 lines
11 KiB
C++
265 lines
11 KiB
C++
/*
|
|
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.
|
|
*/
|
|
|
|
#ifndef _StepFile_ReadData_HeaderFile
|
|
#define _StepFile_ReadData_HeaderFile
|
|
|
|
// Types of arguments
|
|
enum ArgumentType {
|
|
ArgumentType_Sub = 0,
|
|
ArgumentType_Integer,
|
|
ArgumentType_Float,
|
|
ArgumentType_Ident,
|
|
ArgumentType_Text,
|
|
ArgumentType_Nondef,
|
|
ArgumentType_Enum,
|
|
ArgumentType_Hexa,
|
|
ArgumentType_Binary,
|
|
ArgumentType_Misc
|
|
};
|
|
|
|
#include <Standard.hxx>
|
|
#include <Standard_DefineAlloc.hxx>
|
|
|
|
//! Provides data structures and tools to collect and store the data
|
|
//! read from the STEP file.
|
|
//! This class is designed to work in collaboration with STEP parser
|
|
//! built using flex and bison (receives the data generated by the parser).
|
|
//!
|
|
//! All text (sequence of characters) received in the parsing process
|
|
//! is stored in the CharacterPage, but the last received text value is
|
|
//! stored in a pointer to an own page position.
|
|
//!
|
|
//! This value is used to initialize a new record (representation of the
|
|
//! STEP entity) and its arguments (parameters of the STEP entity).
|
|
//! All created arguments are stored in the ArgumentsPage, records in the RecordsPage.
|
|
//!
|
|
//! NOTE:
|
|
//! - Arguments used in the record are pointers to the element of the page,
|
|
//! - All records are pointers to the element of the record page.
|
|
//!
|
|
//! EXAMPLE of parsing STEP file (flex & bison):
|
|
//!
|
|
//! 1. Initial state:
|
|
//! - Input stream to the Flex is "#123=ADVANCED_FACE('',(#124),#125,.F.)"
|
|
//! - State of Flex is "INITIAL"
|
|
//! - Stack of Bison states : STEP HEADER ENDSEC endhead model block
|
|
//! 2. Flex rule detected "#123" - call CreateNewText("#123", 4)
|
|
//! and sends a token "ENTITY".
|
|
//! Now class contains "#123", as current text value.
|
|
//! 3. Bison receive a token and call RecordIdent (), it
|
|
//! creates a new record in the records page with "#123" identifier.
|
|
//! Now current record has ident, but args and types are empty.
|
|
//! 4. Flex rule detected "ADVANCED_FACE" call CreateNewText and send a token "TYPE".
|
|
//! Now class contains "ADVANCED_FACE", as current text value.
|
|
//! 5. Bison receive a token and call RecordType (), it
|
|
//! set "ADVANCED_FACE" to the current record as a type.
|
|
//! Now current record has ident and type, but args are empty.
|
|
//! 6. Flex rule detected "(" send token "(".
|
|
//! Now class continues to contain "ADVANCED_FACE", as current text value.
|
|
//! 7. Bison receive a token and call RecordListStart (),
|
|
//! it does nothing via the current state.
|
|
//! Now current record is not update.
|
|
//! 8. Flex rule detected ('') call CreateNewText and SetTypeArg and
|
|
//! send token TEXT.
|
|
//! Now class contains empty current text value.
|
|
//! 9. Bison receive a token and call CreateNewArg (), it
|
|
//! creates a new argument with empty text value and 'Text' type.
|
|
//! Now current record has ident, type and one argument.
|
|
//! 10. Flex rule detected "," call PrepareNewArg(",",1), it
|
|
//! controls arguments count to protect from a skip or double creating a new argument.
|
|
//! Bison does nothing and the current text value and record are not updated.
|
|
//! 11. Flex rule detected "(" send token "(".
|
|
//! Now class continues to contain empty current text value.
|
|
//! 12. Bison receive a token and call RecordListStart (), it
|
|
//! creates a new record with "$1" ident and "ADVANCED_FACE" type
|
|
//! old record is the next of the new record.
|
|
//! Now current record has ident, type, but args are empty.
|
|
//! 13. Flex rule detected "#124" call CreateNewText("#124",4) and send token "IDENT",
|
|
//! Now class contains "#124", as current text value.
|
|
//! 14. Bison receive a token and call CreateNewArg (), it
|
|
//! creates a new argument with "#124" text value and 'Ident' type.
|
|
//! Now current record has ident, type and one argument.
|
|
//! 15. Flex rule detected ")" send token ")".
|
|
//! Now class continues to contain "#124", as a current text value.
|
|
//! 16. Bison receive a token and call RecordNewEntity (), it
|
|
//! contain record to the records page, prepare to the new record
|
|
//! and get next record as a current record and set a new arg as a sub_record.
|
|
//! Now current record is a old record, it has ident, type and two args.
|
|
//! 17. Flex rule detected "#125" call CreateNewText, SetTypeArg and send token IDEND.
|
|
//! Now class contains "#125", as a current text value.
|
|
//! 18. Bison receive a token and call CreateNewArg (), it
|
|
//! creates a new argument with "#125" text value and 'Ident' type.
|
|
//! Now current record has ident, type and three argument.
|
|
//! 19. Flex rule detected "#125" call CreateNewText, SetTypeArg and send token IDEND.
|
|
//! Now class contains "#125", as a current text value.
|
|
//! 20. Bison receive a token and call CreateNewArg (), it
|
|
//! creates a new argument with "#125" text value and 'Ident' type.
|
|
//! Now current record has ident, type and three argument.
|
|
//! ...
|
|
//!
|
|
//! Reading of several STEP files simultaneously is possible (e.g. in multiple
|
|
//! threads) provided that each file is read using its own instances of Flex, Bison
|
|
//! and StepFile_ReadData tools.
|
|
|
|
class StepFile_ReadData
|
|
{
|
|
public:
|
|
// Standard OCCT memory allocation stuff
|
|
DEFINE_STANDARD_ALLOC
|
|
|
|
private:
|
|
|
|
class CharactersPage; //!< List of characters pages, contains all text derived from Flex
|
|
class Record; //!< List of records, contains all text processed by Bison
|
|
class Argument; //!< List of arguments, contains all argument descriptions
|
|
class ArgumentsPage; //!< List of arguments pages, contains all text derived from Flex
|
|
class Scope; //!< List of scopes pages, contains all records for external processing
|
|
class RecordsPage; //!< List of records pages, contains all records
|
|
|
|
public:
|
|
|
|
//! Constructs an uninitialized tool
|
|
StepFile_ReadData();
|
|
|
|
//! Destructor cleans allocated memory of all fields
|
|
~StepFile_ReadData() { ClearRecorder(3); }
|
|
|
|
//! Preperes the text value for analysis.
|
|
//! It is the main tool for transferring data from flex to bison
|
|
//! If characters page is full, allocates a new page.
|
|
void CreateNewText(const char* theNewText, int theLenText);
|
|
|
|
//! Adds the current record to the list
|
|
void RecordNewEntity();
|
|
|
|
//! Creates a new record and sets Ident from myResText
|
|
void RecordIdent();
|
|
|
|
//! Starts reading of the type (entity)
|
|
void RecordType();
|
|
|
|
//! Prepares and saves a record or sub-record
|
|
void RecordListStart();
|
|
|
|
//! Prepares new arguments.
|
|
//! Type and value already known.
|
|
//! If arguments page is full, allocates a new page
|
|
void CreateNewArg();
|
|
|
|
//! Prepares error arguments, controls count of error arguments.
|
|
//! If bison handles a sequence of error types,
|
|
//! creates only one argument and updates text value
|
|
void CreateErrorArg();
|
|
|
|
//! Creates a new scope, containing the current record
|
|
void AddNewScope();
|
|
|
|
//! Ends the scope
|
|
void FinalOfScope();
|
|
|
|
//! Releases memory.
|
|
//! @param theMode
|
|
//! * 1 - clear pages of records and arguments
|
|
//! * 2 - clear pages of characters
|
|
//! * 3 - clear all data
|
|
void ClearRecorder(const Standard_Integer theMode);
|
|
|
|
//! Returns a value of fields of current argument
|
|
Standard_Boolean GetArgDescription(ArgumentType* theType, char** theValue);
|
|
|
|
//! Returns a value of all file counters
|
|
void GetFileNbR(Standard_Integer* theNbHead, Standard_Integer* theNbRec, Standard_Integer* theNbPage);
|
|
|
|
//! Returns a value of fields of current record
|
|
Standard_Boolean GetRecordDescription(char** theIdent, char** theType, int* theNbArg);
|
|
|
|
//! Initializes the record type with myResText
|
|
void RecordTypeText();
|
|
|
|
//! Skips to next record
|
|
void NextRecord();
|
|
|
|
//! Prints data of current record according to the modeprint
|
|
void PrintCurrentRecord();
|
|
|
|
//! Controls the correct argument count for the record.
|
|
//! Resets error argyment mode
|
|
void PrepareNewArg();
|
|
|
|
//! Prepares the end of the head section
|
|
void FinalOfHead();
|
|
|
|
//! Sets type of the current argument
|
|
void SetTypeArg(const ArgumentType theArgType);
|
|
|
|
//! Initializes the print mode
|
|
//! 0 - don't print descriptions
|
|
//! 1 - print only descriptions of record
|
|
//! 2 - print descriptions of records and its arguments
|
|
void SetModePrint(const Standard_Integer theMode);
|
|
|
|
//! Returns mode print
|
|
Standard_Integer GetModePrint() const;
|
|
|
|
//! Returns number of records
|
|
Standard_Integer GetNbRecord() const;
|
|
|
|
private:
|
|
|
|
//! Prepare text to analyze
|
|
char* RecordNewText(char* theText);
|
|
|
|
//! Get current text value
|
|
void GetResultText(char** theText);
|
|
|
|
//! Add a record to the current records page
|
|
void AddNewRecord(Record* theNewRecord);
|
|
|
|
//! Create new empty record
|
|
//! If records page is fill, add a new page
|
|
Record* CreateNewRecord();
|
|
|
|
//! Print data of the record according to the modeprint
|
|
void PrintRecord(Record* theRecord);
|
|
|
|
private:
|
|
|
|
Standard_Integer myMaxChar; //!< Maximum number of characters in a characters page
|
|
Standard_Integer myMaxRec; //!< Maximum number of records in a records page
|
|
Standard_Integer myMaxArg; //!< Maximum number of arguments in a arguments page
|
|
Standard_Integer myModePrint; //!< Control print output (for call from yacc)
|
|
Standard_Integer myNbRec; //!< Total number of data records read
|
|
Standard_Integer myNbHead; //!< Number of records taken by the Header
|
|
Standard_Integer myNbPar; //!< Total number of parameters read
|
|
Standard_Integer myYaRec; //!< Presence record already created (after 1 Ident)
|
|
Standard_Integer myNumSub; //!< Number of current sublist
|
|
Standard_Boolean myErrorArg; //!< Control of error argument (true - error argument was created)
|
|
char* myResText; //!< Text value written by Flex and passed to Bison to create record
|
|
char* myCurrType; //!< Type of last record read
|
|
char* mySubArg; //!< Ident last record (possible sub-list)
|
|
ArgumentType myTypeArg; //!< Type of last argument read
|
|
Argument* myCurrArg; //!< Current node of the argumets list
|
|
Record* myFirstRec; //!< First node of the records list
|
|
Record* myCurRec; //!< Current node of the records list
|
|
Record* myLastRec; //!< Last node of the records list
|
|
Scope* myCurScope; //!< Current node of the scopes list
|
|
RecordsPage* myOneRecPage; //!< Current node of the records pages list
|
|
CharactersPage* myOneCharPage; //!< Current node of the characters pages list
|
|
ArgumentsPage* myOneArgPage; //!< Current node of the arguments pages list
|
|
};
|
|
|
|
#endif // _StepFile_ReadData_HeaderFile
|