Files
Clifford Yapp 0e091f0de7 lazy: index Edition 1 SCOPE records
Handle nested SCOPE constructs and export lists while indexing Part 21
records, preserving scope-owned source records and their references.
Add scoped-record coverage.
2026-08-01 22:27:46 -04:00

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