mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
After-merge clean-ups
This commit is contained in:
@@ -501,7 +501,7 @@ std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignme
|
||||
} else if (cant) {
|
||||
result = mapAlignmentCantSegment(file, cant);
|
||||
} else {
|
||||
logger::error(std::string("Unexpected IfcAlignmentSegment subtype encountered"));
|
||||
::logger::root().error(std::string("Unexpected IfcAlignmentSegment subtype encountered"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -762,9 +762,9 @@ std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignme
|
||||
|
||||
result.first = curve_segment;
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_VIENNESEBEND) {
|
||||
logger::warning(std::string("mapping of AlignmentHorizontalSegmentType VIENNESEBEND not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentHorizontalSegmentType VIENNESEBEND not supported"));
|
||||
} else {
|
||||
logger::error(std::string("unexpected AlignmentHorizontalSegmentType encountered"));
|
||||
::logger::root().error(std::string("unexpected AlignmentHorizontalSegmentType encountered"));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -830,7 +830,7 @@ std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignme
|
||||
|
||||
result.first = curve_segment;
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CLOTHOID) {
|
||||
logger::warning(std::string("mapping of AlignmentVerticalSegmentType CLOTHOID not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentVerticalSegmentType CLOTHOID not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CIRCULARARC) {
|
||||
auto start_angle = atan(start_gradient);
|
||||
auto end_angle = atan(end_gradient);
|
||||
@@ -856,7 +856,7 @@ std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignme
|
||||
|
||||
result.first = curve_segment;
|
||||
} else {
|
||||
logger::error(std::string("unexpected AlignmentVerticalSegmentType encountered"));
|
||||
::logger::root().error(std::string("unexpected AlignmentVerticalSegmentType encountered"));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -866,21 +866,21 @@ std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignme
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> result;
|
||||
auto type = segment.PredefinedType();
|
||||
if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_BLOSSCURVE) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType BLOSSCURVE not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType BLOSSCURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_CONSTANTCANT) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType CONSTANTCANT not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType CONSTANTCANT not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_COSINECURVE) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType COSINECURVE not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType COSINECURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_HELMERTCURVE) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType HELMERTCURVE not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType HELMERTCURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_LINEARTRANSITION) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType LINEARTRANSTION not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType LINEARTRANSTION not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_SINECURVE) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType SINECURVE not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType SINECURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_VIENNESEBEND) {
|
||||
logger::warning(std::string("mapping of AlignmentCantSegmentType VIENNESEBEND not supported"));
|
||||
::logger::root().warning(std::string("mapping of AlignmentCantSegmentType VIENNESEBEND not supported"));
|
||||
} else {
|
||||
logger::error(std::string("unexpected AlignmentCantSegmentType encountered"));
|
||||
::logger::root().error(std::string("unexpected AlignmentCantSegmentType encountered"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ IFC_SCHEMA_API Ifc4x3_add2::IfcAlignment addAlignment(hierarchy_helper<Ifc4x3_ad
|
||||
// Maps horizontal alignment business logic to geometry.
|
||||
// Bloss curves have two geometry elements for one horizontal alignment segment. That is the reason for returning a pair.
|
||||
// Typically the first element of the pair will have the geometry and the second element will be nullptr
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentSegment& segment, Logger& logger = Logger::Root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentHorizontalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentHorizontalSegment& segment, Logger& logger = Logger::Root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentVerticalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentVerticalSegment& segment, Logger& logger = Logger::Root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentCantSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentCantSegment& segment, Logger& logger = Logger::Root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentSegment& segment, logger& logger = ::logger::root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentHorizontalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentHorizontalSegment& segment, logger& logger = ::logger::root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentVerticalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentVerticalSegment& segment, logger& logger = ::logger::root());
|
||||
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentCantSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentCantSegment& segment, logger& logger = ::logger::root());
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -139,7 +139,8 @@ inline void append_ascii(std::u32string& builder, const char* bytes, size_t coun
|
||||
} // namespace SWAR
|
||||
|
||||
template <typename Reader>
|
||||
character_decoder<Reader>::character_decoder(Reader* stream) {
|
||||
character_decoder<Reader>::character_decoder(Reader* stream, logger& logger)
|
||||
: logger_(logger) {
|
||||
stream_ = stream;
|
||||
codepage_ = 0;
|
||||
builder_.reserve(1024);
|
||||
@@ -151,7 +152,7 @@ character_decoder<Reader>::~character_decoder() {
|
||||
|
||||
namespace {
|
||||
template <typename Reader>
|
||||
std::string read_string(std::u32string& builder_, Reader& stream_, typename ifcopenshell::character_decoder<Reader>::ConversionMode mode, char substitution_character) {
|
||||
std::string read_string(std::u32string& builder_, Reader& stream_, logger& logger_, typename ifcopenshell::character_decoder<Reader>::ConversionMode mode, char substitution_character) {
|
||||
unsigned int parse_state = 0;
|
||||
builder_.clear();
|
||||
// builder_.push_back('\'');
|
||||
@@ -224,7 +225,7 @@ namespace {
|
||||
parse_state += PAGE;
|
||||
} else if (IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state)) {
|
||||
if (IS_LOWERCASE_HEX(current_char)) {
|
||||
logger.Warning("SYN", 2, "Lowercase hexadecimal character '" + std::string(1, current_char) +
|
||||
logger_.warning("SYN", 2, "Lowercase hexadecimal character '" + std::string(1, current_char) +
|
||||
"' found at offset " + std::to_string(stream_.tell()) +
|
||||
". It is recommended to use uppercase for hexadecimal.");
|
||||
}
|
||||
@@ -299,14 +300,14 @@ namespace {
|
||||
|
||||
template <typename Reader>
|
||||
character_decoder<Reader>::operator std::string() {
|
||||
return read_string(builder_, *stream_, mode, substitution_character);
|
||||
return read_string(builder_, *stream_, logger_, mode, substitution_character);
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
std::string character_decoder<Reader>::get(size_t& ptr) {
|
||||
auto local_stream = *stream_;
|
||||
local_stream.seek(ptr);
|
||||
auto s = read_string(builder_, local_stream, mode, substitution_character);
|
||||
auto s = read_string(builder_, local_stream, logger_, mode, substitution_character);
|
||||
ptr = local_stream.tell();
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ template <typename Reader>
|
||||
class IFC_PARSE_API character_decoder {
|
||||
private:
|
||||
Reader* stream_;
|
||||
Logger& logger_;
|
||||
logger& logger_;
|
||||
int codepage_;
|
||||
std::u32string builder_;
|
||||
|
||||
@@ -57,7 +57,7 @@ class IFC_PARSE_API character_decoder {
|
||||
inline static ConversionMode mode = UTF8;
|
||||
inline static char substitution_character = '_';
|
||||
|
||||
character_decoder(Reader* stream, Logger& logger = Logger::Root());
|
||||
character_decoder(Reader* stream, logger& logger = ::logger::root());
|
||||
~character_decoder();
|
||||
// Gets a decoded string representation at the token stream
|
||||
// read pointer and advances the underlying token stream.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "instance_data.h"
|
||||
#include "express.h"
|
||||
#include "exception.h"
|
||||
#include "file.h"
|
||||
|
||||
// @todo is size() still needed?
|
||||
@@ -37,14 +38,14 @@ namespace {
|
||||
try {
|
||||
return array_.storage_ptr->get<T>(index_);
|
||||
} catch (const impl::storage_type_mismatch& e) {
|
||||
throw IfcParse::IfcException(
|
||||
throw ifcopenshell::exception(
|
||||
// entity_or_type not passed, but in v0.9 this is beginning to make sense
|
||||
(entity_or_type
|
||||
? std::string("On instance #" + std::to_string(instance_name_) + " of " + entity_or_type->name() + ": ")
|
||||
: std::string("")) +
|
||||
"Requested type <" + e.requested() + "> does not match actual type <" + e.actual() + "> at index " + std::to_string(index_));
|
||||
} catch (const std::out_of_range& e) {
|
||||
throw IfcParse::IfcException(
|
||||
throw ifcopenshell::exception(
|
||||
(entity_or_type
|
||||
? std::string("On instance #" + std::to_string(instance_name_) + " of " + entity_or_type->name() + ": ")
|
||||
: std::string("")) +
|
||||
@@ -70,7 +71,7 @@ namespace {
|
||||
static_assert(
|
||||
std::is_same_v<T, enumeration_reference> ||
|
||||
std::is_same_v<std::remove_cv_t<T>, express::Base>,
|
||||
"RocksDB deserialization must be specialized for this enumeration_reference and IfcBaseClass*"
|
||||
"RocksDB deserialization must be specialized for this enumeration_reference and express::Base"
|
||||
);
|
||||
}
|
||||
return val;
|
||||
@@ -580,4 +581,4 @@ T* instance_data::get_storage_of_type() const {
|
||||
template IFC_PARSE_API ifcopenshell::impl::in_memory_file_storage* instance_data::get_storage_of_type<ifcopenshell::impl::in_memory_file_storage>() const;
|
||||
template IFC_PARSE_API ifcopenshell::impl::rocks_db_file_storage* instance_data::get_storage_of_type<ifcopenshell::impl::rocks_db_file_storage>() const;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+13
-13
@@ -103,7 +103,7 @@ private:
|
||||
const ifcopenshell::schema_definition* schema_;
|
||||
ifcopenshell::impl::in_memory_file_storage storage_;
|
||||
ifcopenshell::file_open_status good_ = ifcopenshell::file_open_status::SUCCESS;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
std::reference_wrapper<::logger> logger_;
|
||||
int progress_;
|
||||
ifcopenshell::unresolved_references references_to_resolve_;
|
||||
int yielded_header_instances_ = 0;
|
||||
@@ -157,13 +157,13 @@ private:
|
||||
|
||||
void push_page(const std::string& page_data);
|
||||
|
||||
instance_streamer(ifcopenshell::file* owner_file = nullptr, Logger& logger = Logger::Root());
|
||||
instance_streamer(ifcopenshell::file* owner_file = nullptr, ::logger& logger = ::logger::root());
|
||||
|
||||
instance_streamer(const std::string& path, bool use_mmap = false, ifcopenshell::file* owner_file = nullptr, Logger& logger = Logger::Root());
|
||||
instance_streamer(const std::string& path, bool use_mmap = false, ifcopenshell::file* owner_file = nullptr, ::logger& logger = ::logger::root());
|
||||
|
||||
instance_streamer(void* data, int data_size, ifcopenshell::file* owner_file = nullptr, Logger& logger = Logger::Root());
|
||||
instance_streamer(void* data, int data_size, ifcopenshell::file* owner_file = nullptr, ::logger& logger = ::logger::root());
|
||||
|
||||
instance_streamer(Reader* stream, ifcopenshell::file* owner_file = nullptr, Logger& logger = Logger::Root());
|
||||
instance_streamer(Reader* stream, ifcopenshell::file* owner_file = nullptr, ::logger& logger = ::logger::root());
|
||||
|
||||
void bypass_types(const std::set<std::string>& type_names);
|
||||
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
|
||||
private:
|
||||
file_open_status good_ = file_open_status::SUCCESS;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
std::reference_wrapper<::logger> logger_;
|
||||
|
||||
const ifcopenshell::schema_definition* schema_;
|
||||
const ifcopenshell::declaration* ifcroot_type_;
|
||||
@@ -242,7 +242,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="path">UTF-8 file path to an IFC-SPF file</param>
|
||||
/// <param name="mmap">Whether to use memory-mapped I/O</param>
|
||||
file(const std::string& path, bool use_mmap, Logger& logger = Logger::Root());
|
||||
file(const std::string& path, bool use_mmap, ::logger& logger = ::logger::root());
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Constructs an file object from a file path, supports IFC-SPF and the IfcOpenShell-specific RocksDB format.
|
||||
@@ -250,17 +250,17 @@ public:
|
||||
/// <param name="path">UTF-8 file path to an IFC-SPF file or RocksDB database directory</param>
|
||||
/// <param name="ty">File type of the path</param>
|
||||
/// <param name="readonly">Whether to open in read-only mode, only supported on RocksDB databases</param>
|
||||
file(const std::string& path, filetype type = FT_AUTODETECT, bool read_only = false, Logger& logger = Logger::Root());
|
||||
file(const std::string& path, filetype type = FT_AUTODETECT, bool read_only = false, ::logger& logger = ::logger::root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an file object from a stream containing IFC-SPF data.
|
||||
/// </summary>
|
||||
file(std::istream& stream, int data_size, Logger& logger = Logger::Root());
|
||||
file(std::istream& stream, int data_size, ::logger& logger = ::logger::root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an file object from a memory buffer containing IFC-SPF data.
|
||||
/// </summary>
|
||||
file(void* data, int data_size, Logger& logger = Logger::Root());
|
||||
file(void* data, int data_size, ::logger& logger = ::logger::root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an file object with the specified schema, file type, and file path.
|
||||
@@ -269,12 +269,12 @@ public:
|
||||
/// <param name="schema">Pointer to the schema definition to use. Defaults to the IFC4 schema if not specified.</param>
|
||||
/// <param name="ty">The file type to use for the file. Defaults to FT_AUTODETECT.</param>
|
||||
/// <param name="path">The file system path to the IFC file. Defaults to an empty string.</param>
|
||||
file(const ifcopenshell::schema_definition* schema = ifcopenshell::schema_by_name("IFC4"), filetype type = FT_AUTODETECT, const std::string& path = "", Logger& logger = Logger::Root());
|
||||
file(const ifcopenshell::schema_definition* schema = ifcopenshell::schema_by_name("IFC4"), filetype type = FT_AUTODETECT, const std::string& path = "", ::logger& logger = ::logger::root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an unitialized file object. Call initialize() later on. Allows to specify which types to bypass during load.
|
||||
/// </summary>
|
||||
file(const uninitialized_tag& tag, Logger& logger = Logger::Root());
|
||||
file(const uninitialized_tag& tag, ::logger& logger = ::logger::root());
|
||||
|
||||
bool initialize(const std::string& path, filetype type = FT_AUTODETECT, bool read_only = false);
|
||||
#ifdef USE_MMAP
|
||||
@@ -288,7 +288,7 @@ public:
|
||||
~file();
|
||||
|
||||
ifcopenshell::file_open_status good() const { return good_; }
|
||||
Logger& logger() const { return logger_.get(); }
|
||||
::logger& logger() const { return logger_.get(); }
|
||||
|
||||
/// Returns the first entity in the range of instances contained in the model,
|
||||
/// in arbitrary order
|
||||
|
||||
@@ -94,7 +94,7 @@ void expand(const std::string& s, std::vector<unsigned char>& v) {
|
||||
static boost::uuids::basic_random_generator<boost::mt19937> gen;
|
||||
#endif
|
||||
|
||||
ifcopenshell::global_id::global_id(Logger& logger) {
|
||||
ifcopenshell::global_id::global_id(logger& logger) {
|
||||
uuid_data_ = gen();
|
||||
std::vector<unsigned char> v(uuid_data_.size());
|
||||
std::copy(uuid_data_.begin(), uuid_data_.end(), v.begin());
|
||||
@@ -111,12 +111,12 @@ ifcopenshell::global_id::global_id(Logger& logger) {
|
||||
boost::uuids::uuid test_uuid;
|
||||
std::copy(test_vector.begin(), test_vector.end(), test_uuid.begin());
|
||||
if (uuid_data_ != test_uuid) {
|
||||
logger.Message(Logger::LOG_ERROR, "SYS", 34, "Internal error generating GlobalId");
|
||||
logger.message(::logger::LOG_ERROR, "SYS", 34, "Internal error generating GlobalId");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ifcopenshell::global_id::global_id(const std::string& string, Logger& logger)
|
||||
ifcopenshell::global_id::global_id(const std::string& string, logger& logger)
|
||||
: string_data_(string) {
|
||||
std::vector<unsigned char> result;
|
||||
expand(string_data_, result);
|
||||
@@ -130,7 +130,7 @@ ifcopenshell::global_id::global_id(const std::string& string, Logger& logger)
|
||||
#ifndef NDEBUG
|
||||
const std::string test_string = compress(&uuid_data_.data[0]);
|
||||
if (string_data_ != test_string) {
|
||||
logger.Message(Logger::LOG_ERROR, "SYS", 35, "Internal error generating GlobalId");
|
||||
logger.message(::logger::LOG_ERROR, "SYS", 35, "Internal error generating GlobalId");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define IFCGLOBALID_H
|
||||
|
||||
#include "ifc_parse_api.h"
|
||||
#include "IfcLogger.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <string>
|
||||
@@ -37,8 +37,8 @@ class IFC_PARSE_API global_id {
|
||||
|
||||
public:
|
||||
static const unsigned int length = 22;
|
||||
global_id(Logger& logger = Logger::Root());
|
||||
global_id(const std::string& value, Logger& logger = Logger::Root());
|
||||
global_id(logger& logger = ::logger::root());
|
||||
global_id(const std::string& value, logger& logger = ::logger::root());
|
||||
operator const std::string&() const;
|
||||
operator const boost::uuids::uuid&() const;
|
||||
const std::string& formatted() const;
|
||||
|
||||
@@ -180,9 +180,9 @@ class IFC_SCHEMA_API hierarchy_helper : public ifcopenshell::file {
|
||||
break;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
logger::error(e);
|
||||
::logger::root().error(e);
|
||||
} catch (...) {
|
||||
logger::error("Unknown error in addRelatedObject()");
|
||||
::logger::root().error("Unknown error in addRelatedObject()");
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
|
||||
@@ -174,7 +174,7 @@ void hierarchy_helper<Schema>::relatePlacements(typename Schema::IfcProduct pare
|
||||
if (local_place != parent.ObjectPlacement()) {
|
||||
local_place.setPlacementRelTo(parent.ObjectPlacement());
|
||||
} else {
|
||||
logger::notice("Placement cannot be relative to self");
|
||||
::logger::root().notice("Placement cannot be relative to self");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,12 +75,12 @@ class IFC_PARSE_API empty_aggregate_of_aggregate_t {};
|
||||
|
||||
namespace impl {
|
||||
template <>
|
||||
struct VariantTypeName<Blank> {
|
||||
struct VariantTypeName<blank> {
|
||||
static std::string get() { return "null"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantTypeName<Derived> {
|
||||
struct VariantTypeName<derived> {
|
||||
static std::string get() { return "derived"; }
|
||||
};
|
||||
|
||||
@@ -115,12 +115,12 @@ namespace impl {
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantTypeName<EnumerationReference> {
|
||||
struct VariantTypeName<enumeration_reference> {
|
||||
static std::string get() { return "enumeration"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantTypeName<IfcUtil::IfcBaseClass*> {
|
||||
struct VariantTypeName<express::Base> {
|
||||
static std::string get() { return "instance"; }
|
||||
};
|
||||
|
||||
@@ -134,20 +134,10 @@ namespace impl {
|
||||
static std::string get() { return "aggregate of " + VariantTypeName<T>::get(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantTypeName<aggregate_of_instance::ptr> {
|
||||
static std::string get() { return "aggregate of instance"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantTypeName<empty_aggregate_of_aggregate_t> {
|
||||
static std::string get() { return "aggregate of aggregate"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VariantTypeName<aggregate_of_aggregate_of_instance::ptr> {
|
||||
static std::string get() { return "aggregate of aggregate of instance"; }
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
|
||||
+90
-73
@@ -23,8 +23,6 @@
|
||||
#include "instance_data.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/version.hpp>
|
||||
@@ -33,9 +31,6 @@
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
static thread_local express::Base current_product_;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -71,13 +66,23 @@ std::string format_code(const char (&code_prefix)[4], uint16_t code_number) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void plain_text_message(T& out, const express::Base& current_product, Logger::Severity type, const std::string& code, const std::string& message, const express::Base& instance) {
|
||||
void write_code(T& out, const std::string& code) {
|
||||
if (!code.empty()) {
|
||||
out << "[" << code.c_str() << "] ";
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void plain_text_message(T& out, const express::Base& current_product, logger::Severity type, const std::string& code, const std::string& message, const express::Base& instance) {
|
||||
out << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
|
||||
out << "[" << code.c_str() << "] ";
|
||||
out << "[" << get_time(type <= Logger::LOG_PERF).c_str() << "] ";
|
||||
write_code(out, code);
|
||||
out << "[" << get_time(type <= logger::LOG_PERF).c_str() << "] ";
|
||||
if (current_product) {
|
||||
std::string global_id = current_product.as<express::Entity>().get("GlobalId");
|
||||
out << "{" << global_id.c_str() << "} ";
|
||||
express::Entity entity = current_product.as<express::Entity>();
|
||||
if (entity) {
|
||||
std::string global_id = entity.get("GlobalId");
|
||||
out << "{" << global_id.c_str() << "} ";
|
||||
}
|
||||
}
|
||||
out << message.c_str() << std::endl;
|
||||
if (instance) {
|
||||
@@ -99,10 +104,9 @@ std::basic_string<T> string_as(const std::string& string) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void json_message(T& out, const express::Base* current_product, Logger::Severity type, const std::string& code, const std::string& message, const express::Base& instance) {
|
||||
void json_message(T& out, const express::Base& current_product, logger::Severity type, const std::string& code, const std::string& message, const express::Base& instance) {
|
||||
boost::property_tree::basic_ptree<std::basic_string<typename T::char_type>, std::basic_string<typename T::char_type>> property_tree;
|
||||
|
||||
// @todo this is crazy
|
||||
static const typename T::char_type time_string[] = {'t', 'i', 'm', 'e', 0};
|
||||
static const typename T::char_type level_string[] = {'l', 'e', 'v', 'e', 'l', 0};
|
||||
static const typename T::char_type code_string[] = {'c', 'o', 'd', 'e', 0};
|
||||
@@ -111,7 +115,9 @@ void json_message(T& out, const express::Base* current_product, Logger::Severity
|
||||
static const typename T::char_type instance_string[] = {'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 0};
|
||||
|
||||
property_tree.put(level_string, severity_strings<typename T::char_type>::value[type]);
|
||||
property_tree.put(code_string, string_as<typename T::char_type>(code));
|
||||
if (!code.empty()) {
|
||||
property_tree.put(code_string, string_as<typename T::char_type>(code));
|
||||
}
|
||||
if (current_product) {
|
||||
std::ostringstream oss;
|
||||
current_product.to_string(oss);
|
||||
@@ -128,68 +134,63 @@ void json_message(T& out, const express::Base* current_product, Logger::Severity
|
||||
|
||||
boost::property_tree::write_json(out, property_tree, false);
|
||||
|
||||
// Append a newline after the JSON object if the Boost version is 1.86 or higher
|
||||
#if BOOST_VERSION >= 108600
|
||||
out << '\n';
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
log_message::log_message(
|
||||
int severity,
|
||||
const char (&code_prefix)[4],
|
||||
uint16_t code_number,
|
||||
const std::string& code,
|
||||
const std::string& timestamp,
|
||||
const std::string& message,
|
||||
const IfcUtil::IfcBaseInterface* inst,
|
||||
const IfcUtil::IfcBaseClass* current_product)
|
||||
const express::Base& instance,
|
||||
const express::Base& current_product)
|
||||
: severity(severity)
|
||||
, timestamp(timestamp)
|
||||
, message(message)
|
||||
{
|
||||
snprintf(code, 7, "%s%03u", code_prefix, code_number);
|
||||
if (inst) {
|
||||
snprintf(this->code, sizeof(this->code), "%s", code.c_str());
|
||||
if (instance) {
|
||||
std::ostringstream oss;
|
||||
inst->as<IfcUtil::IfcBaseClass>()->toString(oss);
|
||||
instance = oss.str();
|
||||
instance.to_string(oss);
|
||||
this->instance = oss.str();
|
||||
}
|
||||
if (current_product) {
|
||||
std::ostringstream oss;
|
||||
current_product->toString(oss);
|
||||
current_product.to_string(oss);
|
||||
product = oss.str();
|
||||
}
|
||||
}
|
||||
|
||||
Logger& Logger::Root() {
|
||||
static Logger logger;
|
||||
return logger;
|
||||
logger& logger::root() {
|
||||
static logger root_logger;
|
||||
return root_logger;
|
||||
}
|
||||
|
||||
const express::Base& Logger::current_product() const {
|
||||
const express::Base& logger::current_product() const {
|
||||
return current_product_;
|
||||
}
|
||||
|
||||
void logger::set_product(std::optional<const express::Base> product) {
|
||||
if (verbosity_ <= LOG_DEBUG && product) {
|
||||
message(LOG_DEBUG, "Begin processing", *product);
|
||||
}
|
||||
void logger::current_product(const express::Base& product) {
|
||||
current_product_ = product;
|
||||
}
|
||||
|
||||
void Logger::SetProduct(boost::optional<const IfcUtil::IfcBaseClass*> product) {
|
||||
void logger::set_product(std::optional<express::Base> product) {
|
||||
if (verbosity_ <= LOG_DEBUG && product) {
|
||||
Message(LOG_DEBUG, "SYS", 3, "Begin processing", *product);
|
||||
message(LOG_DEBUG, "SYS", 3, "Begin processing", *product);
|
||||
}
|
||||
if (!product && print_perf_stats_on_element_) {
|
||||
print_performance_stats();
|
||||
performance_statistics_.clear();
|
||||
}
|
||||
current_product_ = product.value_or(express::Base{});
|
||||
current_product(product.value_or(express::Base{}));
|
||||
}
|
||||
|
||||
void logger::set_output(std::ostream* stream1, std::ostream* stream2) {
|
||||
wlog1_ = wlog2_ = 0;
|
||||
wlog1_ = wlog2_ = nullptr;
|
||||
log1_ = stream1;
|
||||
log2_ = stream2;
|
||||
if (log2_ == nullptr) {
|
||||
@@ -198,21 +199,33 @@ void logger::set_output(std::ostream* stream1, std::ostream* stream2) {
|
||||
}
|
||||
|
||||
void logger::set_output(std::wostream* stream1, std::wostream* stream2) {
|
||||
log1_ = log2_ = 0;
|
||||
log1_ = log2_ = nullptr;
|
||||
wlog1_ = stream1;
|
||||
wlog2_ = stream2;
|
||||
if (wlog2_ == nullptr) {
|
||||
log2_ = &log_stream_;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Message(Logger::Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const express::Base& instance) {
|
||||
void logger::message(logger::Severity type, const std::string& text, const express::Base& instance) {
|
||||
message(type, std::string(), text, instance);
|
||||
}
|
||||
|
||||
void logger::message(logger::Severity type, const std::exception& exception, const express::Base& instance) {
|
||||
message(type, std::string(exception.what()), instance);
|
||||
}
|
||||
|
||||
void logger::message(logger::Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::string& text, const express::Base& instance) {
|
||||
message(type, format_code(code_prefix, code_number), text, instance);
|
||||
}
|
||||
|
||||
void logger::message(logger::Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const express::Base& instance) {
|
||||
message(type, code_prefix, code_number, std::string(exception.what()), instance);
|
||||
}
|
||||
|
||||
void logger::message(logger::Severity type, const std::string& code, const std::string& text, const express::Base& instance) {
|
||||
if (type < verbosity_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
const std::string code = format_code(code_prefix, code_number);
|
||||
|
||||
if (type == LOG_PERF) {
|
||||
if (!first_timepoint_) {
|
||||
@@ -232,28 +245,24 @@ void Logger::Message(Logger::Severity type, const char (&code_prefix)[4], uint16
|
||||
}
|
||||
|
||||
if (format_ == FMT_INMEMORY) {
|
||||
log_messages_.emplace_back(type, code_prefix, code_number, get_time(), message, instance, current_product());
|
||||
log_messages_.emplace_back(type, code, get_time(), text, instance, current_product());
|
||||
} else if (((log2_ != nullptr) || (wlog2_ != nullptr))) {
|
||||
if (format_ == FMT_PLAIN) {
|
||||
if (log2_ != nullptr) {
|
||||
plain_text_message(*log2_, current_product(), type, code, message, instance);
|
||||
plain_text_message(*log2_, current_product(), type, code, text, instance);
|
||||
} else if (wlog2_ != nullptr) {
|
||||
plain_text_message(*wlog2_, current_product(), type, code, message, instance);
|
||||
plain_text_message(*wlog2_, current_product(), type, code, text, instance);
|
||||
}
|
||||
} else if (format_ == FMT_JSON) {
|
||||
if (log2_ != nullptr) {
|
||||
json_message(*log2_, current_product(), type, code, message, instance);
|
||||
json_message(*log2_, current_product(), type, code, text, instance);
|
||||
} else if (wlog2_ != nullptr) {
|
||||
json_message(*wlog2_, current_product(), type, code, message, instance);
|
||||
json_message(*wlog2_, current_product(), type, code, text, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Message(Logger::Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const express::Base&) {
|
||||
Message(type, code_prefix, code_number, std::string(exception.what()), instance);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void write_status(T& log1, const std::string& text, bool new_line) {
|
||||
log1 << text.c_str();
|
||||
@@ -277,36 +286,32 @@ void logger::progress_bar(int progress) {
|
||||
}
|
||||
|
||||
std::string logger::get_log() {
|
||||
return log_stream_.str();
|
||||
}
|
||||
|
||||
std::string Logger::GetLog() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return log_stream_.str();
|
||||
}
|
||||
|
||||
void Logger::ClearLog() {
|
||||
void logger::clear() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
log_stream_.str(std::string());
|
||||
log_stream_.clear();
|
||||
log_messages_.clear();
|
||||
}
|
||||
|
||||
void Logger::Append(Logger& logger) {
|
||||
if (&logger == this) {
|
||||
void logger::append(logger& other) {
|
||||
if (&other == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock lock(mutex_, logger.mutex_);
|
||||
std::scoped_lock lock(mutex_, other.mutex_);
|
||||
|
||||
if (logger.max_severity_ > max_severity_) {
|
||||
max_severity_ = logger.max_severity_;
|
||||
if (other.max_severity_ > max_severity_) {
|
||||
max_severity_ = other.max_severity_;
|
||||
}
|
||||
|
||||
if (format_ == FMT_INMEMORY) {
|
||||
log_messages_.insert(log_messages_.end(), logger.log_messages_.begin(), logger.log_messages_.end());
|
||||
log_messages_.insert(log_messages_.end(), other.log_messages_.begin(), other.log_messages_.end());
|
||||
} else {
|
||||
const std::string log = logger.log_stream_.str();
|
||||
const std::string log = other.log_stream_.str();
|
||||
if (!log.empty()) {
|
||||
if (log2_ != nullptr) {
|
||||
*log2_ << log;
|
||||
@@ -318,9 +323,9 @@ void Logger::Append(Logger& logger) {
|
||||
}
|
||||
}
|
||||
|
||||
logger.log_stream_.str(std::string());
|
||||
logger.log_stream_.clear();
|
||||
logger.log_messages_.clear();
|
||||
other.log_stream_.str(std::string());
|
||||
other.log_stream_.clear();
|
||||
other.log_messages_.clear();
|
||||
}
|
||||
|
||||
void logger::print_performance_stats() {
|
||||
@@ -340,15 +345,27 @@ void logger::print_performance_stats() {
|
||||
}
|
||||
|
||||
for (auto& item : items) {
|
||||
auto message = item.second + std::string(max_size - item.second.size(), ' ') + ": " + std::to_string(item.first);
|
||||
Message(LOG_PERF, "SYS", 4, message);
|
||||
auto text = item.second + std::string(max_size - item.second.size(), ' ') + ": " + std::to_string(item.first);
|
||||
message(LOG_PERF, "SYS", 4, text);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Verbosity(Logger::Severity severity) { verbosity_ = severity; }
|
||||
Logger::Severity Logger::Verbosity() const { return verbosity_; }
|
||||
void logger::verbosity(logger::Severity severity) {
|
||||
verbosity_ = severity;
|
||||
}
|
||||
|
||||
Logger::Severity Logger::MaxSeverity() const { return max_severity_; }
|
||||
logger::Severity logger::verbosity() const {
|
||||
return verbosity_;
|
||||
}
|
||||
|
||||
void Logger::OutputFormat(Format format) { format_ = format; }
|
||||
Logger::Format Logger::OutputFormat() const { return format_; }
|
||||
logger::Severity logger::max_severity() const {
|
||||
return max_severity_;
|
||||
}
|
||||
|
||||
void logger::output_format(Format format) {
|
||||
format_ = format;
|
||||
}
|
||||
|
||||
logger::Format logger::output_format() const {
|
||||
return format_;
|
||||
}
|
||||
|
||||
+34
-31
@@ -23,12 +23,12 @@
|
||||
#include "ifc_parse_api.h"
|
||||
#include "express.h"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/scope_exit.hpp>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -41,12 +41,11 @@ class IFC_PARSE_API log_message {
|
||||
|
||||
log_message(
|
||||
int severity,
|
||||
const char (&code_prefix)[4],
|
||||
uint16_t code_number,
|
||||
const std::string& code,
|
||||
const std::string& timestamp,
|
||||
const std::string& message,
|
||||
const IfcUtil::IfcBaseInterface* inst = 0,
|
||||
const IfcUtil::IfcBaseClass* current_product = 0);
|
||||
const express::Base& instance = express::Base(),
|
||||
const express::Base& current_product = express::Base());
|
||||
};
|
||||
|
||||
class IFC_PARSE_API logger {
|
||||
@@ -68,8 +67,6 @@ class IFC_PARSE_API logger {
|
||||
private:
|
||||
std::vector<log_message> log_messages_;
|
||||
|
||||
// To both stream variants need to exist at runtime or should this be a
|
||||
// template argument of Logger or controlled using preprocessor directives?
|
||||
std::ostream* log1_ = nullptr;
|
||||
std::ostream* log2_ = nullptr;
|
||||
|
||||
@@ -77,7 +74,7 @@ class IFC_PARSE_API logger {
|
||||
std::wostream* wlog2_ = nullptr;
|
||||
|
||||
std::stringstream log_stream_;
|
||||
const IfcUtil::IfcBaseClass* current_product_ = nullptr;
|
||||
express::Base current_product_;
|
||||
|
||||
Severity verbosity_ = LOG_NOTICE;
|
||||
Format format_ = FMT_PLAIN;
|
||||
@@ -90,64 +87,70 @@ class IFC_PARSE_API logger {
|
||||
bool print_perf_stats_on_element_ = false;
|
||||
std::mutex mutex_;
|
||||
|
||||
const IfcUtil::IfcBaseClass* current_product() const;
|
||||
void current_product(const IfcUtil::IfcBaseClass* product);
|
||||
const express::Base& current_product() const;
|
||||
void current_product(const express::Base& product);
|
||||
void message(Severity type, const std::string& code, const std::string& message, const express::Base& instance);
|
||||
|
||||
public:
|
||||
logger() = default;
|
||||
logger(const logger&) = delete;
|
||||
logger& operator=(const logger&) = delete;
|
||||
|
||||
static logger& Root();
|
||||
static logger& root();
|
||||
|
||||
void set_product(std::optional<const IfcUtil::IfcBaseClass*> product);
|
||||
void set_product(std::optional<express::Base> product);
|
||||
void set_product(const express::Base& product) { set_product(std::optional<express::Base>(product)); }
|
||||
|
||||
/// Determines to what stream respectively progress and errors are logged
|
||||
void set_output(std::wostream* stream1, std::wostream* stream2);
|
||||
|
||||
/// Determines to what stream respectively progress and errors are logged
|
||||
void set_output(std::ostream* stream1, std::ostream* stream2);
|
||||
|
||||
/// Determines the types of log messages to get logged
|
||||
void verbosity(Severity severity);
|
||||
Severity verbosity() const;
|
||||
Severity max_severity() const;
|
||||
|
||||
/// Determines output format: plain text or sequence of JSON objects
|
||||
void output_format(Format format);
|
||||
Format output_format() const;
|
||||
|
||||
/// Log a message to the output stream
|
||||
void message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0);
|
||||
void message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0);
|
||||
void message(Severity type, const std::string& message, const express::Base& instance = express::Base());
|
||||
void message(Severity type, const std::exception& exception, const express::Base& instance = express::Base());
|
||||
void message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const express::Base& instance = express::Base());
|
||||
void message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const express::Base& instance = express::Base());
|
||||
|
||||
void notice(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, code_prefix, code_number, message, instance); }
|
||||
void warning(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, code_prefix, code_number, message, instance); }
|
||||
void error(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, code_prefix, code_number, message, instance); }
|
||||
void notice(const std::string& message, const express::Base& instance = express::Base()) { this->message(LOG_NOTICE, message, instance); }
|
||||
void warning(const std::string& message, const express::Base& instance = express::Base()) { this->message(LOG_WARNING, message, instance); }
|
||||
void error(const std::string& message, const express::Base& instance = express::Base()) { this->message(LOG_ERROR, message, instance); }
|
||||
|
||||
void notice(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, code_prefix, code_number, exception, instance); }
|
||||
void warning(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, code_prefix, code_number, exception, instance); }
|
||||
void error(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, code_prefix, code_number, exception, instance); }
|
||||
void notice(const std::exception& exception, const express::Base& instance = express::Base()) { message(LOG_NOTICE, exception, instance); }
|
||||
void warning(const std::exception& exception, const express::Base& instance = express::Base()) { message(LOG_WARNING, exception, instance); }
|
||||
void error(const std::exception& exception, const express::Base& instance = express::Base()) { message(LOG_ERROR, exception, instance); }
|
||||
|
||||
void notice(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const express::Base& instance = express::Base()) { this->message(LOG_NOTICE, code_prefix, code_number, message, instance); }
|
||||
void warning(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const express::Base& instance = express::Base()) { this->message(LOG_WARNING, code_prefix, code_number, message, instance); }
|
||||
void error(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const express::Base& instance = express::Base()) { this->message(LOG_ERROR, code_prefix, code_number, message, instance); }
|
||||
|
||||
void notice(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const express::Base& instance = express::Base()) { message(LOG_NOTICE, code_prefix, code_number, exception, instance); }
|
||||
void warning(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const express::Base& instance = express::Base()) { message(LOG_WARNING, code_prefix, code_number, exception, instance); }
|
||||
void error(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const express::Base& instance = express::Base()) { message(LOG_ERROR, code_prefix, code_number, exception, instance); }
|
||||
|
||||
void status(const std::string& message, bool new_line = true);
|
||||
|
||||
void progress_bar(int progress);
|
||||
std::string get_log();
|
||||
void clear();
|
||||
void append(Logger& logger);
|
||||
void append(logger& other);
|
||||
void print_performance_stats();
|
||||
void print_performance_stats(bool b) { print_perf_stats_on_element_ = b; }
|
||||
bool print_performance_stats() const { return print_perf_stats_on_element_; }
|
||||
void print_performance_stats_on_element(bool enabled) { print_perf_stats_on_element_ = enabled; }
|
||||
bool print_performance_stats_on_element() const { return print_perf_stats_on_element_; }
|
||||
|
||||
const std::vector<log_message>& log_messages() const { return log_messages_; }
|
||||
};
|
||||
|
||||
#define PERF(x) \
|
||||
\
|
||||
Logger::Root().Message(Logger::LOG_PERF, "SYS", 1, x); \
|
||||
::logger::root().message(::logger::LOG_PERF, x); \
|
||||
\
|
||||
BOOST_SCOPE_EXIT(void) { \
|
||||
Logger::Root().Message(Logger::LOG_PERF, "SYS", 2, "done " + std::string(x)); \
|
||||
::logger::root().message(::logger::LOG_PERF, "done " + std::string(x)); \
|
||||
} \
|
||||
BOOST_SCOPE_EXIT_END
|
||||
|
||||
|
||||
+109
-84
@@ -50,9 +50,11 @@
|
||||
using namespace ifcopenshell;
|
||||
|
||||
template <typename Reader>
|
||||
spf_lexer<Reader>::spf_lexer(Reader* stream_) {
|
||||
spf_lexer<Reader>::spf_lexer(Reader* stream_, ::logger& log)
|
||||
: decoder_(nullptr)
|
||||
, logger_(log) {
|
||||
stream = stream_;
|
||||
decoder_ = new character_decoder<Reader>(stream_);
|
||||
decoder_ = new character_decoder<Reader>(stream_, logger_);
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
@@ -602,20 +604,20 @@ void warn_attribute_count(
|
||||
std::optional<size_t> instance_name,
|
||||
size_t expected_size,
|
||||
size_t actual_size,
|
||||
::Logger& logger
|
||||
::logger& logger
|
||||
) {
|
||||
if (!declaration || expected_size == actual_size) {
|
||||
return;
|
||||
}
|
||||
if (declaration->schema() == &Header_section_schema::get_schema()) {
|
||||
logger.Warning("VAL", 15, "Expected " + std::to_string(expected_size) + " attribute values, found " + std::to_string(actual_size) + " for header entity " + declaration->name());
|
||||
logger.warning("VAL", 15, "Expected " + std::to_string(expected_size) + " attribute values, found " + std::to_string(actual_size) + " for header entity " + declaration->name());
|
||||
} else {
|
||||
logger.Warning("VAL", 16, "Expected " + std::to_string(expected_size) + " attribute values, found " + std::to_string(actual_size) + (instance_name ? std::string(" for instance #" + std::to_string(*instance_name)) : std::string("")));
|
||||
logger.warning("VAL", 16, "Expected " + std::to_string(expected_size) + " attribute values, found " + std::to_string(actual_size) + (instance_name ? std::string(" for instance #" + std::to_string(*instance_name)) : std::string("")));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
void dispatch_token_direct(ifcopenshell::token token, ifcopenshell::declaration* declaration, int attribute_index, Logger& logger, Fn&& fn) {
|
||||
void dispatch_token_direct(ifcopenshell::token token, ifcopenshell::declaration* declaration, int attribute_index, logger& logger, Fn&& fn) {
|
||||
if (token.is_binary()) {
|
||||
fn(token.as_binary());
|
||||
} else if (token.is_bool()) {
|
||||
@@ -628,10 +630,10 @@ void dispatch_token_direct(ifcopenshell::token token, ifcopenshell::declaration*
|
||||
try {
|
||||
fn(enumeration_reference(declaration->as_enumeration_type(), declaration->as_enumeration_type()->lookup_enum_offset(value)));
|
||||
} catch (ifcopenshell::exception&) {
|
||||
logger.Error("VAL", 12, "An enumeration literal '" + value + "' is not valid for type '" + declaration->name() + "' at offset " + std::to_string(token.start_pos));
|
||||
logger.error("VAL", 12, "An enumeration literal '" + value + "' is not valid for type '" + declaration->name() + "' at offset " + std::to_string(token.start_pos));
|
||||
}
|
||||
} else {
|
||||
logger.Error("VAL", 13, "An enumeration literal '" + value + "' is not expected at attribute index '" + std::to_string(attribute_index) + "' at offset " + std::to_string(token.start_pos));
|
||||
logger.error("VAL", 13, "An enumeration literal '" + value + "' is not expected at attribute index '" + std::to_string(attribute_index) + "' at offset " + std::to_string(token.start_pos));
|
||||
}
|
||||
} else if (token.is_int()) {
|
||||
fn(token.as_int());
|
||||
@@ -664,7 +666,10 @@ struct direct_aggregate {
|
||||
direct_aggregate_storage storage;
|
||||
size_t pending_empty_aggregates = 0;
|
||||
size_t values = 0;
|
||||
Logger& logger;
|
||||
::logger& logger_;
|
||||
|
||||
explicit direct_aggregate(::logger& logger)
|
||||
: logger_(logger) {}
|
||||
|
||||
template <typename T>
|
||||
void append(const T& value) {
|
||||
@@ -681,7 +686,7 @@ struct direct_aggregate {
|
||||
}
|
||||
}
|
||||
if (pending_empty_aggregates) {
|
||||
logger.Error("VAL", 14, "Inconsistent aggregate valuation while attempting to append " + std::string(typeid(T).name()) + " after an empty nested aggregate");
|
||||
logger_.error("VAL", 14, "Inconsistent aggregate valuation while attempting to append " + std::string(typeid(T).name()) + " after an empty nested aggregate");
|
||||
pending_empty_aggregates = 0;
|
||||
}
|
||||
if (storage.index() == 0) {
|
||||
@@ -692,7 +697,7 @@ struct direct_aggregate {
|
||||
append_promoted(value);
|
||||
}
|
||||
} else {
|
||||
logger.Error("UNS", 31, std::string("Aggregates of ") + typeid(T).name() + " are not supported in the IfcOpenShell parser");
|
||||
logger_.error("UNS", 31, std::string("Aggregates of ") + typeid(T).name() + " are not supported in the IfcOpenShell parser");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,7 +712,7 @@ struct direct_aggregate {
|
||||
} else if (storage.index() == 0) {
|
||||
++pending_empty_aggregates;
|
||||
} else {
|
||||
logger::error("Inconsistent aggregate valuation while attempting to append an empty nested aggregate");
|
||||
logger_.error("Inconsistent aggregate valuation while attempting to append an empty nested aggregate");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +795,7 @@ private:
|
||||
return std::string{};
|
||||
}
|
||||
}, storage);
|
||||
logger::error("Inconsistent aggregate valuation while attempting to append " + std::string(typeid(T).name()) + " to an aggregate of " + current);
|
||||
logger_.error("Inconsistent aggregate valuation while attempting to append " + std::string(typeid(T).name()) + " to an aggregate of " + current);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -875,9 +880,9 @@ direct_aggregate read_direct_aggregate(
|
||||
const ifcopenshell::entity* entity,
|
||||
int attribute_index,
|
||||
const ifcopenshell::aggregation_type* aggregate_type,
|
||||
::Logger& logger
|
||||
::logger& logger
|
||||
) {
|
||||
direct_aggregate aggregate;
|
||||
direct_aggregate aggregate(logger);
|
||||
token next = tokens->next();
|
||||
|
||||
while (next) {
|
||||
@@ -885,7 +890,7 @@ direct_aggregate read_direct_aggregate(
|
||||
} else if (next.is_operator(')')) {
|
||||
break;
|
||||
} else if (next.is_operator('(')) {
|
||||
auto nested = read_direct_aggregate(storage, tokens, entity_instance_name, entity, attribute_index, nested_aggregation_type(aggregate_type));
|
||||
auto nested = read_direct_aggregate(storage, tokens, entity_instance_name, entity, attribute_index, nested_aggregation_type(aggregate_type), logger);
|
||||
if (nested.values == 0 && nested.storage.index() == 0) {
|
||||
aggregate.append_empty_nested();
|
||||
} else {
|
||||
@@ -909,7 +914,7 @@ direct_aggregate read_direct_aggregate(
|
||||
if (next.is_identifier() && entity && entity_instance_name) {
|
||||
storage.register_inverse((unsigned)*entity_instance_name, entity, next.value_int, attribute_index);
|
||||
}
|
||||
dispatch_token_direct(next, aggregate_type && aggregate_type->type_of_element()->as_named_type() ? aggregate_type->type_of_element()->as_named_type()->declared_type() : nullptr, attribute_index, [&aggregate](const auto& value) {
|
||||
dispatch_token_direct(next, aggregate_type && aggregate_type->type_of_element()->as_named_type() ? aggregate_type->type_of_element()->as_named_type()->declared_type() : nullptr, attribute_index, logger, [&aggregate](const auto& value) {
|
||||
aggregate.append(value);
|
||||
});
|
||||
}
|
||||
@@ -961,7 +966,7 @@ shared_pointer_type ifcopenshell::impl::in_memory_file_storage::load(
|
||||
|
||||
if (next.is_operator('(')) {
|
||||
if (retain_value) {
|
||||
auto aggregate = read_direct_aggregate(*this, tokens, entity_instance_name, entity, reference_attribute_index, aggregate_parameter_type(parameter_type));
|
||||
auto aggregate = read_direct_aggregate(*this, tokens, entity_instance_name, entity, reference_attribute_index, aggregate_parameter_type(parameter_type), logger_.get());
|
||||
std::visit([&](const auto& value) {
|
||||
if constexpr (!std::is_same_v<std::decay_t<decltype(value)>, blank>) {
|
||||
set_direct_attribute(storage, entity_instance_name, references_to_resolve, attribute_index_within_data, attribute_index, value);
|
||||
@@ -982,7 +987,7 @@ shared_pointer_type ifcopenshell::impl::in_memory_file_storage::load(
|
||||
skip_aggregate(tokens);
|
||||
}
|
||||
} catch (exception& e) {
|
||||
logger::message(logger::LOG_ERROR, std::string(e.what()) + " at offset " + std::to_string(next.start_pos));
|
||||
logger_.get().message(::logger::LOG_ERROR, std::string(e.what()) + " at offset " + std::to_string(next.start_pos));
|
||||
--values_read;
|
||||
}
|
||||
} else {
|
||||
@@ -990,7 +995,7 @@ shared_pointer_type ifcopenshell::impl::in_memory_file_storage::load(
|
||||
register_inverse((unsigned)*entity_instance_name, entity, next.value_int, reference_attribute_index);
|
||||
}
|
||||
if (retain_value) {
|
||||
dispatch_token_direct(next, declared_type(parameter_type), (int) attribute_index_within_data, [&](const auto& value) {
|
||||
dispatch_token_direct(next, declared_type(parameter_type), (int) attribute_index_within_data, logger_.get(), [&](const auto& value) {
|
||||
set_direct_attribute(storage, entity_instance_name, references_to_resolve, attribute_index_within_data, attribute_index, value);
|
||||
});
|
||||
}
|
||||
@@ -999,7 +1004,7 @@ shared_pointer_type ifcopenshell::impl::in_memory_file_storage::load(
|
||||
next = tokens->next();
|
||||
}
|
||||
|
||||
warn_attribute_count(declaration, entity_instance_name, expected_size, values_read);
|
||||
warn_attribute_count(declaration, entity_instance_name, expected_size, values_read, logger_.get());
|
||||
return ifcopenshell::make_pointer_type<instance_data>(file, declaration, (declaration && declaration->as_entity()) ? (uint32_t)entity_instance_name.value_or(0) : 0, std::move(storage));
|
||||
}
|
||||
|
||||
@@ -1068,7 +1073,7 @@ void ifcopenshell::impl::rocks_db_file_storage::unregister_inverse(unsigned id_f
|
||||
if (it != vals.end()) {
|
||||
vals.erase(it);
|
||||
} else {
|
||||
logger::error("Unregistering non-existant inverse #" + std::to_string(id_from) + " on instance #" + std::to_string(inst_id) + " at attribute " + std::to_string(attribute_index));
|
||||
file->logger().error("Unregistering non-existant inverse #" + std::to_string(id_from) + " on instance #" + std::to_string(inst_id) + " at attribute " + std::to_string(attribute_index));
|
||||
}
|
||||
s.resize(vals.size() * sizeof(uint32_t));
|
||||
memcpy(s.data(), vals.data(), s.size());
|
||||
@@ -1528,7 +1533,7 @@ express::Base::set_attribute_value(size_t i, const T& t) {
|
||||
}
|
||||
}
|
||||
} catch (ifcopenshell::exception& e) {
|
||||
logger::error(e);
|
||||
file()->logger().error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1556,11 +1561,11 @@ express::Base::set_attribute_value(size_t i, const T& t) {
|
||||
auto guid = (std::string) new_attribute;
|
||||
auto it = file()->internal_guid_map().find(guid);
|
||||
if (it != file()->internal_guid_map().end()) {
|
||||
logger::warning("Duplicate guid " + guid);
|
||||
file()->logger().warning("Duplicate guid " + guid);
|
||||
}
|
||||
file()->internal_guid_map().insert({guid, *this});
|
||||
} catch (ifcopenshell::exception& e) {
|
||||
logger::error(e);
|
||||
file()->logger().error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1579,18 +1584,23 @@ express::Base::set_attribute_value(const std::string& s, const T& t)
|
||||
// Creates the maps
|
||||
//
|
||||
#ifdef USE_MMAP
|
||||
file::file(const std::string& fn, bool mmap) {
|
||||
file::file(const std::string& fn, bool mmap, ::logger& log)
|
||||
: logger_(log)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, header_(new spf_header(this, logger_.get())) {
|
||||
initialize(fn, mmap);
|
||||
}
|
||||
|
||||
bool ifcopenshell::file::initialize(const std::string& fn, bool mmap) {
|
||||
if (mmap) {
|
||||
file_reader<mmap_impl> s(fn);
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||
} else {
|
||||
file_reader<full_buffer_impl> s(fn);
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||
}
|
||||
|
||||
@@ -1606,8 +1616,8 @@ bool ifcopenshell::file::initialize(const std::string& fn, bool mmap) {
|
||||
}
|
||||
#endif
|
||||
|
||||
file::file(const uninitialized_tag&)
|
||||
: schema_(nullptr), max_id_(0), header_(new ifcopenshell::spf_header(this)), good_(file_open_status::UNKNOWN), ifcroot_type_(nullptr) {}
|
||||
file::file(const uninitialized_tag&, ::logger& log)
|
||||
: good_(file_open_status::UNKNOWN), logger_(log), schema_(nullptr), ifcroot_type_(nullptr), max_id_(0), header_(new ifcopenshell::spf_header(this, logger_.get())) {}
|
||||
|
||||
bool ifcopenshell::file::initialize(const std::string& path, filetype ty, bool readonly) {
|
||||
if (ty == FT_AUTODETECT) {
|
||||
@@ -1615,7 +1625,7 @@ bool ifcopenshell::file::initialize(const std::string& path, filetype ty, bool r
|
||||
}
|
||||
if (ty == FT_IFCSPF) {
|
||||
file_reader<full_buffer_impl> s(path);
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
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_)) {
|
||||
@@ -1659,18 +1669,22 @@ void ifcopenshell::file::bypass_type(const std::string& type_name) {
|
||||
types_to_bypass_loading_.insert(type_name);
|
||||
}
|
||||
|
||||
file::file(const std::string& path, filetype ty, bool readonly)
|
||||
: schema_(nullptr)
|
||||
file::file(const std::string& path, filetype ty, bool readonly, ::logger& log)
|
||||
: logger_(log)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, header_(new spf_header(this))
|
||||
, header_(new spf_header(this, logger_.get()))
|
||||
{
|
||||
initialize(path, ty, readonly);
|
||||
}
|
||||
|
||||
file::file(std::istream& stream, int length)
|
||||
: schema_(nullptr)
|
||||
file::file(std::istream& stream, int length, ::logger& log)
|
||||
: logger_(log)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, header_(new ifcopenshell::spf_header(this))
|
||||
, header_(new ifcopenshell::spf_header(this, logger_.get()))
|
||||
{
|
||||
file_reader<pushed_sequential_impl> s(caller_fed_tag{});
|
||||
|
||||
@@ -1679,7 +1693,7 @@ file::file(std::istream& stream, int length)
|
||||
stream.read(string_data.data(), length);
|
||||
s.push_next_page(string_data);
|
||||
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
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_;
|
||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||
@@ -1689,14 +1703,16 @@ file::file(std::istream& stream, int length)
|
||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||
}
|
||||
|
||||
file::file(void* data, int length)
|
||||
: schema_(nullptr)
|
||||
, max_id_(0),
|
||||
header_(new ifcopenshell::spf_header(this))
|
||||
file::file(void* data, int length, ::logger& log)
|
||||
: logger_(log)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, header_(new ifcopenshell::spf_header(this, logger_.get()))
|
||||
{
|
||||
file_reader<pushed_sequential_impl> s(std::string((char*)data, length), caller_fed_tag{});
|
||||
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
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_;
|
||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||
@@ -1706,8 +1722,9 @@ file::file(void* data, int length)
|
||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||
}
|
||||
|
||||
file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std::string& path)
|
||||
: schema_(schema)
|
||||
file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std::string& path, ::logger& log)
|
||||
: logger_(log)
|
||||
, schema_(schema)
|
||||
, ifcroot_type_(schema_->declaration_by_name("IfcRoot"))
|
||||
, max_id_(0)
|
||||
{
|
||||
@@ -1715,7 +1732,7 @@ file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std
|
||||
ty = guess_file_type(path);
|
||||
}
|
||||
if (ty == FT_IFCSPF) {
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
|
||||
byid_ = decltype(byid_)(&std::get<impl::in_memory_file_storage>(storage_).byid_read_);
|
||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
||||
@@ -1733,7 +1750,7 @@ file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std
|
||||
} else {
|
||||
throw std::runtime_error("Unsupported file format");
|
||||
}
|
||||
header_.reset(new spf_header(this));
|
||||
header_.reset(new spf_header(this, logger_.get()));
|
||||
set_default_header_values();
|
||||
}
|
||||
|
||||
@@ -1805,7 +1822,7 @@ bool try_parse_header(
|
||||
parse_header(header, storage, lexer, references_to_resolve);
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
logger::error(e);
|
||||
storage.logger_.get().error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1822,7 +1839,7 @@ spf_header& ifcopenshell::instance_streamer<Reader>::ensure_header() {
|
||||
header_ = &owner_->header();
|
||||
header_->owner_file(owner_);
|
||||
} else {
|
||||
owned_header_ = std::make_unique<spf_header>(owner_);
|
||||
owned_header_ = std::make_unique<spf_header>(owner_, logger_.get());
|
||||
header_ = owned_header_.get();
|
||||
}
|
||||
|
||||
@@ -1868,7 +1885,7 @@ void ifcopenshell::instance_streamer<Reader>::initialize_header() {
|
||||
template <typename Reader>
|
||||
bool ifcopenshell::instance_streamer<Reader>::has_semicolon() const {
|
||||
auto local_stream = stream_->clone();
|
||||
auto local_lexer = spf_lexer<Reader>(&local_stream);
|
||||
auto local_lexer = spf_lexer<Reader>(&local_stream, logger_.get());
|
||||
token t;
|
||||
try {
|
||||
t = local_lexer.next();
|
||||
@@ -1891,7 +1908,7 @@ bool ifcopenshell::instance_streamer<Reader>::has_semicolon() const {
|
||||
template <typename Reader>
|
||||
size_t ifcopenshell::instance_streamer<Reader>::semicolon_count() const {
|
||||
auto local_stream = stream_->clone();
|
||||
auto local_lexer = spf_lexer<Reader>(&local_stream);
|
||||
auto local_lexer = spf_lexer<Reader>(&local_stream, logger_.get());
|
||||
token t;
|
||||
size_t count = 0;
|
||||
try {
|
||||
@@ -1921,12 +1938,14 @@ void ifcopenshell::instance_streamer<Reader>::push_page(const std::string& page)
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(ifcopenshell::file* f)
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(ifcopenshell::file* f, ::logger& log)
|
||||
: stream_(nullptr)
|
||||
, header_(nullptr)
|
||||
, owner_(f)
|
||||
, token_stream_(3, token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, log)
|
||||
, logger_(log)
|
||||
, progress_(0)
|
||||
{
|
||||
if constexpr (std::is_same_v<Reader, file_reader<full_buffer_impl>>) {
|
||||
@@ -1938,19 +1957,21 @@ ifcopenshell::instance_streamer<Reader>::instance_streamer(ifcopenshell::file* f
|
||||
}
|
||||
|
||||
stream_ = owned_stream_.get();
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_);
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_, logger_.get());
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
storage_.file = f;
|
||||
storage_.references_to_resolve = &references_to_resolve_;
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(const std::string& fn, bool mmap, ifcopenshell::file* f)
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(const std::string& fn, bool mmap, ifcopenshell::file* f, ::logger& log)
|
||||
: stream_(nullptr)
|
||||
, header_(nullptr)
|
||||
, owner_(f)
|
||||
, token_stream_(3, token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, log)
|
||||
, logger_(log)
|
||||
, progress_(0)
|
||||
{
|
||||
if constexpr (std::is_same_v<Reader, file_reader<full_buffer_impl>>) {
|
||||
@@ -1966,18 +1987,20 @@ ifcopenshell::instance_streamer<Reader>::instance_streamer(const std::string& fn
|
||||
}
|
||||
|
||||
stream_ = owned_stream_.get();
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_);
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_, logger_.get());
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
initialize_header();
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(void* data, int length, ifcopenshell::file* f)
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(void* data, int length, ifcopenshell::file* f, ::logger& log)
|
||||
: stream_(nullptr)
|
||||
, header_(nullptr)
|
||||
, owner_(f)
|
||||
, token_stream_(3, token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, log)
|
||||
, logger_(log)
|
||||
, progress_(0)
|
||||
{
|
||||
if constexpr (std::is_same_v<Reader, file_reader<full_buffer_impl>>) {
|
||||
@@ -1989,21 +2012,23 @@ ifcopenshell::instance_streamer<Reader>::instance_streamer(void* data, int lengt
|
||||
}
|
||||
|
||||
stream_ = owned_stream_.get();
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_);
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_, logger_.get());
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
initialize_header();
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(Reader* stream, ifcopenshell::file* f)
|
||||
ifcopenshell::instance_streamer<Reader>::instance_streamer(Reader* stream, ifcopenshell::file* f, ::logger& log)
|
||||
: stream_(stream)
|
||||
, header_(nullptr)
|
||||
, owner_(f)
|
||||
, token_stream_(3, token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, log)
|
||||
, logger_(log)
|
||||
, progress_(0)
|
||||
{
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_);
|
||||
lexer_ = std::make_unique<spf_lexer<Reader>>(stream_, logger_.get());
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
initialize_header();
|
||||
}
|
||||
@@ -2067,13 +2092,13 @@ std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointe
|
||||
try {
|
||||
entity_type = schema_->declaration_by_name(token_stream_[2].as_string());
|
||||
} catch (const exception& ex) {
|
||||
logger::message(logger::LOG_ERROR, std::string(ex.what()) + " at offset " + std::to_string(token_stream_[2].start_pos));
|
||||
logger_.get().message(::logger::LOG_ERROR, std::string(ex.what()) + " at offset " + std::to_string(token_stream_[2].start_pos));
|
||||
current_id = 0;
|
||||
goto advance;
|
||||
}
|
||||
|
||||
if (entity_type->as_entity() == nullptr) {
|
||||
logger::message(logger::LOG_ERROR, "Non entity type " + entity_type->name() + " at offset " + std::to_string(token_stream_[2].start_pos));
|
||||
logger_.get().message(::logger::LOG_ERROR, "Non entity type " + entity_type->name() + " at offset " + std::to_string(token_stream_[2].start_pos));
|
||||
goto advance;
|
||||
}
|
||||
|
||||
@@ -2090,7 +2115,7 @@ std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointe
|
||||
if (((++progress_) % 1000) == 0) {
|
||||
std::stringstream ss;
|
||||
ss << "\r#" << current_id;
|
||||
logger::status(ss.str(), false);
|
||||
logger_.get().status(ss.str(), false);
|
||||
}
|
||||
|
||||
return_value.emplace(
|
||||
@@ -2099,7 +2124,7 @@ std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointe
|
||||
data);
|
||||
} catch (const invalid_token_exception& e) {
|
||||
good_ = file_open_status::INVALID_SYNTAX;
|
||||
logger::error(e);
|
||||
logger_.get().error(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2108,9 +2133,9 @@ std::optional<std::tuple<size_t, const ifcopenshell::declaration*, shared_pointe
|
||||
try {
|
||||
next_token = lexer_->next();
|
||||
} catch (const exception& e) {
|
||||
logger::message(logger::LOG_ERROR, std::string(e.what()) + ". Parsing terminated");
|
||||
logger_.get().message(::logger::LOG_ERROR, std::string(e.what()) + ". Parsing terminated");
|
||||
} catch (...) {
|
||||
logger::message(logger::LOG_ERROR, "Parsing terminated");
|
||||
logger_.get().message(::logger::LOG_ERROR, "Parsing terminated");
|
||||
}
|
||||
|
||||
if (!lexer_->stream->eof() && !next_token) {
|
||||
@@ -2140,7 +2165,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
|
||||
std::vector<std::string> schemas;
|
||||
|
||||
instance_streamer<Reader> streamer(s, file);
|
||||
instance_streamer<Reader> streamer(s, file, logger_.get());
|
||||
streamer.yield_header_instances(false);
|
||||
|
||||
if (const auto* header = streamer.header()) {
|
||||
@@ -2156,7 +2181,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
schema = ifcopenshell::schema_by_name(schemas.front());
|
||||
} catch (const ifcopenshell::exception& e) {
|
||||
good_ = file_open_status::UNSUPPORTED_SCHEMA;
|
||||
logger::error(e);
|
||||
logger_.get().error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2166,14 +2191,14 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
} else {
|
||||
good_ = file_open_status::UNSUPPORTED_SCHEMA;
|
||||
}
|
||||
logger::message(logger::LOG_ERROR, "No support for file schema encountered (" + boost::algorithm::join(schemas, ", ") + ")");
|
||||
logger_.get().message(::logger::LOG_ERROR, "No support for file schema encountered (" + boost::algorithm::join(schemas, ", ") + ")");
|
||||
return;
|
||||
}
|
||||
|
||||
auto ifcroot_type_ = schema->declaration_by_name("IfcRoot");
|
||||
streamer.bypass_types(typed_to_bypass);
|
||||
|
||||
logger::status("Scanning file...");
|
||||
logger_.get().status("Scanning file...");
|
||||
|
||||
while (streamer) {
|
||||
auto inst = streamer.read_instance();
|
||||
@@ -2191,11 +2216,11 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
if (byguid_.find(guid) != byguid_.end()) {
|
||||
std::stringstream ss;
|
||||
ss << "Instance encountered with non-unique GlobalId " << guid;
|
||||
logger::message(logger::LOG_WARNING, ss.str());
|
||||
logger_.get().message(::logger::LOG_WARNING, ss.str());
|
||||
}
|
||||
byguid_[guid] = instance;
|
||||
} catch (const exception& ex) {
|
||||
logger::message(logger::LOG_ERROR, ex.what());
|
||||
logger_.get().message(::logger::LOG_ERROR, ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2205,7 +2230,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
if (byid_.find(current_id) != byid_.end()) {
|
||||
std::stringstream ss;
|
||||
ss << "Overwriting instance with name #" << current_id;
|
||||
logger::message(logger::LOG_WARNING, ss.str());
|
||||
logger_.get().message(::logger::LOG_WARNING, ss.str());
|
||||
}
|
||||
|
||||
byid_.insert({(uint32_t)current_id, std::get<2>(*inst)});
|
||||
@@ -2217,7 +2242,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
byref_excl_.sort();
|
||||
read_simple_type_instances = streamer.steal_instances();
|
||||
|
||||
logger::status("\rDone scanning file ");
|
||||
logger_.get().status("\rDone scanning file ");
|
||||
|
||||
if (good_ != file_open_status::SUCCESS) {
|
||||
return;
|
||||
@@ -2235,7 +2260,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
}
|
||||
auto it = byid_.find(*name);
|
||||
if (it == byid_.end()) {
|
||||
logger::error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
|
||||
logger_.get().error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
|
||||
} else {
|
||||
auto& storage = byid_[p.first.name_];
|
||||
auto attr_index = p.first.index_;
|
||||
@@ -2256,7 +2281,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
if (storage->template has_attribute_value<blank>(attr_index)) {
|
||||
storage->set_attribute_value(attr_index, express::Base(it->second));
|
||||
} else {
|
||||
logger::error("Duplicate definition for instance reference");
|
||||
logger_.get().error("Duplicate definition for instance reference");
|
||||
}
|
||||
}
|
||||
} else if (auto inst = std::get_if<express::Base>(v)) {
|
||||
@@ -2272,7 +2297,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
}
|
||||
auto it = byid_.find(*name);
|
||||
if (it == byid_.end()) {
|
||||
logger::error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
|
||||
logger_.get().error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
|
||||
} else {
|
||||
instances.push_back(express::Base(it->second));
|
||||
}
|
||||
@@ -2300,7 +2325,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
if (storage->template has_attribute_value<blank>(attr_index)) {
|
||||
storage->set_attribute_value(attr_index, instances);
|
||||
} else {
|
||||
logger::error("Duplicate definition for instance reference");
|
||||
logger_.get().error("Duplicate definition for instance reference");
|
||||
}
|
||||
} else if (auto* vvv = std::get_if<std::vector<std::vector<reference_or_simple_type>>>(&p.second)) {
|
||||
std::vector<std::vector<express::Base>> instances;
|
||||
@@ -2313,7 +2338,7 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
}
|
||||
auto it = byid_.find(*name);
|
||||
if (it == byid_.end()) {
|
||||
logger::error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
|
||||
logger_.get().error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
|
||||
} else {
|
||||
inner.push_back(express::Base(it->second));
|
||||
}
|
||||
@@ -2342,12 +2367,12 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
if (storage->template has_attribute_value<blank>(attr_index)) {
|
||||
storage->set_attribute_value(attr_index, instances);
|
||||
} else {
|
||||
logger::error("Duplicate definition for instance reference");
|
||||
logger_.get().error("Duplicate definition for instance reference");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger::status("Done resolving references");
|
||||
logger_.get().status("Done resolving references");
|
||||
}
|
||||
|
||||
template void ifcopenshell::impl::in_memory_file_storage::read_from_stream(file_reader<full_buffer_impl>* s, const ifcopenshell::schema_definition*& schema, unsigned int& max_id, const std::set<std::string>& typed_to_bypass);
|
||||
@@ -2490,7 +2515,7 @@ express::Base file::add_entity(const express::Base& entity, int id) {
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
logger::message(logger::LOG_ERROR, "Failed to visit forward references of", entity);
|
||||
logger_.get().message(::logger::LOG_ERROR, "Failed to visit forward references of", entity);
|
||||
}
|
||||
|
||||
// An instance is being added from another file. A copy of the
|
||||
@@ -2617,11 +2642,11 @@ express::Base file::add_entity(const express::Base& entity, int id) {
|
||||
if (byguid_.find(guid) != byguid_.end()) {
|
||||
std::stringstream ss;
|
||||
ss << "Overwriting entity with guid " << guid;
|
||||
logger::message(logger::LOG_WARNING, ss.str());
|
||||
logger_.get().message(::logger::LOG_WARNING, ss.str());
|
||||
}
|
||||
byguid_.insert({ guid, new_entity });
|
||||
} catch (const std::exception& ex) {
|
||||
logger::message(logger::LOG_ERROR, ex.what());
|
||||
logger_.get().message(::logger::LOG_ERROR, ex.what());
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -2731,7 +2756,7 @@ void file::process_deletion_(const express::Base& entity) {
|
||||
if (it != byguid_.end()) {
|
||||
byguid_.erase(it);
|
||||
} else {
|
||||
logger::warning("GlobalId on rooted instance not encountered in map");
|
||||
logger_.get().warning("GlobalId on rooted instance not encountered in map");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ template <typename Reader>
|
||||
class IFC_PARSE_API spf_lexer {
|
||||
private:
|
||||
character_decoder<Reader>* decoder_;
|
||||
Logger& logger_;
|
||||
::logger& logger_;
|
||||
|
||||
size_t skip_whitespace() const;
|
||||
size_t skip_comment() const;
|
||||
@@ -77,7 +77,7 @@ class IFC_PARSE_API spf_lexer {
|
||||
|
||||
Reader* stream;
|
||||
// file* file;
|
||||
spf_lexer(Reader* stream, Logger& logger = Logger::Root());
|
||||
spf_lexer(Reader* stream, ::logger& logger = ::logger::root());
|
||||
token next();
|
||||
~spf_lexer();
|
||||
// void TokenString(size_t offset, std::string& result);
|
||||
|
||||
@@ -11,7 +11,8 @@ using namespace ifcopenshell;
|
||||
|
||||
namespace {
|
||||
|
||||
shared_pointer_type make_header_entity(ifcopenshell::file* file, const ifcopenshell::entity& decl, Logger& logger) {
|
||||
shared_pointer_type make_header_entity(ifcopenshell::file* file, const ifcopenshell::entity& decl, ::logger& logger) {
|
||||
static_cast<void>(logger);
|
||||
const bool in_memory = file == nullptr || std::visit([](auto& storage) {
|
||||
return std::is_same_v<std::decay_t<decltype(storage)>, ifcopenshell::impl::in_memory_file_storage>;
|
||||
}, file->storage_);
|
||||
@@ -25,13 +26,14 @@ shared_pointer_type make_header_entity(ifcopenshell::file* file, const ifcopensh
|
||||
|
||||
} // namespace
|
||||
|
||||
ifcopenshell::spf_header::spf_header(ifcopenshell::file* file)
|
||||
: file_(file) {
|
||||
ifcopenshell::spf_header::spf_header(ifcopenshell::file* file, ::logger& logger)
|
||||
: file_(file)
|
||||
, logger_(logger) {
|
||||
Header_section_schema::get_schema();
|
||||
|
||||
header_entities_[0] = make_header_entity(file_, Header_section_schema::file_description::Class());
|
||||
header_entities_[1] = make_header_entity(file_, Header_section_schema::file_name::Class());
|
||||
header_entities_[2] = make_header_entity(file_, Header_section_schema::file_schema::Class());
|
||||
header_entities_[0] = make_header_entity(file_, Header_section_schema::file_description::Class(), logger_);
|
||||
header_entities_[1] = make_header_entity(file_, Header_section_schema::file_name::Class(), logger_);
|
||||
header_entities_[2] = make_header_entity(file_, Header_section_schema::file_schema::Class(), logger_);
|
||||
}
|
||||
|
||||
ifcopenshell::spf_header::~spf_header() = default;
|
||||
|
||||
@@ -32,29 +32,24 @@ class file;
|
||||
class IFC_PARSE_API spf_header {
|
||||
private:
|
||||
ifcopenshell::file* file_;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
IfcParse::impl::in_memory_file_storage* storage_ = nullptr;
|
||||
std::reference_wrapper<::logger> logger_;
|
||||
|
||||
std::array<shared_pointer_type, 3> header_entities_;
|
||||
|
||||
public:
|
||||
explicit spf_header(ifcopenshell::file* file = nullptr, Logger& logger = Logger::Root());
|
||||
explicit spf_header(spf_lexer* lexer, Logger& logger = Logger::Root());
|
||||
explicit spf_header(ifcopenshell::file* file = nullptr, ::logger& logger = ::logger::root());
|
||||
~spf_header();
|
||||
|
||||
void write(std::ostream& stream) const;
|
||||
|
||||
ifcopenshell::file* owner_file() { return file_; }
|
||||
void owner_file(ifcopenshell::file* file);
|
||||
Logger& logger() const { return logger_.get(); }
|
||||
::logger& logger() const { return logger_.get(); }
|
||||
|
||||
void set_file_description(const shared_pointer_type& description_data);
|
||||
void set_file_name(const shared_pointer_type& name_data);
|
||||
void set_file_schema(const shared_pointer_type& schema_data);
|
||||
|
||||
void assign(const IfcSpfHeader& other);
|
||||
|
||||
void write(std::ostream& out) const;
|
||||
|
||||
Header_section_schema::file_description file_description();
|
||||
Header_section_schema::file_name file_name();
|
||||
Header_section_schema::file_schema file_schema();
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace rocksdb {
|
||||
#include "map_transformer.h"
|
||||
#include "set_to_map_transformer.h"
|
||||
#include "file_open_status.h"
|
||||
#include "IfcLogger.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
@@ -412,8 +412,7 @@ namespace ifcopenshell {
|
||||
return std::move(read_simple_type_instances);
|
||||
}
|
||||
|
||||
ifcopenshell::spf_lexer* tokens;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
std::reference_wrapper<::logger> logger_;
|
||||
// IfcParse::FileReader* stream;
|
||||
|
||||
// Either one of these needs to be set
|
||||
@@ -423,14 +422,14 @@ namespace ifcopenshell {
|
||||
unresolved_references* references_to_resolve = nullptr;
|
||||
|
||||
typedef std::map<const ifcopenshell::declaration*, std::vector<express::Base>> entities_by_type_t;
|
||||
typedef boost::unordered_map<uint32_t, shared_pointer_type> entity_instance_by_name_storage_t;
|
||||
typedef std::unordered_map<uint32_t, shared_pointer_type> entity_instance_by_name_storage_t;
|
||||
typedef map_transformer<entity_instance_by_name_storage_t, std::function<express::Base(shared_pointer_type)>> entity_instance_by_name_t;
|
||||
typedef boost::unordered_map<uint32_t, shared_pointer_type> type_instance_by_name_t;
|
||||
typedef std::unordered_map<uint32_t, shared_pointer_type> type_instance_by_name_t;
|
||||
typedef std::map<std::string, express::Base> entity_instance_by_guid_t;
|
||||
typedef inverse_index entities_by_ref_t;
|
||||
typedef entity_instance_by_name_t::iterator iterator;
|
||||
|
||||
in_memory_file_storage(ifcopenshell::file* owner_file = nullptr, Logger& logger = Logger::Root()) : logger_(logger), file(owner_file), schema(nullptr), byid_read_(&byid_, [this](const shared_pointer_type& data) { return express::Base(data); }) {};
|
||||
in_memory_file_storage(ifcopenshell::file* owner_file = nullptr, ::logger& logger = ::logger::root()) : logger_(logger), file(owner_file), schema(nullptr), byid_read_(&byid_, [this](const shared_pointer_type& data) { return express::Base(data); }) {};
|
||||
in_memory_file_storage(const in_memory_file_storage& other) = delete;
|
||||
in_memory_file_storage(const in_memory_file_storage&& other) = delete;
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ IFC_PARSE_API bool ifcopenshell::path::rename_file(const std::string& old_filena
|
||||
return success;
|
||||
}
|
||||
|
||||
IFC_PARSE_API bool IfcUtil::path::atomic_rename_file(const std::string& old_filename, const std::string& new_filename) {
|
||||
IFC_PARSE_API bool ifcopenshell::path::atomic_rename_file(const std::string& old_filename, const std::string& new_filename) {
|
||||
std::wstring old_filename_w = from_utf8(old_filename);
|
||||
std::wstring new_filename_w = from_utf8(new_filename);
|
||||
// MOVEFILE_REPLACE_EXISTING makes the replace atomic on NTFS (no unlink
|
||||
@@ -292,7 +292,7 @@ IFC_PARSE_API bool ifcopenshell::path::rename_file(const std::string& old_filena
|
||||
return std::rename(old_filename.c_str(), new_filename.c_str()) == 0;
|
||||
}
|
||||
|
||||
IFC_PARSE_API bool IfcUtil::path::atomic_rename_file(const std::string& old_filename, const std::string& new_filename) {
|
||||
IFC_PARSE_API bool ifcopenshell::path::atomic_rename_file(const std::string& old_filename, const std::string& new_filename) {
|
||||
// POSIX rename() atomically replaces an existing destination on the same
|
||||
// filesystem, so there is no window in which new_filename is missing.
|
||||
return std::rename(old_filename.c_str(), new_filename.c_str()) == 0;
|
||||
|
||||
Reference in New Issue
Block a user