@@ -210,17 +210,17 @@ void IfcSpfStream::Inc() {
210210 if ( current == ' \n ' || current == ' \r ' ) IfcSpfStream::Inc ();
211211}
212212
213- Tokens::Tokens (IfcParse::IfcSpfStream *s, IfcParse::IfcFile* f) {
213+ IfcSpfLexer::IfcSpfLexer (IfcParse::IfcSpfStream *s, IfcParse::IfcFile* f) {
214214 file = f;
215215 stream = s;
216216 decoder = new IfcCharacterDecoder (s);
217217}
218218
219- Tokens ::~Tokens () {
219+ IfcSpfLexer ::~IfcSpfLexer () {
220220 delete decoder;
221221}
222222
223- unsigned int Tokens ::skipWhitespace () {
223+ unsigned int IfcSpfLexer ::skipWhitespace () {
224224 unsigned int n = 0 ;
225225 while ( !stream->eof ) {
226226 char c = stream->Peek ();
@@ -233,7 +233,7 @@ unsigned int Tokens::skipWhitespace() {
233233 return n;
234234}
235235
236- unsigned int Tokens ::skipComment () {
236+ unsigned int IfcSpfLexer ::skipComment () {
237237 char c = stream->Peek ();
238238 if (c != ' /' ) return 0 ;
239239 stream->Inc ();
@@ -257,7 +257,7 @@ unsigned int Tokens::skipComment() {
257257//
258258// Returns the offset of the current Token and moves cursor to next
259259//
260- Token Tokens ::Next () {
260+ Token IfcSpfLexer ::Next () {
261261
262262 if ( stream->eof ) return TokenPtr ();
263263
@@ -298,7 +298,7 @@ Token Tokens::Next() {
298298// Reads a std::string from the file at specified offset
299299// Omits whitespace and comments
300300//
301- std::string Tokens ::TokenString (unsigned int offset) {
301+ std::string IfcSpfLexer ::TokenString (unsigned int offset) {
302302 const bool was_eof = stream->eof ;
303303 unsigned int old_offset = stream->Tell ();
304304 stream->Seek (offset);
@@ -323,9 +323,9 @@ std::string Tokens::TokenString(unsigned int offset) {
323323// Functions for creating Tokens from an arbitary file offset.
324324// The first 4 bits are reserved for Tokens of type ()=,;$*
325325//
326- Token IfcParse::TokenPtr (Tokens * tokens, unsigned int offset) { return Token (tokens,offset); }
327- Token IfcParse::TokenPtr (char c) { return Token ((Tokens *)0 ,(unsigned ) c); }
328- Token IfcParse::TokenPtr () { return Token ((Tokens *)0 ,0 ); }
326+ Token IfcParse::TokenPtr (IfcSpfLexer * tokens, unsigned int offset) { return Token (tokens,offset); }
327+ Token IfcParse::TokenPtr (char c) { return Token ((IfcSpfLexer *)0 ,(unsigned ) c); }
328+ Token IfcParse::TokenPtr () { return Token ((IfcSpfLexer *)0 ,0 ); }
329329
330330//
331331// Functions to convert Tokens to binary data
@@ -345,8 +345,9 @@ bool TokenFunc::isString(const Token& t) {
345345bool TokenFunc::isEnumeration (const Token& t) {
346346 return ! isOperator (t) && startsWith (t, ' .' );
347347}
348- bool TokenFunc::isDatatype (const Token& t) {
349- return ! isOperator (t) && startsWith (t, ' I' );
348+ bool TokenFunc::isKeyword (const Token& t) {
349+ // bool is a subtype of enumeration, no need to test for that
350+ return !isOperator (t) && !isIdentifier (t) && !isString (t) && !isEnumeration (t) && !isInt (t) && !isFloat (t);
350351}
351352bool TokenFunc::isInt (const Token& t) {
352353 if (isOperator (t)) return false ;
@@ -419,7 +420,7 @@ EntityArgument::EntityArgument(const Token& t) {
419420// Reads the arguments from a list of token
420421// Aditionally, stores the ids (i.e. #[\d]+) in a vector
421422//
422- ArgumentList::ArgumentList (Tokens * t, std::vector<unsigned int >& ids) {
423+ ArgumentList::ArgumentList (IfcSpfLexer * t, std::vector<unsigned int >& ids) {
423424 IfcParse::IfcFile* file = t->file ;
424425
425426 Token next = t->Next ();
@@ -429,7 +430,7 @@ ArgumentList::ArgumentList(Tokens* t, std::vector<unsigned int>& ids) {
429430 else if ( TokenFunc::isOperator (next,' (' ) ) Push ( new ArgumentList (t,ids) );
430431 else {
431432 if ( TokenFunc::isIdentifier (next) ) ids.push_back (TokenFunc::asInt (next));
432- if ( TokenFunc::isDatatype (next) ) {
433+ if ( TokenFunc::isKeyword (next) ) {
433434 t->Next ();
434435 try {
435436 Push ( new EntityArgument (next) );
@@ -619,7 +620,7 @@ EntityArgument::~EntityArgument() { delete entity; }
619620Entity::Entity (unsigned int i, IfcFile* f) : _id (i), args (0 ) {
620621 file = f;
621622 Token datatype = f->tokens ->Next ();
622- if ( ! TokenFunc::isDatatype (datatype)) throw IfcException (" Unexpected token while parsing entity" );
623+ if ( ! TokenFunc::isKeyword (datatype)) throw IfcException (" Unexpected token while parsing entity" );
623624 _type = IfcSchema::Type::FromString (TokenFunc::asString (datatype));
624625 offset = datatype.second ;
625626}
@@ -661,7 +662,7 @@ void Entity::Load(std::vector<unsigned int>& ids, bool seek) const {
661662 if ( seek ) {
662663 file->tokens ->stream ->Seek (offset);
663664 Token datatype = file->tokens ->Next ();
664- if ( ! TokenFunc::isDatatype (datatype)) throw IfcException (" Unexpected token while parsing entity" );
665+ if ( ! TokenFunc::isKeyword (datatype)) throw IfcException (" Unexpected token while parsing entity" );
665666 _type = IfcSchema::Type::FromString (TokenFunc::asString (datatype));
666667 }
667668 Token open = file->tokens ->Next ();
@@ -760,13 +761,27 @@ bool IfcFile::Init(std::istream& f, int len) {
760761bool IfcFile::Init (void * data, int len) {
761762 return IfcFile::Init (new IfcSpfStream (data,len));
762763}
763- bool IfcFile::Init (IfcParse::IfcSpfStream* f) {
764- IfcSchema::InitStringMap ();
765- stream = f;
766- if ( ! stream->valid ) return false ;
767- tokens = new Tokens (stream,this );
764+ bool IfcFile::Init (IfcParse::IfcSpfStream* s) {
765+ stream = s;
766+ if (!stream->valid ) {
767+ return false ;
768+ }
769+
770+ tokens = new IfcSpfLexer (stream, this );
771+ _header.lexer (tokens);
772+ _header.tryRead ();
773+
774+ std::vector<std::string> schemas;
775+ try {
776+ schemas = _header.file_schema ().schema_identifiers ();
777+ } catch (...) {}
778+ if (schemas.size () != 1 || schemas[0 ] != IfcSchema::Identifier) {
779+ Logger::Message (Logger::LOG_WARNING, std::string (" File schema encountered that is different from expected value of '" ) + IfcSchema::Identifier + " '" );
780+ }
781+
768782 Token token = TokenPtr ();
769783 Token previous = TokenPtr ();
784+
770785 unsigned int currentId = 0 ;
771786 lastId = 0 ;
772787 int x = 0 ;
0 commit comments