Handle nested SCOPE constructs and export lists while indexing Part 21 records, preserving scope-owned source records and their references. Add scoped-record coverage.
142 lines
4.9 KiB
C++
142 lines
4.9 KiB
C++
#ifndef SECTIONREADER_H
|
|
#define SECTIONREADER_H
|
|
|
|
#include <fstream>
|
|
#include <set>
|
|
#include "cllazyfile/lazyTypes.h"
|
|
#include "sc_export.h"
|
|
#include "clutils/errordesc.h"
|
|
#include "clstepcore/STEPcomplex.h"
|
|
|
|
class SDAI_Application_instance;
|
|
class lazyFileReader;
|
|
class ErrorDescriptor;
|
|
class Registry;
|
|
|
|
class SC_LAZYFILE_EXPORT sectionReader {
|
|
protected:
|
|
//protected data members
|
|
lazyFileReader * _lazyFile;
|
|
#ifdef _MSC_VER
|
|
#pragma warning( push )
|
|
#pragma warning( disable: 4251 )
|
|
#endif
|
|
std::ifstream & _file;
|
|
|
|
std::streampos _sectionStart, ///< the start of this section as reported by tellg()
|
|
_sectionEnd; ///< the end of this section as reported by tellg()
|
|
#ifdef _MSC_VER
|
|
#pragma warning( pop )
|
|
#endif
|
|
unsigned long _totalInstances;
|
|
|
|
ErrorDescriptor * _error;
|
|
sectionID _sectionID;
|
|
fileID _fileID;
|
|
|
|
// protected member functions
|
|
|
|
sectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid );
|
|
~sectionReader();
|
|
|
|
/** Find a string, ignoring occurrences in comments or Part 21 strings (i.e. 'string with \S\' control directive' )
|
|
* \param str string to find
|
|
* \param semicolon if true, 'str' must be followed by a semicolon, possibly preceded by whitespace.
|
|
* \returns the position of the end of the found string
|
|
*/
|
|
std::streampos findNormalString( const std::string & str, bool semicolon = false );
|
|
|
|
/** Skip from immediately after a comment's opening slash and star
|
|
* through its closing star and slash. Part 21 comments are opaque:
|
|
* apostrophes and string-control text inside them have no syntax.
|
|
*/
|
|
bool skipComment();
|
|
|
|
/** Skip whitespace and Part 21 comments, leaving the next syntactic
|
|
* token unread. */
|
|
bool skipTokenSeparators();
|
|
|
|
/** Skip an Edition 1 SCOPE construct, including nested scopes and its
|
|
* optional export list. The stream must initially point at '&' and
|
|
* is left at the owning entity's record. */
|
|
bool skipScope();
|
|
|
|
/** Skip an optional scope export list at the current stream
|
|
* position. */
|
|
bool skipScopeExportList();
|
|
|
|
/** Get a keyword ending with one of delimiters.
|
|
*/
|
|
const char * getDelimitedKeyword( const char * delimiters );
|
|
|
|
/** Seek to the end of the current instance */
|
|
std::streampos seekInstanceEnd( instanceRefs ** refs, std::vector<std::string> * componentTypes = 0 );
|
|
|
|
/// operator>> is very slow?!
|
|
inline void skipWS() {
|
|
while( isspace( _file.peek() ) && _file.good() ) {
|
|
_file.ignore( 1 );
|
|
}
|
|
}
|
|
|
|
STEPcomplex * CreateSubSuperInstance( const Registry * reg, instanceID fileid, Severity & sev );
|
|
|
|
public:
|
|
SDAI_Application_instance * getRealInstance( const Registry * reg, lazyFileOffset begin, instanceID instance,
|
|
const std::string & typeName = "", const std::string & schName = "", bool header = false );
|
|
|
|
/** Return one indexed source record without materializing it. The
|
|
* stream position is restored before returning. This is intended
|
|
* for lightweight adapters which can detach scalar/reference data
|
|
* directly from Part 21 source. */
|
|
std::string sourceRecord( lazyFileOffset begin, uint64_t length );
|
|
|
|
sectionID ID() const {
|
|
return _sectionID;
|
|
}
|
|
|
|
virtual void findSectionStart() = 0;
|
|
|
|
void findSectionEnd() {
|
|
_sectionEnd = findNormalString( "ENDSEC", true );
|
|
}
|
|
|
|
std::streampos sectionStart() const {
|
|
return _sectionStart;
|
|
}
|
|
|
|
std::streampos sectionEnd() const {
|
|
return _sectionEnd;
|
|
}
|
|
|
|
void locateAllInstances(); /**< find instances in section, and add lazyInstance's to lazyInstMgr */
|
|
|
|
virtual const namedLazyInstance nextInstance() = 0;
|
|
|
|
/** returns the type string for an instance, read straight from the file
|
|
* if this function changes, probably need to change nextInstance() as well
|
|
* don't check errors - they would have been encountered during the initial file scan, and the file is still open so it can't have been modified */
|
|
const char * getType( lazyFileOffset offset ) {
|
|
if( offset <= 0 ) {
|
|
return 0;
|
|
}
|
|
_file.seekg( static_cast<std::streamoff>( offset ) );
|
|
readInstanceNumber();
|
|
if( !skipTokenSeparators() ) return 0;
|
|
if( _file.peek() == '&' && !skipScope() ) return 0;
|
|
if( !skipTokenSeparators() ) return 0;
|
|
return getDelimitedKeyword( ";( /\\" );
|
|
}
|
|
|
|
instanceID readInstanceNumber();
|
|
|
|
void seekg( std::streampos pos ) {
|
|
_file.seekg( pos );
|
|
}
|
|
std::streampos tellg() {
|
|
return _file.tellg();
|
|
}
|
|
};
|
|
|
|
#endif //SECTIONREADER_H
|