| 667 | |
| 668 | |
| 669 | std::optional<std::tuple<size_t, const IfcParse::declaration*, IfcEntityInstanceData>> IfcParse::InstanceStreamer::readInstance() { |
| 670 | std::optional<std::tuple<size_t, const IfcParse::declaration*, IfcEntityInstanceData>> return_value; |
| 671 | |
| 672 | if (header_ && yielded_header_instances_ < 3) { |
| 673 | if (yielded_header_instances_ == 0) { |
| 674 | return_value.emplace( |
| 675 | 0, |
| 676 | &header_->file_description()->declaration(), |
| 677 | std::move(header_->file_description()->data()) |
| 678 | ); |
| 679 | } else if (yielded_header_instances_ == 1) { |
| 680 | return_value.emplace( |
| 681 | 0, |
| 682 | &header_->file_name()->declaration(), |
| 683 | std::move(header_->file_name()->data()) |
| 684 | ); |
| 685 | } else if (yielded_header_instances_ == 2) { |
| 686 | return_value.emplace( |
| 687 | 0, |
| 688 | &header_->file_schema()->declaration(), |
| 689 | std::move(header_->file_schema()->data()) |
| 690 | ); |
| 691 | } |
| 692 | yielded_header_instances_ += 1; |
| 693 | return return_value; |
| 694 | } |
| 695 | |
| 696 | unsigned current_id = 0; |
| 697 | while (good_ && !lexer_->stream->eof() && !current_id) { |
| 698 | if (token_stream_[0].type == IfcParse::Token_IDENTIFIER && |
| 699 | token_stream_[1].type == IfcParse::Token_OPERATOR && |
| 700 | token_stream_[1].value_char == '=' && |
| 701 | token_stream_[2].type == IfcParse::Token_KEYWORD) { |
| 702 | current_id = (unsigned)TokenFunc::asIdentifier(token_stream_[0]); |
| 703 | const IfcParse::declaration* entity_type; |
| 704 | try { |
| 705 | entity_type = schema_->declaration_by_name(TokenFunc::asStringRef(token_stream_[2])); |
| 706 | } catch (const IfcException& ex) { |
| 707 | Logger::Message(Logger::LOG_ERROR, std::string(ex.what()) + " at offset " + std::to_string(token_stream_[2].startPos)); |
| 708 | current_id = 0; |
| 709 | goto advance; |
| 710 | } |
| 711 | |
| 712 | if (entity_type->as_entity() == nullptr) { |
| 713 | Logger::Message(Logger::LOG_ERROR, "Non entity type " + entity_type->name() + " at offset " + std::to_string(token_stream_[2].startPos)); |
| 714 | goto advance; |
| 715 | } |
| 716 | |
| 717 | for (auto& ty : types_to_bypass_) { |
| 718 | if (entity_type->is(*ty)) { |
| 719 | bypassed_instances_.push_back(current_id); |
| 720 | // Why is this a conditional clause in the loop? |
| 721 | current_id = 0; |
| 722 | goto advance; |
| 723 | } |
| 724 | } |
| 725 | |
| 726 | parse_context ps; |