mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 09:32:37 +00:00
Fix streamer header ownership
Create file-owned headers after storage is selected but before streaming starts. Let owner-backed streamers use that header directly, and keep owned_header_ exclusively for ownerless streamers. Generated with the assistance of an AI coding tool.
This commit is contained in:
+1
-2
@@ -97,7 +97,6 @@ private:
|
|||||||
Reader* stream_;
|
Reader* stream_;
|
||||||
std::unique_ptr<spf_lexer<Reader>> lexer_;
|
std::unique_ptr<spf_lexer<Reader>> lexer_;
|
||||||
std::unique_ptr<spf_header> owned_header_;
|
std::unique_ptr<spf_header> owned_header_;
|
||||||
spf_header* header_;
|
|
||||||
ifcopenshell::file* owner_;
|
ifcopenshell::file* owner_;
|
||||||
boost::circular_buffer<token> token_stream_;
|
boost::circular_buffer<token> token_stream_;
|
||||||
const ifcopenshell::schema_definition* schema_;
|
const ifcopenshell::schema_definition* schema_;
|
||||||
@@ -171,7 +170,7 @@ private:
|
|||||||
|
|
||||||
const ifcopenshell::schema_definition* schema() const { return schema_; }
|
const ifcopenshell::schema_definition* schema() const { return schema_; }
|
||||||
|
|
||||||
const spf_header* header() const { return header_; }
|
const spf_header* header() const;
|
||||||
|
|
||||||
~instance_streamer() = default;
|
~instance_streamer() = default;
|
||||||
|
|
||||||
|
|||||||
+30
-28
@@ -1666,10 +1666,12 @@ bool ifcopenshell::file::initialize(const std::string& fn, bool mmap) {
|
|||||||
if (mmap) {
|
if (mmap) {
|
||||||
file_reader<mmap_impl> s(fn);
|
file_reader<mmap_impl> s(fn);
|
||||||
storage_.emplace<1>(this, logger_.get());
|
storage_.emplace<1>(this, logger_.get());
|
||||||
|
header_.reset(new spf_header(this, &logger_.get()));
|
||||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||||
} else {
|
} else {
|
||||||
file_reader<full_buffer_impl> s(fn);
|
file_reader<full_buffer_impl> s(fn);
|
||||||
storage_.emplace<1>(this, logger_.get());
|
storage_.emplace<1>(this, logger_.get());
|
||||||
|
header_.reset(new spf_header(this, &logger_.get()));
|
||||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1681,7 +1683,6 @@ bool ifcopenshell::file::initialize(const std::string& fn, bool mmap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||||
header_.reset(new spf_header(this, &logger_.get()));
|
|
||||||
return good_ == file_open_status::SUCCESS;
|
return good_ == file_open_status::SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1696,6 +1697,7 @@ bool ifcopenshell::file::initialize(const std::string& path, filetype ty, bool r
|
|||||||
if (ty == FT_IFCSPF) {
|
if (ty == FT_IFCSPF) {
|
||||||
file_reader<full_buffer_impl> s(path);
|
file_reader<full_buffer_impl> s(path);
|
||||||
storage_.emplace<1>(this, logger_.get());
|
storage_.emplace<1>(this, logger_.get());
|
||||||
|
header_.reset(new spf_header(this, &logger_.get()));
|
||||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||||
|
|
||||||
if ((good_ = std::get<impl::in_memory_file_storage>(storage_).good_)) {
|
if ((good_ = std::get<impl::in_memory_file_storage>(storage_).good_)) {
|
||||||
@@ -1732,7 +1734,9 @@ bool ifcopenshell::file::initialize(const std::string& path, filetype ty, bool r
|
|||||||
// throw std::runtime_error("Unsupported file format");
|
// throw std::runtime_error("Unsupported file format");
|
||||||
}
|
}
|
||||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||||
header_.reset(new spf_header(this, &logger_.get()));
|
if (!header_) {
|
||||||
|
header_.reset(new spf_header(this, &logger_.get()));
|
||||||
|
}
|
||||||
return good_ == file_open_status::SUCCESS;
|
return good_ == file_open_status::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1763,6 +1767,7 @@ file::file(std::istream& stream, int length, ::logger& log)
|
|||||||
s.push_next_page(string_data);
|
s.push_next_page(string_data);
|
||||||
|
|
||||||
storage_.emplace<1>(this, logger_.get());
|
storage_.emplace<1>(this, logger_.get());
|
||||||
|
header_.reset(new spf_header(this, &logger_.get()));
|
||||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||||
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
||||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||||
@@ -1771,7 +1776,6 @@ file::file(std::istream& stream, int length, ::logger& log)
|
|||||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
||||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||||
|
|
||||||
header_.reset(new spf_header(this, &logger_.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file::file(void* data, int length, ::logger& log)
|
file::file(void* data, int length, ::logger& log)
|
||||||
@@ -1783,6 +1787,7 @@ file::file(void* data, int length, ::logger& log)
|
|||||||
file_reader<pushed_sequential_impl> s(std::string((char*)data, length), caller_fed_tag{});
|
file_reader<pushed_sequential_impl> s(std::string((char*)data, length), caller_fed_tag{});
|
||||||
|
|
||||||
storage_.emplace<1>(this, logger_.get());
|
storage_.emplace<1>(this, logger_.get());
|
||||||
|
header_.reset(new spf_header(this, &logger_.get()));
|
||||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||||
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
||||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||||
@@ -1791,7 +1796,6 @@ file::file(void* data, int length, ::logger& log)
|
|||||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
||||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||||
|
|
||||||
header_.reset(new spf_header(this, &logger_.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std::string& path, ::logger& log)
|
file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std::string& path, ::logger& log)
|
||||||
@@ -1901,21 +1905,22 @@ bool try_parse_header(
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
template <typename Reader>
|
||||||
|
const spf_header* ifcopenshell::instance_streamer<Reader>::header() const {
|
||||||
|
return owner_ ? &owner_->header() : owned_header_.get();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
spf_header& ifcopenshell::instance_streamer<Reader>::ensure_header() {
|
spf_header& ifcopenshell::instance_streamer<Reader>::ensure_header() {
|
||||||
if (header_) {
|
|
||||||
return *header_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (owner_ != nullptr) {
|
if (owner_ != nullptr) {
|
||||||
header_ = &owner_->header();
|
return owner_->header();
|
||||||
header_->owner_file(owner_);
|
|
||||||
} else {
|
|
||||||
owned_header_ = std::make_unique<spf_header>(owner_, &logger_.get());
|
|
||||||
header_ = owned_header_.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *header_;
|
if (!owned_header_) {
|
||||||
|
owned_header_ = std::make_unique<spf_header>(owner_, &logger_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *owned_header_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
@@ -2012,7 +2017,6 @@ void ifcopenshell::instance_streamer<Reader>::push_page(const std::string& page)
|
|||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(ifcopenshell::file* f, ::logger& log)
|
ifcopenshell::instance_streamer<Reader>::instance_streamer(ifcopenshell::file* f, ::logger& log)
|
||||||
: stream_(nullptr)
|
: stream_(nullptr)
|
||||||
, header_(nullptr)
|
|
||||||
, owner_(f)
|
, owner_(f)
|
||||||
, token_stream_(3, token{})
|
, token_stream_(3, token{})
|
||||||
, schema_(nullptr)
|
, schema_(nullptr)
|
||||||
@@ -2038,7 +2042,6 @@ ifcopenshell::instance_streamer<Reader>::instance_streamer(ifcopenshell::file* f
|
|||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(const std::string& fn, bool mmap, ifcopenshell::file* f, ::logger& log)
|
ifcopenshell::instance_streamer<Reader>::instance_streamer(const std::string& fn, bool mmap, ifcopenshell::file* f, ::logger& log)
|
||||||
: stream_(nullptr)
|
: stream_(nullptr)
|
||||||
, header_(nullptr)
|
|
||||||
, owner_(f)
|
, owner_(f)
|
||||||
, token_stream_(3, token{})
|
, token_stream_(3, token{})
|
||||||
, schema_(nullptr)
|
, schema_(nullptr)
|
||||||
@@ -2067,7 +2070,6 @@ ifcopenshell::instance_streamer<Reader>::instance_streamer(const std::string& fn
|
|||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(void* data, int length, ifcopenshell::file* f, ::logger& log)
|
ifcopenshell::instance_streamer<Reader>::instance_streamer(void* data, int length, ifcopenshell::file* f, ::logger& log)
|
||||||
: stream_(nullptr)
|
: stream_(nullptr)
|
||||||
, header_(nullptr)
|
|
||||||
, owner_(f)
|
, owner_(f)
|
||||||
, token_stream_(3, token{})
|
, token_stream_(3, token{})
|
||||||
, schema_(nullptr)
|
, schema_(nullptr)
|
||||||
@@ -2092,7 +2094,6 @@ ifcopenshell::instance_streamer<Reader>::instance_streamer(void* data, int lengt
|
|||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(Reader* stream, ifcopenshell::file* f, ::logger& log)
|
ifcopenshell::instance_streamer<Reader>::instance_streamer(Reader* stream, ifcopenshell::file* f, ::logger& log)
|
||||||
: stream_(stream)
|
: stream_(stream)
|
||||||
, header_(nullptr)
|
|
||||||
, owner_(f)
|
, owner_(f)
|
||||||
, token_stream_(3, token{})
|
, token_stream_(3, token{})
|
||||||
, schema_(nullptr)
|
, schema_(nullptr)
|
||||||
@@ -2120,33 +2121,34 @@ template <typename Reader>
|
|||||||
std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointer_type>> ifcopenshell::instance_streamer<Reader>::read_instance() {
|
std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointer_type>> ifcopenshell::instance_streamer<Reader>::read_instance() {
|
||||||
std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointer_type>> return_value;
|
std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointer_type>> return_value;
|
||||||
|
|
||||||
if (yield_header_instances_ && header_ && yielded_header_instances_ < 3) {
|
const auto* header = this->header();
|
||||||
|
if (yield_header_instances_ && header && yielded_header_instances_ < 3) {
|
||||||
if (yielded_header_instances_ == 0) {
|
if (yielded_header_instances_ == 0) {
|
||||||
return_value.emplace(
|
return_value.emplace(
|
||||||
0,
|
0,
|
||||||
&header_->file_description().declaration(),
|
&header->file_description().declaration(),
|
||||||
#ifdef IFOPSH_SAFE_INSTANCE
|
#ifdef IFOPSH_SAFE_INSTANCE
|
||||||
header_->file_description().data_weak().lock());
|
header->file_description().data_weak().lock());
|
||||||
#else
|
#else
|
||||||
header_->file_description().data_weak());
|
header->file_description().data_weak());
|
||||||
#endif
|
#endif
|
||||||
} else if (yielded_header_instances_ == 1) {
|
} else if (yielded_header_instances_ == 1) {
|
||||||
return_value.emplace(
|
return_value.emplace(
|
||||||
0,
|
0,
|
||||||
&header_->file_name().declaration(),
|
&header->file_name().declaration(),
|
||||||
#ifdef IFOPSH_SAFE_INSTANCE
|
#ifdef IFOPSH_SAFE_INSTANCE
|
||||||
header_->file_name().data_weak().lock());
|
header->file_name().data_weak().lock());
|
||||||
#else
|
#else
|
||||||
header_->file_name().data_weak());
|
header->file_name().data_weak());
|
||||||
#endif
|
#endif
|
||||||
} else if (yielded_header_instances_ == 2) {
|
} else if (yielded_header_instances_ == 2) {
|
||||||
return_value.emplace(
|
return_value.emplace(
|
||||||
0,
|
0,
|
||||||
&header_->file_schema().declaration(),
|
&header->file_schema().declaration(),
|
||||||
#ifdef IFOPSH_SAFE_INSTANCE
|
#ifdef IFOPSH_SAFE_INSTANCE
|
||||||
header_->file_schema().data_weak().lock());
|
header->file_schema().data_weak().lock());
|
||||||
#else
|
#else
|
||||||
header_->file_schema().data_weak());
|
header->file_schema().data_weak());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
yielded_header_instances_ += 1;
|
yielded_header_instances_ += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user