clang-format: format test

This commit is contained in:
Dirk Olbrich
2023-09-17 12:30:17 +02:00
committed by Thomas Krijnen
parent 17838f2426
commit 63177a7c35
31 changed files with 6531 additions and 6357 deletions
+35 -36
View File
@@ -20,59 +20,58 @@
#ifndef ARGUMENT_H
#define ARGUMENT_H
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include "ifc_parse_api.h"
#include "ArgumentType.h"
#include "ifc_parse_api.h"
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <boost/dynamic_bitset.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/shared_ptr.hpp>
#include <set>
#include <sstream>
#include <string>
#include <vector>
class aggregate_of_instance;
class aggregate_of_aggregate_of_instance;
namespace IfcUtil {
class IfcBaseClass;
class IfcBaseClass;
IFC_PARSE_API const char* ArgumentTypeToString(ArgumentType argument_type);
IFC_PARSE_API const char* ArgumentTypeToString(ArgumentType argument_type);
/// Returns false when the string `s` contains character outside of {'0', '1'}
IFC_PARSE_API bool valid_binary_string(const std::string& s);
}
/// Returns false when the string `s` contains character outside of {'0', '1'}
IFC_PARSE_API bool valid_binary_string(const std::string& s);
} // namespace IfcUtil
class IFC_PARSE_API Argument {
public:
virtual operator int() const;
virtual operator bool() const;
virtual operator boost::logic::tribool() const;
virtual operator double() const;
virtual operator std::string() const;
virtual operator boost::dynamic_bitset<>() const;
virtual operator IfcUtil::IfcBaseClass*() const;
public:
virtual operator int() const;
virtual operator bool() const;
virtual operator boost::logic::tribool() const;
virtual operator double() const;
virtual operator std::string() const;
virtual operator boost::dynamic_bitset<>() const;
virtual operator IfcUtil::IfcBaseClass*() const;
virtual operator std::vector<int>() const;
virtual operator std::vector<double>() const;
virtual operator std::vector<std::string>() const;
virtual operator std::vector<boost::dynamic_bitset<> >() const;
virtual operator boost::shared_ptr<aggregate_of_instance>() const;
virtual operator std::vector<int>() const;
virtual operator std::vector<double>() const;
virtual operator std::vector<std::string>() const;
virtual operator std::vector<boost::dynamic_bitset<>>() const;
virtual operator boost::shared_ptr<aggregate_of_instance>() const;
virtual operator std::vector< std::vector<int> >() const;
virtual operator std::vector< std::vector<double> >() const;
virtual operator boost::shared_ptr<aggregate_of_aggregate_of_instance>() const;
virtual operator std::vector<std::vector<int>>() const;
virtual operator std::vector<std::vector<double>>() const;
virtual operator boost::shared_ptr<aggregate_of_aggregate_of_instance>() const;
virtual bool isNull() const = 0;
virtual unsigned int size() const = 0;
virtual bool isNull() const = 0;
virtual unsigned int size() const = 0;
virtual IfcUtil::ArgumentType type() const = 0;
virtual Argument* operator [] (unsigned int i) const = 0;
virtual std::string toString(bool upper=false) const = 0;
virtual ~Argument() {};
virtual IfcUtil::ArgumentType type() const = 0;
virtual Argument* operator[](unsigned int i) const = 0;
virtual std::string toString(bool upper = false) const = 0;
virtual ~Argument(){};
};
#endif
+29 -30
View File
@@ -17,44 +17,43 @@
* *
********************************************************************************/
#include "../ifcparse/IfcSchema.h"
#include "ifc_parse_api.h"
#ifndef ARGUMENTTYPE_H
#define ARGUMENTTYPE_H
#include "ifc_parse_api.h"
#include "IfcSchema.h"
namespace IfcUtil {
enum ArgumentType {
Argument_NULL,
Argument_DERIVED,
Argument_INT,
Argument_BOOL,
Argument_LOGICAL,
Argument_DOUBLE,
Argument_STRING,
Argument_BINARY,
Argument_ENUMERATION,
Argument_ENTITY_INSTANCE,
enum ArgumentType {
Argument_NULL,
Argument_DERIVED,
Argument_INT,
Argument_BOOL,
Argument_LOGICAL,
Argument_DOUBLE,
Argument_STRING,
Argument_BINARY,
Argument_ENUMERATION,
Argument_ENTITY_INSTANCE,
Argument_EMPTY_AGGREGATE,
Argument_AGGREGATE_OF_INT,
Argument_AGGREGATE_OF_DOUBLE,
Argument_AGGREGATE_OF_STRING,
Argument_AGGREGATE_OF_BINARY,
Argument_AGGREGATE_OF_ENTITY_INSTANCE,
Argument_EMPTY_AGGREGATE,
Argument_AGGREGATE_OF_INT,
Argument_AGGREGATE_OF_DOUBLE,
Argument_AGGREGATE_OF_STRING,
Argument_AGGREGATE_OF_BINARY,
Argument_AGGREGATE_OF_ENTITY_INSTANCE,
Argument_AGGREGATE_OF_EMPTY_AGGREGATE,
Argument_AGGREGATE_OF_AGGREGATE_OF_INT,
Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE,
Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE,
Argument_AGGREGATE_OF_EMPTY_AGGREGATE,
Argument_AGGREGATE_OF_AGGREGATE_OF_INT,
Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE,
Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE,
Argument_UNKNOWN
};
Argument_UNKNOWN
};
IFC_PARSE_API ArgumentType from_parameter_type(const IfcParse::parameter_type*);
IFC_PARSE_API ArgumentType make_aggregate(ArgumentType elem_type);
}
IFC_PARSE_API ArgumentType from_parameter_type(const IfcParse::parameter_type*);
IFC_PARSE_API ArgumentType make_aggregate(ArgumentType elem_type);
} // namespace IfcUtil
#endif
+115 -114
View File
@@ -20,151 +20,152 @@
#ifndef IFCBASECLASS_H
#define IFCBASECLASS_H
#include "Argument.h"
#include "ifc_parse_api.h"
#include "../ifcparse/IfcEntityInstanceData.h"
#include "../ifcparse/IfcSchema.h"
#include "../ifcparse/utils.h"
#include <boost/shared_ptr.hpp>
#include "IfcEntityInstanceData.h"
#include "IfcSchema.h"
#include "utils.h"
#include <atomic>
#include <boost/shared_ptr.hpp>
class Argument;
class aggregate_of_instance;
namespace IfcUtil {
class IFC_PARSE_API IfcBaseInterface {
protected:
static bool is_null(const IfcBaseInterface* not_this) {
return !not_this;
}
class IFC_PARSE_API IfcBaseInterface {
protected:
static bool is_null(const IfcBaseInterface* not_this) {
return !not_this;
}
template<typename T>
std::enable_if_t<!std::is_same<IfcBaseClass, T>::value && !std::is_same<IfcBaseEntity, T>::value && !std::is_same<IfcBaseType, T>::value> raise_error_on_concrete_class() const {
throw IfcParse::IfcException("Instance of type " + this->declaration().name() + " cannot be cast to " + T::Class().name());
}
template <typename T>
std::enable_if_t<!std::is_same<IfcBaseClass, T>::value && !std::is_same<IfcBaseEntity, T>::value && !std::is_same<IfcBaseType, T>::value> raise_error_on_concrete_class() const {
throw IfcParse::IfcException("Instance of type " + this->declaration().name() + " cannot be cast to " + T::Class().name());
}
template<typename T>
std::enable_if_t<std::is_same<IfcBaseClass, T>::value || std::is_same<IfcBaseEntity, T>::value || std::is_same<IfcBaseType, T>::value> raise_error_on_concrete_class() const {
throw IfcParse::IfcException("Instance of type " + this->declaration().name() + " cannot be cast to base class");
}
template <typename T>
std::enable_if_t<std::is_same<IfcBaseClass, T>::value || std::is_same<IfcBaseEntity, T>::value || std::is_same<IfcBaseType, T>::value> raise_error_on_concrete_class() const {
throw IfcParse::IfcException("Instance of type " + this->declaration().name() + " cannot be cast to base class");
}
public:
virtual const IfcEntityInstanceData& data() const = 0;
virtual IfcEntityInstanceData& data() = 0;
virtual const IfcParse::declaration& declaration() const = 0;
public:
virtual const IfcEntityInstanceData& data() const = 0;
virtual IfcEntityInstanceData& data() = 0;
virtual const IfcParse::declaration& declaration() const = 0;
template <class T>
T* as(bool do_throw = false) {
// @todo: do not allow this to be null in the first place
if (is_null(this)) {
return static_cast<T*>(0);
}
auto t = dynamic_cast<T*>(this);
if (do_throw && !t) {
raise_error_on_concrete_class<T>();
}
return t;
}
template <class T>
T* as(bool do_throw = false) {
// @todo: do not allow this to be null in the first place
if (is_null(this)) {
return static_cast<T*>(0);
}
auto t = dynamic_cast<T*>(this);
if (do_throw && !t) {
raise_error_on_concrete_class<T>();
}
return t;
}
template <class T>
const T* as(bool do_throw = false) const {
if (is_null(this)) {
return static_cast<const T*>(0);
}
auto t = dynamic_cast<const T*>(this);
if (do_throw && !t) {
raise_error_on_concrete_class<T>();
}
return t;
}
};
template <class T>
const T* as(bool do_throw = false) const {
if (is_null(this)) {
return static_cast<const T*>(0);
}
auto t = dynamic_cast<const T*>(this);
if (do_throw && !t) {
raise_error_on_concrete_class<T>();
}
return t;
}
};
class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
private:
uint32_t identity_;
static std::atomic_uint32_t counter_;
class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
private:
uint32_t identity_;
static std::atomic_uint32_t counter_;
protected:
IfcEntityInstanceData* data_;
protected:
IfcEntityInstanceData* data_;
static bool is_null(const IfcBaseClass* not_this) {
return !not_this;
}
public:
IfcBaseClass() : identity_(counter_++), data_(0) {}
IfcBaseClass(IfcEntityInstanceData* d) : identity_(counter_++), data_(d) {}
virtual ~IfcBaseClass() { delete data_; }
const IfcEntityInstanceData& data() const { return *data_; }
IfcEntityInstanceData& data() { return *data_; }
void data(IfcEntityInstanceData* d);
virtual const IfcParse::declaration& declaration() const = 0;
static bool is_null(const IfcBaseClass* not_this) {
return !not_this;
}
uint32_t identity() const { return identity_; }
};
public:
IfcBaseClass() : identity_(counter_++),
data_(0) {}
IfcBaseClass(IfcEntityInstanceData* d) : identity_(counter_++),
data_(d) {}
virtual ~IfcBaseClass() { delete data_; }
class IFC_PARSE_API IfcLateBoundEntity : public IfcBaseClass {
private:
const IfcParse::declaration* decl_;
const IfcEntityInstanceData& data() const { return *data_; }
IfcEntityInstanceData& data() { return *data_; }
void data(IfcEntityInstanceData* d);
public:
IfcLateBoundEntity(const IfcParse::declaration* decl, IfcEntityInstanceData* data) : IfcBaseClass(data), decl_(decl) {}
virtual const IfcParse::declaration& declaration() const = 0;
virtual const IfcParse::declaration& declaration() const {
return *decl_;
}
};
uint32_t identity() const { return identity_; }
};
class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass {
public:
IfcBaseEntity() : IfcBaseClass() {}
IfcBaseEntity(IfcEntityInstanceData* d) : IfcBaseClass(d) {}
class IFC_PARSE_API IfcLateBoundEntity : public IfcBaseClass {
private:
const IfcParse::declaration* decl_;
virtual const IfcParse::entity& declaration() const = 0;
public:
IfcLateBoundEntity(const IfcParse::declaration* decl, IfcEntityInstanceData* data) : IfcBaseClass(data),
decl_(decl) {}
Argument* get(const std::string& name) const;
template <typename T>
T get_value(const std::string& name) const;
template <typename T>
T get_value(const std::string& name, const T& default_value) const;
virtual const IfcParse::declaration& declaration() const {
return *decl_;
}
};
boost::shared_ptr<aggregate_of_instance> get_inverse(const std::string& a) const;
};
class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass {
public:
IfcBaseEntity() : IfcBaseClass() {}
IfcBaseEntity(IfcEntityInstanceData* d) : IfcBaseClass(d) {}
// TODO: Investigate whether these should be template classes instead
class IFC_PARSE_API IfcBaseType : public IfcBaseClass {
public:
IfcBaseType() : IfcBaseClass() {}
IfcBaseType(IfcEntityInstanceData* d) : IfcBaseClass(d) {}
virtual const IfcParse::entity& declaration() const = 0;
virtual const IfcParse::declaration& declaration() const = 0;
};
Argument* get(const std::string& name) const;
}
template <typename T>
T get_value(const std::string& name) const;
#include "../ifcparse/Argument.h"
template <typename T>
T get_value(const std::string& name, const T& default_value) const;
boost::shared_ptr<aggregate_of_instance> get_inverse(const std::string& a) const;
};
// TODO: Investigate whether these should be template classes instead
class IFC_PARSE_API IfcBaseType : public IfcBaseClass {
public:
IfcBaseType() : IfcBaseClass() {}
IfcBaseType(IfcEntityInstanceData* d) : IfcBaseClass(d) {}
virtual const IfcParse::declaration& declaration() const = 0;
};
} // namespace IfcUtil
namespace IfcUtil {
template <typename T>
T IfcBaseEntity::get_value(const std::string& name) const {
auto attr = get(name);
return (T)*attr;
}
template <typename T>
T IfcBaseEntity::get_value(const std::string& name, const T& default_value) const {
auto attr = get(name);
if (attr->isNull()) {
return default_value;
}
return (T)*attr;
}
template <typename T>
T IfcBaseEntity::get_value(const std::string& name) const {
auto attr = get(name);
return (T)*attr;
}
template <typename T>
T IfcBaseEntity::get_value(const std::string& name, const T& default_value) const {
auto attr = get(name);
if (attr->isNull()) {
return default_value;
}
return (T)*attr;
}
} // namespace IfcUtil
#endif
+329 -316
View File
@@ -16,337 +16,352 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
/********************************************************************************
/********************************************************************************
* *
* Implementation of character decoding as described in ISO 10303-21 table 2 and *
* table 4 *
* *
********************************************************************************/
#include <string>
#include <sstream>
#include <iomanip>
#include "IfcCharacterDecoder.h"
#include "IfcException.h"
#include "IfcSpfStream.h"
#include <codecvt>
#include <iomanip>
#include <sstream>
#include <string>
#include "../ifcparse/IfcCharacterDecoder.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcSpfStream.h"
#define FIRST_SOLIDUS (1 << 1)
#define PAGE (1 << 2)
#define ALPHABET (1 << 3)
#define SECOND_SOLIDUS (1 << 4)
#define ALPHABET_DEFINITION (1 << 5)
#define APOSTROPHE (1 << 6)
#define ARBITRARY (1 << 7)
#define EXTENDED2 (1 << 8)
#define EXTENDED4 (1 << 9)
#define HEX(N) (1 << (9+N))
#define THIRD_SOLIDUS (1 << 18)
#define ENDEXTENDED_X (1 << 19)
#define ENDEXTENDED_0 (1 << 20)
#define IGNORED_DIRECTIVE (1 << 22)
#define ENCOUNTERED_HEX (1 << 23)
#define FIRST_SOLIDUS (1 << 1)
#define PAGE (1 << 2)
#define ALPHABET (1 << 3)
#define SECOND_SOLIDUS (1 << 4)
#define ALPHABET_DEFINITION (1 << 5)
#define APOSTROPHE (1 << 6)
#define ARBITRARY (1 << 7)
#define EXTENDED2 (1 << 8)
#define EXTENDED4 (1 << 9)
#define HEX(N) (1 << (9 + N))
#define THIRD_SOLIDUS (1 << 18)
#define ENDEXTENDED_X (1 << 19)
#define ENDEXTENDED_0 (1 << 20)
#define IGNORED_DIRECTIVE (1 << 22)
#define ENCOUNTERED_HEX (1 << 23)
// FIXME: These probably need to be less forgiving in terms of wrongly defined sequences
#define EXPECTS_ALPHABET(S) (S & FIRST_SOLIDUS)
#define EXPECTS_PAGE(S) (S & FIRST_SOLIDUS)
#define EXPECTS_ARBITRARY(S) (S & FIRST_SOLIDUS)
#define EXPECTS_N_OR_F(S) (S & FIRST_SOLIDUS && !(S & ARBITRARY) )
#define EXPECTS_ARBITRARY2(S) (S & ARBITRARY && !(S & SECOND_SOLIDUS))
#define EXPECTS_ALPHABET_DEFINITION(S) (S & FIRST_SOLIDUS && S & ALPHABET)
#define EXPECTS_SOLIDUS(S) (S & ALPHABET_DEFINITION || S & PAGE || S & ARBITRARY || S & EXTENDED2 || S & EXTENDED4 || S & ENDEXTENDED_0 || S & IGNORED_DIRECTIVE || (S & EXTENDED4 && S & HEX(8)) || (S & EXTENDED2 && S & HEX(4)))
#define EXPECTS_CHARACTER(S) (S & PAGE && S & SECOND_SOLIDUS)
#define EXPECTS_HEX(S) (S & HEX(1) || S & HEX(3) || S & HEX(5) || S & HEX(6) || S & HEX(7) || (S & ARBITRARY && S & SECOND_SOLIDUS) || (S & EXTENDED2 && S & HEX(2)) || (S & EXTENDED4 && S & HEX(4)) )
#define EXPECTS_ENDEXTENDED_X(S) (S & THIRD_SOLIDUS)
#define EXPECTS_ENDEXTENDED_0(S) (S & ENDEXTENDED_X)
#define EXPECTS_ALPHABET(S) (S & FIRST_SOLIDUS)
#define EXPECTS_PAGE(S) (S & FIRST_SOLIDUS)
#define EXPECTS_ARBITRARY(S) (S & FIRST_SOLIDUS)
#define EXPECTS_N_OR_F(S) (S & FIRST_SOLIDUS && !(S & ARBITRARY))
#define EXPECTS_ARBITRARY2(S) (S & ARBITRARY && !(S & SECOND_SOLIDUS))
#define EXPECTS_ALPHABET_DEFINITION(S) (S & FIRST_SOLIDUS && S & ALPHABET)
#define EXPECTS_SOLIDUS(S) (S & ALPHABET_DEFINITION || S & PAGE || S & ARBITRARY || S & EXTENDED2 || S & EXTENDED4 || S & ENDEXTENDED_0 || S & IGNORED_DIRECTIVE || (S & EXTENDED4 && S & HEX(8)) || (S & EXTENDED2 && S & HEX(4)))
#define EXPECTS_CHARACTER(S) (S & PAGE && S & SECOND_SOLIDUS)
#define EXPECTS_HEX(S) (S & HEX(1) || S & HEX(3) || S & HEX(5) || S & HEX(6) || S & HEX(7) || (S & ARBITRARY && S & SECOND_SOLIDUS) || (S & EXTENDED2 && S & HEX(2)) || (S & EXTENDED4 && S & HEX(4)))
#define EXPECTS_ENDEXTENDED_X(S) (S & THIRD_SOLIDUS)
#define EXPECTS_ENDEXTENDED_0(S) (S & ENDEXTENDED_X)
#define IS_VALID_ALPHABET_DEFINITION(C) (C >= 0x41 && C <= 0x49)
#define IS_HEXADECIMAL(C) ((C >= 0x30 && C <= 0x39 ) || (C >= 0x41 && C <= 0x46 ))
#define HEX_TO_INT(C) ((C >= 0x30 && C <= 0x39 ) ? C - 0x30 : (C+10) - 0x41)
#define CLEAR_HEX(C) (C &= ~(HEX(1)|HEX(2)|HEX(3)|HEX(4)|HEX(5)|HEX(6)|HEX(7)|HEX(8)))
#define IS_VALID_ALPHABET_DEFINITION(C) (C >= 0x41 && C <= 0x49)
#define IS_HEXADECIMAL(C) ((C >= 0x30 && C <= 0x39) || (C >= 0x41 && C <= 0x46))
#define HEX_TO_INT(C) ((C >= 0x30 && C <= 0x39) ? C - 0x30 : (C + 10) - 0x41)
#define CLEAR_HEX(C) (C &= ~(HEX(1) | HEX(2) | HEX(3) | HEX(4) | HEX(5) | HEX(6) | HEX(7) | HEX(8)))
using namespace IfcParse;
using namespace IfcWrite;
IfcCharacterDecoder::IfcCharacterDecoder(IfcParse::IfcSpfStream* f) {
file = f;
codepage_ = 0;
file = f;
codepage_ = 0;
}
IfcCharacterDecoder::~IfcCharacterDecoder() {
}
namespace {
static unsigned int reference_helper = 0;
static unsigned int reference_helper = 0;
class pure_impure_helper {
private:
bool pure_;
IfcParse::IfcSpfStream* stream_;
unsigned int& pointer_;
std::wstring builder_;
class pure_impure_helper {
private:
bool pure_;
IfcParse::IfcSpfStream* stream_;
unsigned int& pointer_;
std::wstring builder_;
char peek() {
if (pure_) {
return stream_->peek_at(pointer_);
} else {
return stream_->Peek();
}
}
char peek() {
if (pure_) {
return stream_->peek_at(pointer_);
} else {
return stream_->Peek();
}
}
unsigned int tell() {
if (pure_) {
return pointer_;
} else {
return stream_->Tell();
}
}
unsigned int tell() {
if (pure_) {
return pointer_;
} else {
return stream_->Tell();
}
}
void increment() {
if (pure_) {
stream_->increment_at(pointer_);
} else {
stream_->Inc();
}
}
void increment() {
if (pure_) {
stream_->increment_at(pointer_);
} else {
stream_->Inc();
}
}
public:
pure_impure_helper(IfcParse::IfcSpfStream* stream)
: pure_(false), stream_(stream), pointer_(reference_helper)
{}
public:
pure_impure_helper(IfcParse::IfcSpfStream* stream)
: pure_(false),
stream_(stream),
pointer_(reference_helper) {}
pure_impure_helper(IfcParse::IfcSpfStream* stream, unsigned int& pointer)
: pure_(true), stream_(stream), pointer_(pointer)
{}
pure_impure_helper(IfcParse::IfcSpfStream* stream, unsigned int& pointer)
: pure_(true),
stream_(stream),
pointer_(pointer) {}
std::string get(IfcParse::IfcCharacterDecoder::ConversionMode mode, char substitution_character) {
unsigned int parse_state = 0;
builder_.clear();
builder_.push_back('\'');
char current_char;
int codepage = 1;
unsigned int hex = 0;
unsigned int hex_count = 0;
std::string get(IfcParse::IfcCharacterDecoder::ConversionMode mode, char substitution_character) {
unsigned int parse_state = 0;
builder_.clear();
builder_.push_back('\'');
char current_char;
int codepage = 1;
unsigned int hex = 0;
unsigned int hex_count = 0;
while ((current_char = peek()) != 0) {
if (EXPECTS_CHARACTER(parse_state)) {
builder_.push_back(IfcUtil::convert_codepage(codepage, current_char + 0x80));
parse_state = 0;
} else if (current_char == '\'' && !parse_state) {
parse_state = APOSTROPHE;
} else if (current_char == '\\' && !parse_state) {
parse_state = FIRST_SOLIDUS;
} else if (current_char == '\\' && EXPECTS_SOLIDUS(parse_state)) {
if (parse_state & ALPHABET_DEFINITION ||
parse_state & IGNORED_DIRECTIVE ||
parse_state & ENDEXTENDED_0) parse_state = hex = hex_count = 0;
else if (parse_state & ENCOUNTERED_HEX) {
parse_state += THIRD_SOLIDUS;
parse_state -= ENCOUNTERED_HEX;
} else parse_state += SECOND_SOLIDUS;
} else if (current_char == 'X' && EXPECTS_ENDEXTENDED_X(parse_state)) {
parse_state += ENDEXTENDED_X;
} else if (current_char == '0' && EXPECTS_ENDEXTENDED_0(parse_state)) {
parse_state += ENDEXTENDED_0;
} else if (current_char == 'X' && EXPECTS_ARBITRARY(parse_state)) {
parse_state += ARBITRARY;
} else if (current_char == '2' && EXPECTS_ARBITRARY2(parse_state)) {
parse_state += EXTENDED2;
} else if (current_char == '4' && EXPECTS_ARBITRARY2(parse_state)) {
parse_state += EXTENDED2 + EXTENDED4;
} else if (current_char == 'P' && EXPECTS_ALPHABET(parse_state)) {
parse_state += ALPHABET;
} else if ((current_char == 'N' || current_char == 'F') && EXPECTS_N_OR_F(parse_state)) {
parse_state += IGNORED_DIRECTIVE;
} else if (IS_VALID_ALPHABET_DEFINITION(current_char) && EXPECTS_ALPHABET_DEFINITION(parse_state)) {
codepage = current_char - 0x40;
parse_state += ALPHABET_DEFINITION;
} else if (current_char == 'S' && EXPECTS_PAGE(parse_state)) {
parse_state += PAGE;
} else if (IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state)) {
hex <<= 4;
parse_state += HEX((++hex_count));
hex += HEX_TO_INT(current_char);
if ((hex_count == 2 && !(parse_state & EXTENDED2)) ||
(hex_count == 4 && !(parse_state & EXTENDED4)) ||
(hex_count == 8)) {
builder_.push_back(hex);
if (hex_count == 2) parse_state = 0;
else {
CLEAR_HEX(parse_state);
parse_state |= ENCOUNTERED_HEX;
}
hex = hex_count = 0;
}
} else if (parse_state && !(
(current_char == '\\' && parse_state == FIRST_SOLIDUS) ||
(current_char == '\'' && parse_state == APOSTROPHE)
)) {
if (parse_state == APOSTROPHE && current_char != '\'') break;
throw IfcInvalidTokenException(tell(), current_char);
} else {
parse_state = hex = hex_count = 0;
builder_.push_back(current_char);
}
increment();
}
builder_.push_back('\'');
while ((current_char = peek()) != 0) {
if (EXPECTS_CHARACTER(parse_state)) {
builder_.push_back(IfcUtil::convert_codepage(codepage, current_char + 0x80));
parse_state = 0;
} else if (current_char == '\'' && !parse_state) {
parse_state = APOSTROPHE;
} else if (current_char == '\\' && !parse_state) {
parse_state = FIRST_SOLIDUS;
} else if (current_char == '\\' && EXPECTS_SOLIDUS(parse_state)) {
if (parse_state & ALPHABET_DEFINITION ||
parse_state & IGNORED_DIRECTIVE ||
parse_state & ENDEXTENDED_0) {
parse_state = hex = hex_count = 0;
} else if (parse_state & ENCOUNTERED_HEX) {
parse_state += THIRD_SOLIDUS;
parse_state -= ENCOUNTERED_HEX;
} else {
parse_state += SECOND_SOLIDUS;
}
} else if (current_char == 'X' && EXPECTS_ENDEXTENDED_X(parse_state)) {
parse_state += ENDEXTENDED_X;
} else if (current_char == '0' && EXPECTS_ENDEXTENDED_0(parse_state)) {
parse_state += ENDEXTENDED_0;
} else if (current_char == 'X' && EXPECTS_ARBITRARY(parse_state)) {
parse_state += ARBITRARY;
} else if (current_char == '2' && EXPECTS_ARBITRARY2(parse_state)) {
parse_state += EXTENDED2;
} else if (current_char == '4' && EXPECTS_ARBITRARY2(parse_state)) {
parse_state += EXTENDED2 + EXTENDED4;
} else if (current_char == 'P' && EXPECTS_ALPHABET(parse_state)) {
parse_state += ALPHABET;
} else if ((current_char == 'N' || current_char == 'F') && EXPECTS_N_OR_F(parse_state)) {
parse_state += IGNORED_DIRECTIVE;
} else if (IS_VALID_ALPHABET_DEFINITION(current_char) && EXPECTS_ALPHABET_DEFINITION(parse_state)) {
codepage = current_char - 0x40;
parse_state += ALPHABET_DEFINITION;
} else if (current_char == 'S' && EXPECTS_PAGE(parse_state)) {
parse_state += PAGE;
} else if (IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state)) {
hex <<= 4;
parse_state += HEX((++hex_count));
hex += HEX_TO_INT(current_char);
if ((hex_count == 2 && !(parse_state & EXTENDED2)) ||
(hex_count == 4 && !(parse_state & EXTENDED4)) ||
(hex_count == 8)) {
builder_.push_back(hex);
if (hex_count == 2) {
parse_state = 0;
} else {
CLEAR_HEX(parse_state);
parse_state |= ENCOUNTERED_HEX;
}
hex = hex_count = 0;
}
} else if (parse_state && !(
(current_char == '\\' && parse_state == FIRST_SOLIDUS) ||
(current_char == '\'' && parse_state == APOSTROPHE))) {
if (parse_state == APOSTROPHE && current_char != '\'') {
break;
}
throw IfcInvalidTokenException(tell(), current_char);
} else {
parse_state = hex = hex_count = 0;
builder_.push_back(current_char);
}
increment();
}
builder_.push_back('\'');
if (mode == IfcParse::IfcCharacterDecoder::UTF8) {
if (builder_.empty()) {
static std::string empty;
return empty;
} else {
auto it = std::max_element(builder_.begin(), builder_.end());
if (*it <= 0x7e) {
std::string r(builder_.begin(), builder_.end());
return r;
} else {
return IfcUtil::convert_utf8(builder_);
}
}
} else if (mode == IfcParse::IfcCharacterDecoder::SUBSTITUTE) {
std::string r;
r.reserve(builder_.size());
std::transform(builder_.begin(), builder_.end(), std::back_inserter(r), [&substitution_character](wchar_t c) {
if (c >= 0x20 && c <= 0x7e) {
return (char)c;
} else {
return substitution_character;
}
});
return r;
} else if (mode == IfcParse::IfcCharacterDecoder::ESCAPE) {
std::stringstream str;
str << std::hex << std::setw(4) << std::setfill('0');
std::for_each(builder_.begin(), builder_.end(), [&str](wchar_t c) {
if (c >= 0x20 && c <= 0x7e) {
str.put((char)c);
} else {
str << "\\u" << c;
}
});
return str.str();
} else {
throw IfcParse::IfcException("Invalid conversion mode");
}
}
};
}
if (mode == IfcParse::IfcCharacterDecoder::UTF8) {
if (builder_.empty()) {
static std::string empty;
return empty;
} else {
auto it = std::max_element(builder_.begin(), builder_.end());
if (*it <= 0x7e) {
std::string r(builder_.begin(), builder_.end());
return r;
} else {
return IfcUtil::convert_utf8(builder_);
}
}
} else if (mode == IfcParse::IfcCharacterDecoder::SUBSTITUTE) {
std::string r;
r.reserve(builder_.size());
std::transform(builder_.begin(), builder_.end(), std::back_inserter(r), [&substitution_character](wchar_t c) {
if (c >= 0x20 && c <= 0x7e) {
return (char)c;
} else {
return substitution_character;
}
});
return r;
} else if (mode == IfcParse::IfcCharacterDecoder::ESCAPE) {
std::stringstream str;
str << std::hex << std::setw(4) << std::setfill('0');
std::for_each(builder_.begin(), builder_.end(), [&str](wchar_t c) {
if (c >= 0x20 && c <= 0x7e) {
str.put((char)c);
} else {
str << "\\u" << c;
}
});
return str.str();
} else {
throw IfcParse::IfcException("Invalid conversion mode");
}
}
};
} // namespace
IfcCharacterDecoder::operator std::string() {
return pure_impure_helper(file).get(mode, substitution_character);
return pure_impure_helper(file).get(mode, substitution_character);
}
std::string IfcCharacterDecoder::get(unsigned int& ptr) {
return pure_impure_helper(file, ptr).get(mode, substitution_character);
return pure_impure_helper(file, ptr).get(mode, substitution_character);
}
void IfcCharacterDecoder::skip() {
unsigned int parse_state = 0;
char current_char;
unsigned int hex_count = 0;
while ((current_char = file->Peek()) != 0) {
if ( EXPECTS_CHARACTER(parse_state) ) {
parse_state = 0;
} else if ( current_char == '\'' && ! parse_state ) {
parse_state = APOSTROPHE;
} else if ( current_char == '\\' && ! parse_state ) {
parse_state = FIRST_SOLIDUS;
} else if ( current_char == '\\' && EXPECTS_SOLIDUS(parse_state) ) {
if ( parse_state & ALPHABET_DEFINITION ||
parse_state & IGNORED_DIRECTIVE ||
parse_state & ENDEXTENDED_0 ) parse_state = hex_count = 0;
else if ( parse_state & ENCOUNTERED_HEX ) {
parse_state += THIRD_SOLIDUS;
parse_state -= ENCOUNTERED_HEX;
}
else parse_state += SECOND_SOLIDUS;
} else if ( current_char == 'X' && EXPECTS_ENDEXTENDED_X(parse_state) ) {
parse_state += ENDEXTENDED_X;
} else if ( current_char == '0' && EXPECTS_ENDEXTENDED_0(parse_state) ) {
parse_state += ENDEXTENDED_0;
} else if ( current_char == 'X' && EXPECTS_ARBITRARY(parse_state) ) {
parse_state += ARBITRARY;
} else if ( current_char == '2' && EXPECTS_ARBITRARY2(parse_state) ) {
parse_state += EXTENDED2;
} else if ( current_char == '4' && EXPECTS_ARBITRARY2(parse_state) ) {
parse_state += EXTENDED2 + EXTENDED4;
} else if ( current_char == 'P' && EXPECTS_ALPHABET(parse_state) ) {
parse_state += ALPHABET;
} else if ( (current_char == 'N' || current_char == 'F') && EXPECTS_N_OR_F(parse_state) ) {
parse_state += IGNORED_DIRECTIVE;
} else if ( IS_VALID_ALPHABET_DEFINITION(current_char) && EXPECTS_ALPHABET_DEFINITION(parse_state) ) {
parse_state += ALPHABET_DEFINITION;
} else if ( current_char == 'S' && EXPECTS_PAGE(parse_state) ) {
parse_state += PAGE;
} else if ( IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state) ) {
parse_state += HEX((++hex_count));
if ( (hex_count == 2 && !(parse_state & EXTENDED2)) ||
(hex_count == 4 && !(parse_state & EXTENDED4)) ||
(hex_count == 8) ) {
if ( hex_count == 2 ) parse_state = 0;
else {
CLEAR_HEX(parse_state);
parse_state |= ENCOUNTERED_HEX;
}
hex_count = 0;
}
} else if ( parse_state && !(
(current_char == '\\' && parse_state == FIRST_SOLIDUS) ||
(current_char == '\'' && parse_state == APOSTROPHE)
) ) {
if ( parse_state == APOSTROPHE && current_char != '\'' ) break;
throw IfcInvalidTokenException(file->Tell(), current_char);
} else {
parse_state = hex_count = 0;
}
file->Inc();
}
unsigned int parse_state = 0;
char current_char;
unsigned int hex_count = 0;
while ((current_char = file->Peek()) != 0) {
if (EXPECTS_CHARACTER(parse_state)) {
parse_state = 0;
} else if (current_char == '\'' && !parse_state) {
parse_state = APOSTROPHE;
} else if (current_char == '\\' && !parse_state) {
parse_state = FIRST_SOLIDUS;
} else if (current_char == '\\' && EXPECTS_SOLIDUS(parse_state)) {
if (parse_state & ALPHABET_DEFINITION ||
parse_state & IGNORED_DIRECTIVE ||
parse_state & ENDEXTENDED_0) {
parse_state = hex_count = 0;
} else if (parse_state & ENCOUNTERED_HEX) {
parse_state += THIRD_SOLIDUS;
parse_state -= ENCOUNTERED_HEX;
} else {
parse_state += SECOND_SOLIDUS;
}
} else if (current_char == 'X' && EXPECTS_ENDEXTENDED_X(parse_state)) {
parse_state += ENDEXTENDED_X;
} else if (current_char == '0' && EXPECTS_ENDEXTENDED_0(parse_state)) {
parse_state += ENDEXTENDED_0;
} else if (current_char == 'X' && EXPECTS_ARBITRARY(parse_state)) {
parse_state += ARBITRARY;
} else if (current_char == '2' && EXPECTS_ARBITRARY2(parse_state)) {
parse_state += EXTENDED2;
} else if (current_char == '4' && EXPECTS_ARBITRARY2(parse_state)) {
parse_state += EXTENDED2 + EXTENDED4;
} else if (current_char == 'P' && EXPECTS_ALPHABET(parse_state)) {
parse_state += ALPHABET;
} else if ((current_char == 'N' || current_char == 'F') && EXPECTS_N_OR_F(parse_state)) {
parse_state += IGNORED_DIRECTIVE;
} else if (IS_VALID_ALPHABET_DEFINITION(current_char) && EXPECTS_ALPHABET_DEFINITION(parse_state)) {
parse_state += ALPHABET_DEFINITION;
} else if (current_char == 'S' && EXPECTS_PAGE(parse_state)) {
parse_state += PAGE;
} else if (IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state)) {
parse_state += HEX((++hex_count));
if ((hex_count == 2 && !(parse_state & EXTENDED2)) ||
(hex_count == 4 && !(parse_state & EXTENDED4)) ||
(hex_count == 8)) {
if (hex_count == 2) {
parse_state = 0;
} else {
CLEAR_HEX(parse_state);
parse_state |= ENCOUNTERED_HEX;
}
hex_count = 0;
}
} else if (parse_state && !(
(current_char == '\\' && parse_state == FIRST_SOLIDUS) ||
(current_char == '\'' && parse_state == APOSTROPHE))) {
if (parse_state == APOSTROPHE && current_char != '\'') {
break;
}
throw IfcInvalidTokenException(file->Tell(), current_char);
} else {
parse_state = hex_count = 0;
}
file->Inc();
}
}
IfcCharacterDecoder::ConversionMode IfcCharacterDecoder::mode = IfcCharacterDecoder::UTF8;
char IfcCharacterDecoder::substitution_character = '_';
IfcCharacterEncoder::IfcCharacterEncoder(const std::string& input)
: str(IfcUtil::convert_utf8_to_utf32(input)) {}
: str(IfcUtil::convert_utf8_to_utf32(input)) {}
IfcCharacterEncoder::operator std::string() {
std::ostringstream oss;
oss.put('\'');
std::ostringstream oss;
oss.put('\'');
// Either 2 or 4 to uses \X2 or \X4 respectively.
// Currently hardcoded to 4, but \X2 might be
// sufficient for nearly all purposes.
const int num_bytes = (str.empty() || (*std::max_element(str.begin(), str.end()) > 0xffff)) ? 4 : 2;
const std::string num_bytes_str = std::string(1,num_bytes + 0x30);
bool in_extended = false;
// Either 2 or 4 to uses \X2 or \X4 respectively.
// Currently hardcoded to 4, but \X2 might be
// sufficient for nearly all purposes.
const int num_bytes = (str.empty() || (*std::max_element(str.begin(), str.end()) > 0xffff)) ? 4 : 2;
const std::string num_bytes_str = std::string(1, num_bytes + 0x30);
for (auto it = str.begin(); it != str.end(); ++it) {
auto ch = *it;
const bool within_spf_range = ch >= 0x20 && ch <= 0x7e;
if ( in_extended && within_spf_range ) {
oss << "\\X0\\";
} else if ( !in_extended && !within_spf_range ) {
oss << "\\X" << num_bytes_str << "\\";
}
if ( within_spf_range ) {
oss.put((char)ch);
if ( ch == '\\' || ch == '\'' ) oss.put((char)ch);
} else {
oss << std::hex << std::setw(num_bytes*2) << std::uppercase << std::setfill('0') << (int) ch;
}
in_extended = !within_spf_range;
}
bool in_extended = false;
if ( in_extended ) oss << "\\X0\\";
for (auto it = str.begin(); it != str.end(); ++it) {
auto ch = *it;
const bool within_spf_range = ch >= 0x20 && ch <= 0x7e;
if (in_extended && within_spf_range) {
oss << "\\X0\\";
} else if (!in_extended && !within_spf_range) {
oss << "\\X" << num_bytes_str << "\\";
}
if (within_spf_range) {
oss.put((char)ch);
if (ch == '\\' || ch == '\'') {
oss.put((char)ch);
}
} else {
oss << std::hex << std::setw(num_bytes * 2) << std::uppercase << std::setfill('0') << (int)ch;
}
in_extended = !within_spf_range;
}
oss.put('\'');
return oss.str();
if (in_extended) {
oss << "\\X0\\";
}
oss.put('\'');
return oss.str();
}
/*
@@ -364,43 +379,41 @@ def _():
"{%s}" % ",".join(_())
*/
std::wstring::value_type IfcUtil::convert_codepage(int codepage, int c) {
if (codepage < 1 || codepage > 16 || codepage == 12) {
throw IfcParse::IfcException("Invalid codepage");
}
if (c < 0 || c > 255) {
throw IfcParse::IfcException("Invalid character ordinal");
}
static std::array<std::array<wchar_t, 256>, 16> codepage_data = { {
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 728, 321, 164, 317, 346, 167, 168, 352, 350, 356, 377, 173, 381, 379, 176, 261, 731, 322, 180, 318, 347, 711, 184, 353, 351, 357, 378, 733, 382, 380, 340, 193, 194, 258, 196, 313, 262, 199, 268, 201, 280, 203, 282, 205, 206, 270, 272, 323, 327, 211, 212, 336, 214, 215, 344, 366, 218, 368, 220, 221, 354, 223, 341, 225, 226, 259, 228, 314, 263, 231, 269, 233, 281, 235, 283, 237, 238, 271, 273, 324, 328, 243, 244, 337, 246, 247, 345, 367, 250, 369, 252, 253, 355, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 294, 728, 163, 164, 0, 292, 167, 168, 304, 350, 286, 308, 173, 0, 379, 176, 295, 178, 179, 180, 181, 293, 183, 184, 305, 351, 287, 309, 189, 0, 380, 192, 193, 194, 0, 196, 266, 264, 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, 209, 210, 211, 212, 288, 214, 215, 284, 217, 218, 219, 220, 364, 348, 223, 224, 225, 226, 0, 228, 267, 265, 231, 232, 233, 234, 235, 236, 237, 238, 239, 0, 241, 242, 243, 244, 289, 246, 247, 285, 249, 250, 251, 252, 365, 349, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 312, 342, 164, 296, 315, 167, 168, 352, 274, 290, 358, 173, 381, 175, 176, 261, 731, 343, 180, 297, 316, 711, 184, 353, 275, 291, 359, 330, 382, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 298, 272, 325, 332, 310, 212, 213, 214, 215, 216, 370, 218, 219, 220, 360, 362, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 299, 273, 326, 333, 311, 244, 245, 246, 247, 248, 371, 250, 251, 252, 361, 363, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 173, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 8470, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 167, 1118, 1119}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 1548, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1563, 0, 0, 0, 1567, 0, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 0, 0, 0, 0, 0, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 8216, 8217, 163, 8364, 8367, 166, 167, 168, 169, 890, 171, 172, 173, 0, 8213, 176, 177, 178, 179, 900, 901, 902, 183, 904, 905, 906, 187, 908, 189, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 0, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, 162, 163, 164, 165, 166, 167, 168, 169, 215, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 247, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8215, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 0, 0, 8206, 8207, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 286, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 304, 350, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 287, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 305, 351, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 274, 290, 298, 296, 310, 167, 315, 272, 352, 358, 381, 173, 362, 330, 176, 261, 275, 291, 299, 297, 311, 183, 316, 273, 353, 359, 382, 8213, 363, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 207, 208, 325, 332, 211, 212, 213, 214, 360, 216, 370, 218, 219, 220, 221, 222, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 239, 240, 326, 333, 243, 244, 245, 246, 361, 248, 371, 250, 251, 252, 253, 254, 312}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 0, 0, 0, 0, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 0, 0, 0, 0}},
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 8221, 162, 163, 164, 8222, 166, 167, 216, 169, 342, 171, 172, 173, 174, 198, 176, 177, 178, 179, 8220, 181, 182, 183, 248, 185, 343, 187, 188, 189, 190, 230, 260, 302, 256, 262, 196, 197, 280, 274, 268, 201, 377, 278, 290, 310, 298, 315, 352, 323, 325, 211, 332, 213, 214, 215, 370, 321, 346, 362, 220, 379, 381, 223, 261, 303, 257, 263, 228, 229, 281, 275, 269, 233, 378, 279, 291, 311, 299, 316, 353, 324, 326, 243, 333, 245, 246, 247, 371, 322, 347, 363, 252, 380, 382, 8217}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 7682, 7683, 163, 266, 267, 7690, 167, 7808, 169, 7810, 7691, 7922, 173, 174, 376, 7710, 7711, 288, 289, 7744, 7745, 182, 7766, 7809, 7767, 7811, 7776, 7923, 7812, 7813, 7777, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 372, 209, 210, 211, 212, 213, 214, 7786, 216, 217, 218, 219, 220, 221, 374, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 373, 241, 242, 243, 244, 245, 246, 7787, 248, 249, 250, 251, 252, 253, 375, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 8364, 165, 352, 167, 353, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 381, 181, 182, 183, 382, 185, 186, 187, 338, 339, 376, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 261, 321, 8364, 8222, 352, 167, 353, 169, 536, 171, 377, 173, 378, 379, 176, 177, 268, 322, 381, 8221, 182, 183, 382, 269, 537, 187, 338, 339, 376, 380, 192, 193, 194, 258, 196, 262, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 272, 323, 210, 211, 212, 336, 214, 346, 368, 217, 218, 219, 220, 280, 538, 223, 224, 225, 226, 259, 228, 263, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 273, 324, 242, 243, 244, 337, 246, 347, 369, 249, 250, 251, 252, 281, 539, 255}}
}};
auto r = codepage_data[codepage - 1][c];
if (r == 0) {
throw IfcParse::IfcException("Character not defined");
}
return r;
if (codepage < 1 || codepage > 16 || codepage == 12) {
throw IfcParse::IfcException("Invalid codepage");
}
if (c < 0 || c > 255) {
throw IfcParse::IfcException("Invalid character ordinal");
}
static std::array<std::array<wchar_t, 256>, 16> codepage_data = {{{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 728, 321, 164, 317, 346, 167, 168, 352, 350, 356, 377, 173, 381, 379, 176, 261, 731, 322, 180, 318, 347, 711, 184, 353, 351, 357, 378, 733, 382, 380, 340, 193, 194, 258, 196, 313, 262, 199, 268, 201, 280, 203, 282, 205, 206, 270, 272, 323, 327, 211, 212, 336, 214, 215, 344, 366, 218, 368, 220, 221, 354, 223, 341, 225, 226, 259, 228, 314, 263, 231, 269, 233, 281, 235, 283, 237, 238, 271, 273, 324, 328, 243, 244, 337, 246, 247, 345, 367, 250, 369, 252, 253, 355, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 294, 728, 163, 164, 0, 292, 167, 168, 304, 350, 286, 308, 173, 0, 379, 176, 295, 178, 179, 180, 181, 293, 183, 184, 305, 351, 287, 309, 189, 0, 380, 192, 193, 194, 0, 196, 266, 264, 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, 209, 210, 211, 212, 288, 214, 215, 284, 217, 218, 219, 220, 364, 348, 223, 224, 225, 226, 0, 228, 267, 265, 231, 232, 233, 234, 235, 236, 237, 238, 239, 0, 241, 242, 243, 244, 289, 246, 247, 285, 249, 250, 251, 252, 365, 349, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 312, 342, 164, 296, 315, 167, 168, 352, 274, 290, 358, 173, 381, 175, 176, 261, 731, 343, 180, 297, 316, 711, 184, 353, 275, 291, 359, 330, 382, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 298, 272, 325, 332, 310, 212, 213, 214, 215, 216, 370, 218, 219, 220, 360, 362, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 299, 273, 326, 333, 311, 244, 245, 246, 247, 248, 371, 250, 251, 252, 361, 363, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 173, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 8470, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 167, 1118, 1119}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 1548, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1563, 0, 0, 0, 1567, 0, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 0, 0, 0, 0, 0, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 8216, 8217, 163, 8364, 8367, 166, 167, 168, 169, 890, 171, 172, 173, 0, 8213, 176, 177, 178, 179, 900, 901, 902, 183, 904, 905, 906, 187, 908, 189, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 0, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, 162, 163, 164, 165, 166, 167, 168, 169, 215, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 247, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8215, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 0, 0, 8206, 8207, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 286, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 304, 350, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 287, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 305, 351, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 274, 290, 298, 296, 310, 167, 315, 272, 352, 358, 381, 173, 362, 330, 176, 261, 275, 291, 299, 297, 311, 183, 316, 273, 353, 359, 382, 8213, 363, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 207, 208, 325, 332, 211, 212, 213, 214, 360, 216, 370, 218, 219, 220, 221, 222, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 239, 240, 326, 333, 243, 244, 245, 246, 361, 248, 371, 250, 251, 252, 253, 254, 312}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 0, 0, 0, 0, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 0, 0, 0, 0}},
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 8221, 162, 163, 164, 8222, 166, 167, 216, 169, 342, 171, 172, 173, 174, 198, 176, 177, 178, 179, 8220, 181, 182, 183, 248, 185, 343, 187, 188, 189, 190, 230, 260, 302, 256, 262, 196, 197, 280, 274, 268, 201, 377, 278, 290, 310, 298, 315, 352, 323, 325, 211, 332, 213, 214, 215, 370, 321, 346, 362, 220, 379, 381, 223, 261, 303, 257, 263, 228, 229, 281, 275, 269, 233, 378, 279, 291, 311, 299, 316, 353, 324, 326, 243, 333, 245, 246, 247, 371, 322, 347, 363, 252, 380, 382, 8217}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 7682, 7683, 163, 266, 267, 7690, 167, 7808, 169, 7810, 7691, 7922, 173, 174, 376, 7710, 7711, 288, 289, 7744, 7745, 182, 7766, 7809, 7767, 7811, 7776, 7923, 7812, 7813, 7777, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 372, 209, 210, 211, 212, 213, 214, 7786, 216, 217, 218, 219, 220, 221, 374, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 373, 241, 242, 243, 244, 245, 246, 7787, 248, 249, 250, 251, 252, 253, 375, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 8364, 165, 352, 167, 353, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 381, 181, 182, 183, 382, 185, 186, 187, 338, 339, 376, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 261, 321, 8364, 8222, 352, 167, 353, 169, 536, 171, 377, 173, 378, 379, 176, 177, 268, 322, 381, 8221, 182, 183, 382, 269, 537, 187, 338, 339, 376, 380, 192, 193, 194, 258, 196, 262, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 272, 323, 210, 211, 212, 336, 214, 346, 368, 217, 218, 219, 220, 280, 538, 223, 224, 225, 226, 259, 228, 263, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 273, 324, 242, 243, 244, 337, 246, 347, 369, 249, 250, 251, 252, 281, 539, 255}}}};
auto r = codepage_data[codepage - 1][c];
if (r == 0) {
throw IfcParse::IfcException("Character not defined");
}
return r;
}
std::string IfcUtil::convert_utf8(const std::wstring& s) {
return std::wstring_convert<std::codecvt_utf8<std::wstring::value_type>>().to_bytes(s);
return std::wstring_convert<std::codecvt_utf8<std::wstring::value_type>>().to_bytes(s);
}
std::wstring IfcUtil::convert_utf8(const std::string& s) {
return std::wstring_convert<std::codecvt_utf8<std::wstring::value_type>>().from_bytes(s);
return std::wstring_convert<std::codecvt_utf8<std::wstring::value_type>>().from_bytes(s);
}
#ifdef _MSC_VER
@@ -408,14 +421,14 @@ std::wstring IfcUtil::convert_utf8(const std::string& s) {
// bug in msvc 2015 and 2017, unsure if fixed in later versions
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
return std::u32string(reinterpret_cast<char32_t const *>(converted.data()));
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
return std::u32string(reinterpret_cast<char32_t const*>(converted.data()));
}
#else
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(s);
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(s);
}
#endif
#endif
+43 -37
View File
@@ -27,53 +27,59 @@
#ifndef IFCCHARACTERDECODER_H
#define IFCCHARACTERDECODER_H
#include <string>
#include <sstream>
#include "IfcSpfStream.h"
#include "../ifcparse/IfcSpfStream.h"
#include <sstream>
#include <string>
namespace IfcUtil {
std::wstring::value_type convert_codepage(int codepage, int c);
std::string convert_utf8(const std::wstring& s);
std::wstring convert_utf8(const std::string& s);
std::u32string convert_utf8_to_utf32(const std::string& s);
}
std::wstring::value_type convert_codepage(int codepage, int c);
std::string convert_utf8(const std::wstring& s);
std::wstring convert_utf8(const std::string& s);
std::u32string convert_utf8_to_utf32(const std::string& s);
} // namespace IfcUtil
namespace IfcParse {
class IFC_PARSE_API IfcCharacterDecoder {
private:
IfcParse::IfcSpfStream* file;
int codepage_;
public:
enum ConversionMode {SUBSTITUTE, UTF8, ESCAPE};
static ConversionMode mode;
static char substitution_character;
IfcCharacterDecoder(IfcParse::IfcSpfStream* file);
~IfcCharacterDecoder();
// Only advances the underlying token stream read pointer
// to the next token.
void skip();
// Gets a decoded string representation at the token stream
// read pointer and advances the underlying token stream.
operator std::string();
// Gets a decoded string representation at the offset provided,
// does not mutate the underlying token stream read pointer.
std::string get(unsigned int&);
};
class IFC_PARSE_API IfcCharacterDecoder {
private:
IfcParse::IfcSpfStream* file;
int codepage_;
}
public:
enum ConversionMode {
SUBSTITUTE,
UTF8,
ESCAPE
};
static ConversionMode mode;
static char substitution_character;
IfcCharacterDecoder(IfcParse::IfcSpfStream* file);
~IfcCharacterDecoder();
// Only advances the underlying token stream read pointer
// to the next token.
void skip();
// Gets a decoded string representation at the token stream
// read pointer and advances the underlying token stream.
operator std::string();
// Gets a decoded string representation at the offset provided,
// does not mutate the underlying token stream read pointer.
std::string get(unsigned int&);
};
} // namespace IfcParse
namespace IfcWrite {
class IFC_PARSE_API IfcCharacterEncoder {
private:
std::u32string str;
public:
IfcCharacterEncoder(const std::string& input);
operator std::string();
};
class IFC_PARSE_API IfcCharacterEncoder {
private:
std::u32string str;
}
public:
IfcCharacterEncoder(const std::string& input);
operator std::string();
};
} // namespace IfcWrite
#endif
+57 -48
View File
@@ -20,81 +20,90 @@
#ifndef IFCENTITYINSTANCEDATA_H
#define IFCENTITYINSTANCEDATA_H
#include "../ifcparse/ArgumentType.h"
#include "ArgumentType.h"
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
class Argument;
class aggregate_of_instance;
namespace IfcParse {
class IfcFile;
class IfcFile;
}
class IFC_PARSE_API IfcEntityInstanceData {
public:
// Public for backwards compatibility
IfcParse::IfcFile* file;
protected:
unsigned id_;
const IfcParse::declaration* type_;
mutable Argument** attributes_;
unsigned offset_in_file_;
public:
// Public for backwards compatibility
IfcParse::IfcFile* file;
public:
IfcEntityInstanceData(const IfcParse::declaration* type, IfcParse::IfcFile* file_, unsigned id = 0, unsigned offset_in_file = 0)
: file(file_), id_(id), type_(type), attributes_(0), offset_in_file_(offset_in_file)
{}
protected:
unsigned id_;
const IfcParse::declaration* type_;
mutable Argument** attributes_;
unsigned offset_in_file_;
IfcEntityInstanceData(IfcParse::IfcFile* file_, size_t size)
: file(file_), id_(0), type_(0), attributes_(new Argument*[size] {0}), offset_in_file_(0)
{}
public:
IfcEntityInstanceData(const IfcParse::declaration* type, IfcParse::IfcFile* file_, unsigned id = 0, unsigned offset_in_file = 0)
: file(file_),
id_(id),
type_(type),
attributes_(0),
offset_in_file_(offset_in_file) {}
IfcEntityInstanceData(const IfcParse::declaration* type)
: file(0), id_(0), type_(type), attributes_(new Argument*[getArgumentCount()]{ 0 }), offset_in_file_(0)
{}
IfcEntityInstanceData(IfcParse::IfcFile* file_, size_t size)
: file(file_),
id_(0),
type_(0),
attributes_(new Argument* [size] { 0 }),
offset_in_file_(0) {}
void load() const;
IfcEntityInstanceData(const IfcParse::declaration* type)
: file(0),
id_(0),
type_(type),
attributes_(new Argument* [getArgumentCount()] { 0 }),
offset_in_file_(0) {}
IfcEntityInstanceData(const IfcEntityInstanceData& e);
void load() const;
virtual ~IfcEntityInstanceData();
IfcEntityInstanceData(const IfcEntityInstanceData& e);
boost::shared_ptr<aggregate_of_instance> getInverse (const IfcParse::declaration* type, int attribute_index) const;
virtual ~IfcEntityInstanceData();
Argument* getArgument(size_t i) const;
boost::shared_ptr<aggregate_of_instance> getInverse(const IfcParse::declaration* type, int attribute_index) const;
// NB: This makes a copy of the argument if make_copy is set
void setArgument(size_t i, Argument* a, IfcUtil::ArgumentType attr_type = IfcUtil::Argument_UNKNOWN, bool make_copy = false);
Argument* getArgument(size_t i) const;
virtual size_t getArgumentCount() const {
if (type_ == 0) {
return 0;
}
if (type_->as_entity()) {
return type_->as_entity()->attribute_count();
} else {
return 1;
}
}
// NB: This makes a copy of the argument if make_copy is set
void setArgument(size_t i, Argument* a, IfcUtil::ArgumentType attr_type = IfcUtil::Argument_UNKNOWN, bool make_copy = false);
void clearArguments();
virtual size_t getArgumentCount() const {
if (type_ == 0) {
return 0;
}
if (type_->as_entity()) {
return type_->as_entity()->attribute_count();
} else {
return 1;
}
}
const IfcParse::declaration* type() const {
return type_;
}
void clearArguments();
std::string toString(bool upper = false) const;
const IfcParse::declaration* type() const {
return type_;
}
unsigned int id() const { return id_; }
unsigned int offset_in_file() const { return offset_in_file_; }
std::string toString(bool upper = false) const;
// NB: const ommitted for lazy loading
Argument**& attributes() const { return attributes_; }
unsigned int id() const { return id_; }
unsigned int offset_in_file() const { return offset_in_file_; }
unsigned set_id(boost::optional<unsigned> i = boost::none);
// NB: const ommitted for lazy loading
Argument**& attributes() const { return attributes_; }
unsigned set_id(boost::optional<unsigned> i = boost::none);
};
#endif
+37 -43
View File
@@ -23,7 +23,6 @@
#include "ifc_parse_api.h"
#include <boost/lexical_cast.hpp>
#include <exception>
#include <string>
@@ -35,51 +34,46 @@
#endif
namespace IfcParse {
class IFC_PARSE_API IfcException : public std::exception {
private:
std::string message;
public:
IfcException(const std::string& m)
: message(m) {}
virtual ~IfcException () throw () {}
virtual const char* what() const throw() {
return message.c_str();
}
};
class IFC_PARSE_API IfcException : public std::exception {
private:
std::string message;
class IFC_PARSE_API IfcAttributeOutOfRangeException : public IfcException {
public:
IfcAttributeOutOfRangeException(const std::string& e)
: IfcException(e) {}
~IfcAttributeOutOfRangeException () throw () {}
};
public:
IfcException(const std::string& m)
: message(m) {}
virtual ~IfcException() throw() {}
virtual const char* what() const throw() {
return message.c_str();
}
};
class IFC_PARSE_API IfcInvalidTokenException : public IfcException {
public:
IfcInvalidTokenException(
int token_start,
const std::string& token_string,
const std::string& expected_type
)
: IfcException(
std::string("Token ") + token_string + " at offset " +
boost::lexical_cast<std::string>(token_start) +
" invalid " + expected_type
)
{}
IfcInvalidTokenException(
int token_start,
char c
)
: IfcException(
std::string("Unexpected '") + std::string(1, c) + "' at offset " +
boost::lexical_cast<std::string>(token_start)
)
{}
~IfcInvalidTokenException() throw () {}
};
class IFC_PARSE_API IfcAttributeOutOfRangeException : public IfcException {
public:
IfcAttributeOutOfRangeException(const std::string& e)
: IfcException(e) {}
~IfcAttributeOutOfRangeException() throw() {}
};
}
class IFC_PARSE_API IfcInvalidTokenException : public IfcException {
public:
IfcInvalidTokenException(
int token_start,
const std::string& token_string,
const std::string& expected_type)
: IfcException(
std::string("Token ") + token_string + " at offset " +
boost::lexical_cast<std::string>(token_start) +
" invalid " + expected_type) {}
IfcInvalidTokenException(
int token_start,
char c)
: IfcException(
std::string("Unexpected '") + std::string(1, c) + "' at offset " +
boost::lexical_cast<std::string>(token_start)) {}
~IfcInvalidTokenException() throw() {}
};
} // namespace IfcParse
#ifdef _MSC_VER
#pragma warning(pop)
+237 -233
View File
@@ -20,319 +20,323 @@
#ifndef IFCFILE_H
#define IFCFILE_H
#include <map>
#include <set>
#include <iterator>
#include "ifc_parse_api.h"
#include "IfcParse.h"
#include "IfcSchema.h"
#include "IfcSpfHeader.h"
#include <boost/unordered_map.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include "ifc_parse_api.h"
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcSpfHeader.h"
#include "../ifcparse/IfcSchema.h"
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/unordered_map.hpp>
#include <iterator>
#include <map>
#include <set>
namespace IfcParse {
class IFC_PARSE_API file_open_status {
public:
enum file_open_enum {
SUCCESS,
READ_ERROR,
NO_HEADER,
UNSUPPORTED_SCHEMA
};
public:
enum file_open_enum {
SUCCESS,
READ_ERROR,
NO_HEADER,
UNSUPPORTED_SCHEMA
};
private:
file_open_enum error_;
private:
file_open_enum error_;
public:
file_open_status(file_open_enum error)
: error_(error)
{}
public:
file_open_status(file_open_enum error)
: error_(error) {}
operator file_open_enum() const {
return error_;
}
operator file_open_enum() const {
return error_;
}
file_open_enum value() const {
return error_;
}
file_open_enum value() const {
return error_;
}
operator bool() const {
return error_ == SUCCESS;
}
operator bool() const {
return error_ == SUCCESS;
}
};
/// This class provides several static convenience functions and variables
/// and provide access to the entities in an IFC file
class IFC_PARSE_API IfcFile {
public:
typedef std::map<const IfcParse::declaration*, aggregate_of_instance::ptr> entities_by_type_t;
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
typedef boost::unordered_map<uint32_t, IfcUtil::IfcBaseClass*> entity_by_iden_t;
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
typedef std::tuple<int, int, int> inverse_attr_record;
enum INVERSE_ATTR { INSTANCE_ID, INSTANCE_TYPE, ATTRIBUTE_INDEX };
typedef std::map<inverse_attr_record, std::vector<int> > entities_by_ref_t;
typedef std::map<int, std::vector<int> > entities_by_ref_excl_t;
typedef std::map<unsigned int, aggregate_of_instance::ptr> ref_map_t;
typedef entity_by_id_t::const_iterator const_iterator;
public:
typedef std::map<const IfcParse::declaration*, aggregate_of_instance::ptr> entities_by_type_t;
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
typedef boost::unordered_map<uint32_t, IfcUtil::IfcBaseClass*> entity_by_iden_t;
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
typedef std::tuple<int, int, int> inverse_attr_record;
enum INVERSE_ATTR {
INSTANCE_ID,
INSTANCE_TYPE,
ATTRIBUTE_INDEX
};
typedef std::map<inverse_attr_record, std::vector<int>> entities_by_ref_t;
typedef std::map<int, std::vector<int>> entities_by_ref_excl_t;
typedef std::map<unsigned int, aggregate_of_instance::ptr> ref_map_t;
typedef entity_by_id_t::const_iterator const_iterator;
class type_iterator : private entities_by_type_t::const_iterator {
public:
type_iterator() : entities_by_type_t::const_iterator() {};
class type_iterator : private entities_by_type_t::const_iterator {
public:
type_iterator() : entities_by_type_t::const_iterator(){};
type_iterator(const entities_by_type_t::const_iterator& it)
: entities_by_type_t::const_iterator(it)
{};
type_iterator(const entities_by_type_t::const_iterator& it)
: entities_by_type_t::const_iterator(it){};
entities_by_type_t::key_type const * operator->() const {
return &entities_by_type_t::const_iterator::operator->()->first;
}
entities_by_type_t::key_type const* operator->() const {
return &entities_by_type_t::const_iterator::operator->()->first;
}
entities_by_type_t::key_type const & operator*() const {
return entities_by_type_t::const_iterator::operator*().first;
}
entities_by_type_t::key_type const& operator*() const {
return entities_by_type_t::const_iterator::operator*().first;
}
type_iterator& operator++() {
entities_by_type_t::const_iterator::operator++(); return *this;
}
type_iterator& operator++() {
entities_by_type_t::const_iterator::operator++();
return *this;
}
type_iterator operator++(int) {
type_iterator tmp(*this); operator++(); return tmp;
}
type_iterator operator++(int) {
type_iterator tmp(*this);
operator++();
return tmp;
}
bool operator!=(const type_iterator& other) const {
const entities_by_type_t::const_iterator& self_ = *this;
const entities_by_type_t::const_iterator& other_ = other;
return self_ != other_;
}
};
bool operator!=(const type_iterator& other) const {
const entities_by_type_t::const_iterator& self_ = *this;
const entities_by_type_t::const_iterator& other_ = other;
return self_ != other_;
}
};
static bool lazy_load_;
static bool lazy_load() { return lazy_load_; }
static void lazy_load(bool b) { lazy_load_ = b; }
static bool lazy_load_;
static bool lazy_load() { return lazy_load_; }
static void lazy_load(bool b) { lazy_load_ = b; }
static bool guid_map_;
static bool guid_map() { return guid_map_; }
static void guid_map(bool b) { guid_map_ = b; }
static bool guid_map_;
static bool guid_map() { return guid_map_; }
static void guid_map(bool b) { guid_map_ = b; }
private:
typedef std::map<uint32_t, IfcUtil::IfcBaseClass*> entity_entity_map_t;
private:
typedef std::map<uint32_t, IfcUtil::IfcBaseClass*> entity_entity_map_t;
bool parsing_complete_;
file_open_status good_ = file_open_status::SUCCESS;
bool parsing_complete_;
file_open_status good_ = file_open_status::SUCCESS;
const IfcParse::schema_definition* schema_;
const IfcParse::declaration* ifcroot_type_;
const IfcParse::schema_definition* schema_;
const IfcParse::declaration* ifcroot_type_;
std::vector<Argument*> internal_attribute_vector_, internal_attribute_vector_simple_type_;
std::vector<Argument*> internal_attribute_vector_, internal_attribute_vector_simple_type_;
entity_by_id_t byid;
// this is for simple types
entity_by_iden_t byidentity;
entities_by_type_t bytype;
entities_by_type_t bytype_excl;
entities_by_ref_t byref;
entities_by_ref_excl_t byref_excl;
entity_by_guid_t byguid;
entity_entity_map_t entity_file_map;
entity_by_id_t byid;
// this is for simple types
entity_by_iden_t byidentity;
entities_by_type_t bytype;
entities_by_type_t bytype_excl;
entities_by_ref_t byref;
entities_by_ref_excl_t byref_excl;
entity_by_guid_t byguid;
entity_entity_map_t entity_file_map;
unsigned int MaxId;
unsigned int MaxId;
IfcSpfHeader _header;
IfcSpfHeader _header;
void setDefaultHeaderValues();
void setDefaultHeaderValues();
void initialize_(IfcParse::IfcSpfStream* f);
void initialize_(IfcParse::IfcSpfStream* f);
void build_inverses_(IfcUtil::IfcBaseClass*);
void build_inverses_(IfcUtil::IfcBaseClass*);
typedef boost::multi_index_container<
int,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::ordered_unique<
boost::multi_index::identity<int>
>
>
> batch_deletion_ids_t;
batch_deletion_ids_t batch_deletion_ids_;
bool batch_mode_ = false;
void process_deletion_();
typedef boost::multi_index_container<
int,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::ordered_unique<
boost::multi_index::identity<int>>>>
batch_deletion_ids_t;
batch_deletion_ids_t batch_deletion_ids_;
bool batch_mode_ = false;
void process_deletion_();
public:
IfcParse::IfcSpfLexer* tokens;
IfcParse::IfcSpfStream* stream;
public:
IfcParse::IfcSpfLexer* tokens;
IfcParse::IfcSpfStream* stream;
#ifdef USE_MMAP
IfcFile(const std::string& fn, bool mmap = false);
IfcFile(const std::string& fn, bool mmap = false);
#else
IfcFile(const std::string& fn);
IfcFile(const std::string& fn);
#endif
IfcFile(std::istream& fn, int len);
IfcFile(void* data, int len);
IfcFile(IfcParse::IfcSpfStream* f);
IfcFile(const IfcParse::schema_definition* schema = IfcParse::schema_by_name("IFC4"));
IfcFile(std::istream& fn, int len);
IfcFile(void* data, int len);
IfcFile(IfcParse::IfcSpfStream* f);
IfcFile(const IfcParse::schema_definition* schema = IfcParse::schema_by_name("IFC4"));
/// Deleting the file will also delete all new instances that were added to the file (via memory allocation)
virtual ~IfcFile();
/// Deleting the file will also delete all new instances that were added to the file (via memory allocation)
virtual ~IfcFile();
file_open_status good() const { return good_; }
/// Returns the first entity in the file, this probably is the entity
/// with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator begin() const;
/// Returns the last entity in the file, this probably is the entity
/// with the highest id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator end() const;
file_open_status good() const { return good_; }
type_iterator types_begin() const;
type_iterator types_end() const;
/// Returns the first entity in the file, this probably is the entity
/// with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator begin() const;
/// Returns the last entity in the file, this probably is the entity
/// with the highest id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator end() const;
type_iterator types_incl_super_begin() const;
type_iterator types_incl_super_end() const;
type_iterator types_begin() const;
type_iterator types_end() const;
/// Returns all entities in the file that match the template argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
template <class T>
typename T::list::ptr instances_by_type() {
aggregate_of_instance::ptr untyped_list = instances_by_type(&T::Class());
if (untyped_list) {
return untyped_list->as<T>();
} else {
return typename T::list::ptr(new typename T::list);
}
}
type_iterator types_incl_super_begin() const;
type_iterator types_incl_super_end() const;
template <class T>
typename T::list::ptr instances_by_type_excl_subtypes() {
aggregate_of_instance::ptr untyped_list = instances_by_type_excl_subtypes(&T::Class());
if (untyped_list) {
return untyped_list->as<T>();
} else {
return typename T::list::ptr(new typename T::list);
}
}
/// Returns all entities in the file that match the template argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
template <class T>
typename T::list::ptr instances_by_type() {
aggregate_of_instance::ptr untyped_list = instances_by_type(&T::Class());
if (untyped_list) {
return untyped_list->as<T>();
} else {
return typename T::list::ptr(new typename T::list);
}
}
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
aggregate_of_instance::ptr instances_by_type(const IfcParse::declaration*);
template <class T>
typename T::list::ptr instances_by_type_excl_subtypes() {
aggregate_of_instance::ptr untyped_list = instances_by_type_excl_subtypes(&T::Class());
if (untyped_list) {
return untyped_list->as<T>();
} else {
return typename T::list::ptr(new typename T::list);
}
}
/// Returns all entities in the file that match the positional argument.
aggregate_of_instance::ptr instances_by_type_excl_subtypes(const IfcParse::declaration*);
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
aggregate_of_instance::ptr instances_by_type(const IfcParse::declaration*);
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
aggregate_of_instance::ptr instances_by_type(const std::string& t);
/// Returns all entities in the file that match the positional argument.
aggregate_of_instance::ptr instances_by_type_excl_subtypes(const IfcParse::declaration*);
/// Returns all entities in the file that match the positional argument.
aggregate_of_instance::ptr instances_by_type_excl_subtypes(const std::string& t);
/// Returns all entities in the file that reference the id
aggregate_of_instance::ptr instances_by_reference(int id);
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
aggregate_of_instance::ptr instances_by_type(const std::string& t);
/// Returns the entity with the specified id
IfcUtil::IfcBaseClass* instance_by_id(int id);
/// Returns all entities in the file that match the positional argument.
aggregate_of_instance::ptr instances_by_type_excl_subtypes(const std::string& t);
/// Returns the entity with the specified GlobalId
IfcUtil::IfcBaseClass* instance_by_guid(const std::string& guid);
/// Returns all entities in the file that reference the id
aggregate_of_instance::ptr instances_by_reference(int id);
/// Performs a depth-first traversal, returning all entity instance
/// attributes as a flat list. NB: includes the root instance specified
/// in the first function argument.
aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level=-1);
/// Returns the entity with the specified id
IfcUtil::IfcBaseClass* instance_by_id(int id);
/// Same as traverse() but maintains topological order by using a
/// breadth-first search
aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level=-1);
/// Returns the entity with the specified GlobalId
IfcUtil::IfcBaseClass* instance_by_guid(const std::string& guid);
/// Get the attribute indices corresponding to the list of entity instances
/// returned by getInverse().
std::vector<int> get_inverse_indices(int instance_id);
/// Performs a depth-first traversal, returning all entity instance
/// attributes as a flat list. NB: includes the root instance specified
/// in the first function argument.
aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level = -1);
aggregate_of_instance::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index);
int getTotalInverses(int instance_id);
/// Same as traverse() but maintains topological order by using a
/// breadth-first search
aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level = -1);
template <typename T>
typename T::list::ptr getInverse(int instance_id, int attribute_index) {
return getInverse(instance_id, &T::Class(), attribute_index)->template as<T>();
}
/// Get the attribute indices corresponding to the list of entity instances
/// returned by getInverse().
std::vector<int> get_inverse_indices(int instance_id);
unsigned int FreshId() { return ++MaxId; }
aggregate_of_instance::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index);
unsigned int getMaxId() const { return MaxId; }
int getTotalInverses(int instance_id);
const IfcParse::declaration* ifcroot_type() const { return ifcroot_type_; }
template <typename T>
typename T::list::ptr getInverse(int instance_id, int attribute_index) {
return getInverse(instance_id, &T::Class(), attribute_index)->template as<T>();
}
void recalculate_id_counter();
unsigned int FreshId() { return ++MaxId; }
IfcUtil::IfcBaseClass* addEntity(IfcUtil::IfcBaseClass* entity, int id=-1);
void addEntities(aggregate_of_instance::ptr es);
unsigned int getMaxId() const { return MaxId; }
void batch() { batch_mode_ = true; }
void unbatch() { process_deletion_(); batch_mode_ = false; }
const IfcParse::declaration* ifcroot_type() const { return ifcroot_type_; }
/// Removes entity instance from file and unsets references.
///
/// Attention when running removeEntity inside a loop over a list of entities to be removed.
/// This invalidates the iterator. A workaround is to reverse the loop:
/// boost::shared_ptr<aggregate_of_instance> entities = ...;
/// for (auto it = entities->end() - 1; it >= entities->begin(); --it) {
/// IfcUtil::IfcBaseClass *const inst = *it;
/// model->removeEntity(inst);
/// }
void removeEntity(IfcUtil::IfcBaseClass* entity);
void recalculate_id_counter();
const IfcSpfHeader& header() const { return _header; }
IfcSpfHeader& header() { return _header; }
IfcUtil::IfcBaseClass* addEntity(IfcUtil::IfcBaseClass* entity, int id = -1);
void addEntities(aggregate_of_instance::ptr es);
std::string createTimestamp() const;
void batch() { batch_mode_ = true; }
void unbatch() {
process_deletion_();
batch_mode_ = false;
}
size_t load(unsigned entity_instance_name, const IfcParse::entity* entity, Argument**& attributes, size_t num_attributes, int attribute_index=-1);
void seek_to(const IfcEntityInstanceData& data);
void try_read_semicolon();
/// Removes entity instance from file and unsets references.
///
/// Attention when running removeEntity inside a loop over a list of entities to be removed.
/// This invalidates the iterator. A workaround is to reverse the loop:
/// boost::shared_ptr<aggregate_of_instance> entities = ...;
/// for (auto it = entities->end() - 1; it >= entities->begin(); --it) {
/// IfcUtil::IfcBaseClass *const inst = *it;
/// model->removeEntity(inst);
/// }
void removeEntity(IfcUtil::IfcBaseClass* entity);
void register_inverse(unsigned, const IfcParse::entity* from_entity, Token, int attribute_index);
void register_inverse(unsigned, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass*, int attribute_index);
void unregister_inverse(unsigned, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass*, int attribute_index);
const IfcParse::schema_definition* schema() const { return schema_; }
const IfcSpfHeader& header() const { return _header; }
IfcSpfHeader& header() { return _header; }
std::pair<IfcUtil::IfcBaseClass*, double> getUnit(const std::string& unit_type);
std::string createTimestamp() const;
bool parsing_complete() const { return parsing_complete_; }
bool& parsing_complete() { return parsing_complete_; }
size_t load(unsigned entity_instance_name, const IfcParse::entity* entity, Argument**& attributes, size_t num_attributes, int attribute_index = -1);
void seek_to(const IfcEntityInstanceData& data);
void try_read_semicolon();
void build_inverses();
void register_inverse(unsigned, const IfcParse::entity* from_entity, Token, int attribute_index);
void register_inverse(unsigned, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass*, int attribute_index);
void unregister_inverse(unsigned, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass*, int attribute_index);
entity_by_guid_t& internal_guid_map() { return byguid; };
const IfcParse::schema_definition* schema() const { return schema_; }
std::pair<IfcUtil::IfcBaseClass*, double> getUnit(const std::string& unit_type);
bool parsing_complete() const { return parsing_complete_; }
bool& parsing_complete() { return parsing_complete_; }
void build_inverses();
entity_by_guid_t& internal_guid_map() { return byguid; };
};
#ifdef WITH_IFCXML
IFC_PARSE_API IfcFile* parse_ifcxml(const std::string& filename);
#endif
}
} // namespace IfcParse
namespace std {
template <>
struct iterator_traits<IfcParse::IfcFile::type_iterator> {
typedef ptrdiff_t difference_type;
typedef const IfcParse::declaration* value_type;
typedef const IfcParse::declaration*& reference;
typedef const IfcParse::declaration** pointer;
typedef std::forward_iterator_tag iterator_category;
};
}
template <>
struct iterator_traits<IfcParse::IfcFile::type_iterator> {
typedef ptrdiff_t difference_type;
typedef const IfcParse::declaration* value_type;
typedef const IfcParse::declaration*& reference;
typedef const IfcParse::declaration** pointer;
typedef std::forward_iterator_tag iterator_category;
};
} // namespace std
#endif
+72 -68
View File
@@ -17,124 +17,128 @@
* *
********************************************************************************/
#include <vector>
#include <algorithm>
#include "IfcGlobalId.h"
#include "IfcBaseClass.h"
#include "IfcException.h"
#include "IfcLogger.h"
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/version.hpp>
#include <boost/lexical_cast.hpp>
#include "../ifcparse/IfcGlobalId.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/IfcLogger.h"
#include <vector>
static const char* chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
// Converts an unsigned integer into a base64 string of length l
std::string base64(unsigned v, int l) {
std::string r;
r.reserve(l);
while ( v ) {
r.push_back(chars[v%64]);
v /= 64;
}
while ( (int)r.size() != l ) r.push_back('0');
std::reverse(r.begin(),r.end());
return r;
std::string r;
r.reserve(l);
while (v) {
r.push_back(chars[v % 64]);
v /= 64;
}
while ((int)r.size() != l) {
r.push_back('0');
}
std::reverse(r.begin(), r.end());
return r;
}
// Converts a base64 string into an unsigned integer
unsigned from_base64(const std::string& s) {
std::string::size_type zeros = s.find_first_not_of('0');
unsigned r = 0;
if ( zeros != std::string::npos )
for ( std::string::const_iterator i = s.begin()+zeros; i != s.end(); ++ i ) {
r *= 64;
const char* c = strchr(chars,*i);
if ( !c ) throw IfcParse::IfcException("Failed to decode GlobalId");
r += (unsigned)(c-chars);
}
return r;
std::string::size_type zeros = s.find_first_not_of('0');
unsigned r = 0;
if (zeros != std::string::npos) {
for (std::string::const_iterator i = s.begin() + zeros; i != s.end(); ++i) {
r *= 64;
const char* c = strchr(chars, *i);
if (!c) {
throw IfcParse::IfcException("Failed to decode GlobalId");
}
r += (unsigned)(c - chars);
}
}
return r;
}
// Compresses the UUID byte array into a base64 representation
std::string compress(unsigned char* v) {
std::string r;
r.reserve(22);
r += base64(v[0],2);
for ( unsigned i = 1; i < 16; i += 3 ) {
r += base64((v[i]<<16) + (v[i+1]<<8) + v[i+2],4);
}
return r;
std::string r;
r.reserve(22);
r += base64(v[0], 2);
for (unsigned i = 1; i < 16; i += 3) {
r += base64((v[i] << 16) + (v[i + 1] << 8) + v[i + 2], 4);
}
return r;
}
// Expands the base64 representation into a UUID byte array
void expand(const std::string& s, std::vector<unsigned char>& v) {
v.push_back((unsigned char)from_base64(s.substr(0,2)));
for( unsigned i = 0; i < 5; ++i ) {
unsigned d = from_base64(s.substr(2+4*i,4));
for ( unsigned j = 0; j < 3; ++ j ) {
v.push_back((d>>(8*(2-j))) % 256);
}
}
v.push_back((unsigned char)from_base64(s.substr(0, 2)));
for (unsigned i = 0; i < 5; ++i) {
unsigned d = from_base64(s.substr(2 + 4 * i, 4));
for (unsigned j = 0; j < 3; ++j) {
v.push_back((d >> (8 * (2 - j))) % 256);
}
}
}
// A random number generator for the UUID
static boost::uuids::basic_random_generator<boost::mt19937> gen;
IfcParse::IfcGlobalId::IfcGlobalId() {
uuid_data = gen();
std::vector<unsigned char> v(uuid_data.size());
std::copy(uuid_data.begin(), uuid_data.end(), v.begin());
string_data = compress(&v[0]);
uuid_data = gen();
std::vector<unsigned char> v(uuid_data.size());
std::copy(uuid_data.begin(), uuid_data.end(), v.begin());
string_data = compress(&v[0]);
#if BOOST_VERSION < 104400
formatted_string = boost::lexical_cast<std::string>(uuid_data);
formatted_string = boost::lexical_cast<std::string>(uuid_data);
#else
formatted_string = boost::uuids::to_string(uuid_data);
formatted_string = boost::uuids::to_string(uuid_data);
#endif
#ifndef NDEBUG
std::vector<unsigned char> test_vector;
expand(string_data, test_vector);
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, "Internal error generating GlobalId");
}
std::vector<unsigned char> test_vector;
expand(string_data, test_vector);
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, "Internal error generating GlobalId");
}
#endif
}
IfcParse::IfcGlobalId::IfcGlobalId(const std::string& s)
: string_data(s)
{
std::vector<unsigned char> v;
expand(string_data, v);
std::copy(v.begin(), v.end(), uuid_data.begin());
: string_data(s) {
std::vector<unsigned char> v;
expand(string_data, v);
std::copy(v.begin(), v.end(), uuid_data.begin());
#if BOOST_VERSION < 104400
formatted_string = boost::lexical_cast<std::string>(uuid_data);
formatted_string = boost::lexical_cast<std::string>(uuid_data);
#else
formatted_string = boost::uuids::to_string(uuid_data);
formatted_string = boost::uuids::to_string(uuid_data);
#endif
#ifndef NDEBUG
const std::string test_string = compress(&uuid_data.data[0]);
if (string_data != test_string) {
Logger::Message(Logger::LOG_ERROR, "Internal error generating GlobalId");
}
const std::string test_string = compress(&uuid_data.data[0]);
if (string_data != test_string) {
Logger::Message(Logger::LOG_ERROR, "Internal error generating GlobalId");
}
#endif
}
IfcParse::IfcGlobalId::operator const std::string&() const {
return string_data;
return string_data;
}
IfcParse::IfcGlobalId::operator const boost::uuids::uuid&() const {
return uuid_data;
return uuid_data;
}
const std::string& IfcParse::IfcGlobalId::formatted() const {
return formatted_string;
return formatted_string;
}
+19 -18
View File
@@ -20,27 +20,28 @@
#ifndef IFCGLOBALID_H
#define IFCGLOBALID_H
#include <string>
#include <boost/uuid/uuid.hpp>
#include "ifc_parse_api.h"
#include <boost/uuid/uuid.hpp>
#include <string>
namespace IfcParse {
/// A helper class for the creation of IFC GlobalIds.
class IFC_PARSE_API IfcGlobalId {
private:
std::string string_data, formatted_string;
boost::uuids::uuid uuid_data;
public:
static const unsigned int length = 22;
IfcGlobalId();
IfcGlobalId(const std::string&);
operator const std::string&() const;
operator const boost::uuids::uuid&() const;
const std::string& formatted() const;
};
/// A helper class for the creation of IFC GlobalIds.
class IFC_PARSE_API IfcGlobalId {
private:
std::string string_data, formatted_string;
boost::uuids::uuid uuid_data;
}
public:
static const unsigned int length = 22;
IfcGlobalId();
IfcGlobalId(const std::string&);
operator const std::string&() const;
operator const boost::uuids::uuid&() const;
const std::string& formatted() const;
};
#endif
} // namespace IfcParse
#endif
File diff suppressed because it is too large Load Diff
+326 -308
View File
@@ -28,361 +28,367 @@
#ifndef IFCHIERARCHYHELPER_H
#define IFCHIERARCHYHELPER_H
#include <map>
#include "ifc_parse_api.h"
#include <map>
#ifdef HAS_SCHEMA_2x3
#include "../ifcparse/Ifc2x3.h"
#include "Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "../ifcparse/Ifc4.h"
#include "Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "../ifcparse/Ifc4x1.h"
#include "Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "../ifcparse/Ifc4x2.h"
#include "Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "../ifcparse/Ifc4x3_rc1.h"
#include "Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "../ifcparse/Ifc4x3_rc2.h"
#include "Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "../ifcparse/Ifc4x3_rc3.h"
#include "Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "../ifcparse/Ifc4x3_rc4.h"
#include "Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "../ifcparse/Ifc4x3.h"
#include "Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "../ifcparse/Ifc4x3_tc1.h"
#include "Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "../ifcparse/Ifc4x3_add1.h"
#include "Ifc4x3_add1.h"
#endif
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcGlobalId.h"
#include "IfcFile.h"
#include "IfcGlobalId.h"
#include "IfcWrite.h"
namespace {
#ifdef HAS_SCHEMA_2x3
Ifc2x3::IfcObjectDefinition* get_parent_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc2x3::IfcObjectDefinition* get_parent_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc2x3::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc2x3::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc2x3::IfcProduct>());
}
void set_children_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc2x3::IfcProduct>());
}
void set_children_of_relation(Ifc2x3::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc2x3::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc2x3::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc2x3::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4
Ifc4::IfcObjectDefinition* get_parent_of_relation(Ifc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4::IfcObjectDefinition* get_parent_of_relation(Ifc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4::IfcProduct>());
}
void set_children_of_relation(Ifc4::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4::IfcProduct>());
}
void set_children_of_relation(Ifc4::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x1
Ifc4x1::IfcObjectDefinition* get_parent_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x1::IfcObjectDefinition* get_parent_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x1::IfcProduct>());
}
void set_children_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x1::IfcProduct>());
}
void set_children_of_relation(Ifc4x1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x1::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x1::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x2
Ifc4x2::IfcObjectDefinition* get_parent_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x2::IfcObjectDefinition* get_parent_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x2::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x2::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x2::IfcProduct>());
}
void set_children_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x2::IfcProduct>());
}
void set_children_of_relation(Ifc4x2::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x2::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x2::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x2::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3_rc1
Ifc4x3_rc1::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3_rc1::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc1::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc1::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc1::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_rc1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc1::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3_rc2
Ifc4x3_rc2::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3_rc2::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc2::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc2::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc2::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc2::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc2::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc2::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_rc2::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc2::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3_rc3
Ifc4x3_rc3::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3_rc3::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc3::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc3::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc3::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc3::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc3::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc3::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_rc3::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc3::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3_rc4
Ifc4x3_rc4::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3_rc4::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc4::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_rc4::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc4::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_rc4::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_rc4::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc4::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_rc4::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_rc4::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3
Ifc4x3::IfcObjectDefinition* get_parent_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3::IfcObjectDefinition* get_parent_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3::IfcProduct>());
}
void set_children_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3::IfcProduct>());
}
void set_children_of_relation(Ifc4x3::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3_tc1
Ifc4x3_tc1::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3_tc1::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_tc1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_tc1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_tc1::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_tc1::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_tc1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_tc1::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_tc1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_tc1::IfcObjectDefinition>());
}
#endif
#ifdef HAS_SCHEMA_4x3_add1
Ifc4x3_add1::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
Ifc4x3_add1::IfcObjectDefinition* get_parent_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure* t) {
return t->RelatingStructure();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure* t) {
return t->RelatedElements()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_add1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_add1::IfcRelAggregates* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_add1::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_add1::IfcProduct>());
}
void set_children_of_relation(Ifc4x3_add1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_add1::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_add1::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_add1::IfcObjectDefinition>());
}
#endif
IfcUtil::IfcBaseClass* get_parent_of_relation(IfcUtil::IfcBaseClass* t) {
return *t->data().getArgument(
t->declaration().as_entity()->attribute_index("RelatingObject")
);
}
aggregate_of_instance::ptr get_children_of_relation(IfcUtil::IfcBaseClass* t) {
return *t->data().getArgument(
t->declaration().as_entity()->attribute_index("RelatedElements")
);
}
void set_children_of_relation(IfcUtil::IfcBaseClass* t, aggregate_of_instance::ptr& cs) {
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument;
attr->set(cs);
t->data().setArgument(
t->declaration().as_entity()->attribute_index("RelatedElements"),
attr
);
}
IfcUtil::IfcBaseClass* get_parent_of_relation(IfcUtil::IfcBaseClass* t) {
return *t->data().getArgument(
t->declaration().as_entity()->attribute_index("RelatingObject"));
}
aggregate_of_instance::ptr get_children_of_relation(IfcUtil::IfcBaseClass* t) {
return *t->data().getArgument(
t->declaration().as_entity()->attribute_index("RelatedElements"));
}
void set_children_of_relation(IfcUtil::IfcBaseClass* t, aggregate_of_instance::ptr& cs) {
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument;
attr->set(cs);
t->data().setArgument(
t->declaration().as_entity()->attribute_index("RelatedElements"),
attr);
}
} // namespace
template <typename Schema>
class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
public:
IfcHierarchyHelper() : IfcParse::IfcFile(&Schema::get_schema()) {}
public:
IfcHierarchyHelper() : IfcParse::IfcFile(&Schema::get_schema()) {}
template <class T>
T* addTriplet(double x, double y, double z) {
std::vector<double> a; a.push_back(x); a.push_back(y); a.push_back(z);
T* t = new T(a);
addEntity(t);
return t;
}
template <class T>
T* addTriplet(double x, double y, double z) {
std::vector<double> a;
a.push_back(x);
a.push_back(y);
a.push_back(z);
T* t = new T(a);
addEntity(t);
return t;
}
template <class T>
T* addDoublet(double x, double y) {
std::vector<double> a; a.push_back(x); a.push_back(y);
T* t = new T(a);
addEntity(t);
return t;
}
template <class T>
T* addDoublet(double x, double y) {
std::vector<double> a;
a.push_back(x);
a.push_back(y);
T* t = new T(a);
addEntity(t);
return t;
}
template <class T>
T* getSingle() {
typename T::list::ptr ts = instances_by_type<T>();
if (ts->size() != 1) return 0;
return *ts->begin();
}
typename Schema::IfcAxis2Placement3D* addPlacement3d(double ox=0.0, double oy=0.0, double oz=0.0,
double zx=0.0, double zy=0.0, double zz=1.0,
double xx=1.0, double xy=0.0, double xz=0.0);
template <class T>
T* getSingle() {
typename T::list::ptr ts = instances_by_type<T>();
if (ts->size() != 1) {
return 0;
}
return *ts->begin();
}
typename Schema::IfcAxis2Placement2D* addPlacement2d(double ox=0.0, double oy=0.0,
double xx=1.0, double xy=0.0);
typename Schema::IfcAxis2Placement3D* addPlacement3d(double ox = 0.0, double oy = 0.0, double oz = 0.0, double zx = 0.0, double zy = 0.0, double zz = 1.0, double xx = 1.0, double xy = 0.0, double xz = 0.0);
typename Schema::IfcLocalPlacement* addLocalPlacement(typename Schema::IfcObjectPlacement* parent = 0,
double ox=0.0, double oy=0.0, double oz=0.0,
double zx=0.0, double zy=0.0, double zz=1.0,
double xx=1.0, double xy=0.0, double xz=0.0);
typename Schema::IfcAxis2Placement2D* addPlacement2d(double ox = 0.0, double oy = 0.0, double xx = 1.0, double xy = 0.0);
template <class T>
void addRelatedObject(typename Schema::IfcObjectDefinition* relating_object,
typename Schema::IfcObjectDefinition* related_object, typename Schema::IfcOwnerHistory* owner_hist = 0)
{
typename T::list::ptr li = instances_by_type<T>();
bool found = false;
for (typename T::list::it i = li->begin(); i != li->end(); ++i) {
T* rel = *i;
typename Schema::IfcLocalPlacement* addLocalPlacement(typename Schema::IfcObjectPlacement* parent = 0,
double ox = 0.0,
double oy = 0.0,
double oz = 0.0,
double zx = 0.0,
double zy = 0.0,
double zz = 1.0,
double xx = 1.0,
double xy = 0.0,
double xz = 0.0);
template <class T>
void addRelatedObject(typename Schema::IfcObjectDefinition* relating_object,
typename Schema::IfcObjectDefinition* related_object,
typename Schema::IfcOwnerHistory* owner_hist = 0) {
typename T::list::ptr li = instances_by_type<T>();
bool found = false;
for (typename T::list::it i = li->begin(); i != li->end(); ++i) {
T* rel = *i;
try {
if (get_parent_of_relation(rel) == relating_object) {
aggregate_of_instance::ptr products = get_children_of_relation(rel);
@@ -392,88 +398,100 @@ public:
break;
}
} catch (std::exception& e) {
Logger::Error(e);
} catch (...) {
Logger::Error("Unknown error in addRelatedObject()");
}
}
if (! found) {
if (! owner_hist) {
owner_hist = getSingle<typename Schema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
Logger::Error(e);
} catch (...) {
Logger::Error("Unknown error in addRelatedObject()");
}
}
if (!found) {
if (!owner_hist) {
owner_hist = getSingle<typename Schema::IfcOwnerHistory>();
}
if (!owner_hist) {
owner_hist = addOwnerHistory();
}
aggregate_of_instance::ptr related_objects (new aggregate_of_instance);
related_objects->push(related_object);
aggregate_of_instance::ptr related_objects(new aggregate_of_instance);
related_objects->push(related_object);
IfcEntityInstanceData* data = new IfcEntityInstanceData(&T::Class());
{ IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument(); attr->set<std::string>(IfcParse::IfcGlobalId()); data->setArgument(0, attr); }
{ IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument(); attr->set(owner_hist); data->setArgument(1, attr); }
int relating_index = 4, related_index = 5;
if (T::Class().name() == "IfcRelContainedInSpatialStructure") {
// IfcRelContainedInSpatialStructure has attributes reversed.
std::swap(relating_index, related_index);
}
{ IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument(); attr->set(relating_object); data->setArgument(relating_index, attr); }
{ IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument(); attr->set(related_objects); data->setArgument(related_index, attr); }
T* t = (T*)Schema::get_schema().instantiate(data);
addEntity(t);
}
}
IfcEntityInstanceData* data = new IfcEntityInstanceData(&T::Class());
{
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
attr->set<std::string>(IfcParse::IfcGlobalId());
data->setArgument(0, attr);
}
{
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
attr->set(owner_hist);
data->setArgument(1, attr);
}
int relating_index = 4, related_index = 5;
if (T::Class().name() == "IfcRelContainedInSpatialStructure") {
// IfcRelContainedInSpatialStructure has attributes reversed.
std::swap(relating_index, related_index);
}
{
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
attr->set(relating_object);
data->setArgument(relating_index, attr);
}
{
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
attr->set(related_objects);
data->setArgument(related_index, attr);
}
typename Schema::IfcOwnerHistory* addOwnerHistory();
typename Schema::IfcProject* addProject(typename Schema::IfcOwnerHistory* owner_hist = 0);
void relatePlacements(typename Schema::IfcProduct* parent, typename Schema::IfcProduct* product);
typename Schema::IfcSite* addSite(typename Schema::IfcProject* proj = 0, typename Schema::IfcOwnerHistory* owner_hist = 0);
typename Schema::IfcBuilding* addBuilding(typename Schema::IfcSite* site = 0, typename Schema::IfcOwnerHistory* owner_hist = 0);
T* t = (T*)Schema::get_schema().instantiate(data);
addEntity(t);
}
}
typename Schema::IfcBuildingStorey* addBuildingStorey(typename Schema::IfcBuilding* building = 0,
typename Schema::IfcOwnerHistory* owner_hist = 0);
typename Schema::IfcOwnerHistory* addOwnerHistory();
typename Schema::IfcProject* addProject(typename Schema::IfcOwnerHistory* owner_hist = 0);
void relatePlacements(typename Schema::IfcProduct* parent, typename Schema::IfcProduct* product);
typename Schema::IfcSite* addSite(typename Schema::IfcProject* proj = 0, typename Schema::IfcOwnerHistory* owner_hist = 0);
typename Schema::IfcBuilding* addBuilding(typename Schema::IfcSite* site = 0, typename Schema::IfcOwnerHistory* owner_hist = 0);
typename Schema::IfcBuildingStorey* addBuildingProduct(typename Schema::IfcProduct* product,
typename Schema::IfcBuildingStorey* storey = 0, typename Schema::IfcOwnerHistory* owner_hist = 0);
typename Schema::IfcBuildingStorey* addBuildingStorey(typename Schema::IfcBuilding* building = 0,
typename Schema::IfcOwnerHistory* owner_hist = 0);
void addExtrudedPolyline(typename Schema::IfcShapeRepresentation* rep, const std::vector<std::pair<double, double> >& points, double h,
typename Schema::IfcAxis2Placement2D* place=0, typename Schema::IfcAxis2Placement3D* place2=0,
typename Schema::IfcDirection* dir=0, typename Schema::IfcRepresentationContext* context=0);
typename Schema::IfcBuildingStorey* addBuildingProduct(typename Schema::IfcProduct* product,
typename Schema::IfcBuildingStorey* storey = 0,
typename Schema::IfcOwnerHistory* owner_hist = 0);
typename Schema::IfcProductDefinitionShape* addExtrudedPolyline(const std::vector<std::pair<double, double> >& points, double h,
typename Schema::IfcAxis2Placement2D* place=0, typename Schema::IfcAxis2Placement3D* place2=0, typename Schema::IfcDirection* dir=0,
typename Schema::IfcRepresentationContext* context=0);
void addExtrudedPolyline(typename Schema::IfcShapeRepresentation* rep, const std::vector<std::pair<double, double>>& points, double h, typename Schema::IfcAxis2Placement2D* place = 0, typename Schema::IfcAxis2Placement3D* place2 = 0, typename Schema::IfcDirection* dir = 0, typename Schema::IfcRepresentationContext* context = 0);
void addBox(typename Schema::IfcShapeRepresentation* rep, double w, double d, double h,
typename Schema::IfcAxis2Placement2D* place=0, typename Schema::IfcAxis2Placement3D* place2=0,
typename Schema::IfcDirection* dir=0, typename Schema::IfcRepresentationContext* context=0);
typename Schema::IfcProductDefinitionShape* addExtrudedPolyline(const std::vector<std::pair<double, double>>& points, double h, typename Schema::IfcAxis2Placement2D* place = 0, typename Schema::IfcAxis2Placement3D* place2 = 0, typename Schema::IfcDirection* dir = 0, typename Schema::IfcRepresentationContext* context = 0);
typename Schema::IfcProductDefinitionShape* addBox(double w, double d, double h, typename Schema::IfcAxis2Placement2D* place=0,
typename Schema::IfcAxis2Placement3D* place2=0, typename Schema::IfcDirection* dir=0, typename Schema::IfcRepresentationContext* context=0);
void addBox(typename Schema::IfcShapeRepresentation* rep, double w, double d, double h, typename Schema::IfcAxis2Placement2D* place = 0, typename Schema::IfcAxis2Placement3D* place2 = 0, typename Schema::IfcDirection* dir = 0, typename Schema::IfcRepresentationContext* context = 0);
void addAxis(typename Schema::IfcShapeRepresentation* rep, double l, typename Schema::IfcRepresentationContext* context=0);
typename Schema::IfcProductDefinitionShape* addBox(double w, double d, double h, typename Schema::IfcAxis2Placement2D* place = 0, typename Schema::IfcAxis2Placement3D* place2 = 0, typename Schema::IfcDirection* dir = 0, typename Schema::IfcRepresentationContext* context = 0);
typename Schema::IfcProductDefinitionShape* addAxisBox(double w, double d, double h, typename Schema::IfcRepresentationContext* context=0);
void addAxis(typename Schema::IfcShapeRepresentation* rep, double l, typename Schema::IfcRepresentationContext* context = 0);
void clipRepresentation(typename Schema::IfcProductRepresentation* shape,
typename Schema::IfcAxis2Placement3D* place, bool agree);
typename Schema::IfcProductDefinitionShape* addAxisBox(double w, double d, double h, typename Schema::IfcRepresentationContext* context = 0);
void clipRepresentation(typename Schema::IfcRepresentation* shape,
typename Schema::IfcAxis2Placement3D* place, bool agree);
void clipRepresentation(typename Schema::IfcProductRepresentation* shape,
typename Schema::IfcAxis2Placement3D* place,
bool agree);
typename Schema::IfcProductDefinitionShape* addMappedItem(typename Schema::IfcShapeRepresentation*,
typename Schema::IfcCartesianTransformationOperator3D* transform = 0,
typename Schema::IfcProductDefinitionShape* def = 0);
void clipRepresentation(typename Schema::IfcRepresentation* shape,
typename Schema::IfcAxis2Placement3D* place,
bool agree);
typename Schema::IfcProductDefinitionShape* addMappedItem(typename Schema::IfcShapeRepresentation::list::ptr,
typename Schema::IfcCartesianTransformationOperator3D* transform = 0);
typename Schema::IfcShapeRepresentation* addEmptyRepresentation(const std::string& repid = "Body", const std::string& reptype = "SweptSolid");
typename Schema::IfcProductDefinitionShape* addMappedItem(typename Schema::IfcShapeRepresentation*,
typename Schema::IfcCartesianTransformationOperator3D* transform = 0,
typename Schema::IfcProductDefinitionShape* def = 0);
typename Schema::IfcGeometricRepresentationContext* getRepresentationContext(const std::string&);
typename Schema::IfcProductDefinitionShape* addMappedItem(typename Schema::IfcShapeRepresentation::list::ptr,
typename Schema::IfcCartesianTransformationOperator3D* transform = 0);
private:
std::map<std::string, typename Schema::IfcGeometricRepresentationContext*> contexts;
typename Schema::IfcShapeRepresentation* addEmptyRepresentation(const std::string& repid = "Body", const std::string& reptype = "SweptSolid");
typename Schema::IfcGeometricRepresentationContext* getRepresentationContext(const std::string&);
private:
std::map<std::string, typename Schema::IfcGeometricRepresentationContext*> contexts;
};
#ifdef HAS_SCHEMA_2x3
@@ -530,7 +548,7 @@ IFC_PARSE_API Ifc4x3_rc3::IfcPresentationStyle* setSurfaceColour(IfcHierarchyHel
IFC_PARSE_API Ifc4x3_rc3::IfcPresentationStyle* setSurfaceColour(IfcHierarchyHelper<Ifc4x3_rc3>& file, Ifc4x3_rc3::IfcRepresentation* shape, double r, double g, double b, double a = 1.0);
IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper<Ifc4x3_rc3>& file, Ifc4x3_rc3::IfcProductRepresentation* shape, Ifc4x3_rc3::IfcPresentationStyle* style);
IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper<Ifc4x3_rc3>& file, Ifc4x3_rc3::IfcRepresentation* shape, Ifc4x3_rc3::IfcPresentationStyle* style);
#endif
#endif
#ifdef HAS_SCHEMA_4x3_rc4
IFC_PARSE_API Ifc4x3_rc4::IfcPresentationStyle* addStyleAssignment(IfcHierarchyHelper<Ifc4x3_rc4>& file, double r, double g, double b, double a = 1.0);
+152 -154
View File
@@ -19,217 +19,215 @@
#include "IfcLogger.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/Argument.h"
#include "Argument.h"
#include "IfcException.h"
#include <algorithm>
#include <boost/algorithm/string/replace.hpp>
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/version.hpp>
#include <mutex>
#include <iostream>
#include <algorithm>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <chrono>
#include <iostream>
#include <mutex>
namespace {
std::string get_time(bool with_milliseconds=false) {
std::ostringstream oss;
time_t now = time(nullptr);
oss << std::put_time(localtime(&now), "%F %T");
std::string get_time(bool with_milliseconds = false) {
std::ostringstream oss;
time_t now = time(nullptr);
oss << std::put_time(localtime(&now), "%F %T");
if (with_milliseconds) {
auto now_chrono = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now_chrono.time_since_epoch()) % 1000;
oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
}
if (with_milliseconds) {
auto now_chrono = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now_chrono.time_since_epoch()) % 1000;
oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
}
return oss.str();
}
template <typename T>
struct severity_strings {
static const std::array<std::basic_string<T>, 5> value;
};
template <>
const std::array<std::basic_string<char>, 5> severity_strings<char>::value = { "Performance", "Debug", "Notice", "Warning", "Error" };
template <>
const std::array<std::basic_string<wchar_t>, 5> severity_strings<wchar_t>::value = { L"Performance", L"Debug", L"Notice", L"Warning", L"Error" };
template <typename T>
void plain_text_message(T& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
os << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
os << "[" << get_time(type <= Logger::LOG_PERF).c_str() << "] ";
if (current_product) {
std::string global_id = *((IfcUtil::IfcBaseEntity*)*current_product)->get("GlobalId");
os << "{" << global_id.c_str() << "} ";
}
os << message.c_str() << std::endl;
if (instance) {
std::string instance_string = instance->data().toString();
if (instance_string.size() > 259) {
instance_string = instance_string.substr(0, 256) + "...";
}
os << instance_string.c_str() << std::endl;
}
}
template <typename T>
std::basic_string<T> string_as(const std::string& s) {
std::basic_string<T> v;
v.assign(s.begin(), s.end());
return v;
}
template <typename T>
void json_message(T& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
boost::property_tree::basic_ptree<std::basic_string<typename T::char_type>, std::basic_string<typename T::char_type> > pt;
// @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 product_string[] = { 'p', 'r', 'o', 'd', 'u', 'c', 't', 0 };
static const typename T::char_type message_string[] = { 'm', 'e', 's', 's', 'a', 'g', 'e', 0 };
static const typename T::char_type instance_string[] = { 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 0 };
pt.put(level_string, severity_strings<typename T::char_type>::value[type]);
if (current_product) {
pt.put(product_string, string_as<typename T::char_type>((**current_product).data().toString()));
}
pt.put(message_string, string_as<typename T::char_type>(message));
if (instance) {
pt.put(instance_string, string_as<typename T::char_type>(instance->data().toString()));
}
pt.put(time_string, string_as<typename T::char_type>(get_time()));
boost::property_tree::write_json(os, pt, false);
}
return oss.str();
}
template <typename T>
struct severity_strings {
static const std::array<std::basic_string<T>, 5> value;
};
template <>
const std::array<std::basic_string<char>, 5> severity_strings<char>::value = {"Performance", "Debug", "Notice", "Warning", "Error"};
template <>
const std::array<std::basic_string<wchar_t>, 5> severity_strings<wchar_t>::value = {L"Performance", L"Debug", L"Notice", L"Warning", L"Error"};
template <typename T>
void plain_text_message(T& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
os << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
os << "[" << get_time(type <= Logger::LOG_PERF).c_str() << "] ";
if (current_product) {
std::string global_id = *((IfcUtil::IfcBaseEntity*)*current_product)->get("GlobalId");
os << "{" << global_id.c_str() << "} ";
}
os << message.c_str() << std::endl;
if (instance) {
std::string instance_string = instance->data().toString();
if (instance_string.size() > 259) {
instance_string = instance_string.substr(0, 256) + "...";
}
os << instance_string.c_str() << std::endl;
}
}
template <typename T>
std::basic_string<T> string_as(const std::string& s) {
std::basic_string<T> v;
v.assign(s.begin(), s.end());
return v;
}
template <typename T>
void json_message(T& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
boost::property_tree::basic_ptree<std::basic_string<typename T::char_type>, std::basic_string<typename T::char_type>> pt;
// @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 product_string[] = {'p', 'r', 'o', 'd', 'u', 'c', 't', 0};
static const typename T::char_type message_string[] = {'m', 'e', 's', 's', 'a', 'g', 'e', 0};
static const typename T::char_type instance_string[] = {'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 0};
pt.put(level_string, severity_strings<typename T::char_type>::value[type]);
if (current_product) {
pt.put(product_string, string_as<typename T::char_type>((**current_product).data().toString()));
}
pt.put(message_string, string_as<typename T::char_type>(message));
if (instance) {
pt.put(instance_string, string_as<typename T::char_type>(instance->data().toString()));
}
pt.put(time_string, string_as<typename T::char_type>(get_time()));
boost::property_tree::write_json(os, pt, false);
}
} // namespace
void Logger::SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product) {
if (verbosity <= LOG_DEBUG && product) {
Message(LOG_DEBUG, "Begin processing", *product);
}
if (!product && print_perf_stats_on_element) {
PrintPerformanceStats();
performance_statistics.clear();
}
current_product = product;
if (verbosity <= LOG_DEBUG && product) {
Message(LOG_DEBUG, "Begin processing", *product);
}
if (!product && print_perf_stats_on_element) {
PrintPerformanceStats();
performance_statistics.clear();
}
current_product = product;
}
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
wlog1 = wlog2 = 0;
log1 = l1;
log2 = l2;
if (!log2) {
log2 = &log_stream;
}
wlog1 = wlog2 = 0;
log1 = l1;
log2 = l2;
if (!log2) {
log2 = &log_stream;
}
}
void Logger::SetOutput(std::wostream* l1, std::wostream* l2) {
log1 = log2 = 0;
wlog1 = l1;
wlog2 = l2;
if (!wlog2) {
log2 = &log_stream;
}
log1 = log2 = 0;
wlog1 = l1;
wlog2 = l2;
if (!wlog2) {
log2 = &log_stream;
}
}
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
static std::mutex m;
std::lock_guard<std::mutex> lk(m);
static std::mutex m;
std::lock_guard<std::mutex> lk(m);
if (type == LOG_PERF) {
if (!first_timepoint) {
first_timepoint = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()).time_since_epoch().count();
}
double t0 = (std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()).time_since_epoch().count() - *first_timepoint) / 1.e9;
if (message.substr(0, 5) == "done ") {
auto orig = message.substr(5);
performance_statistics[orig] += t0 - performance_signal_start[orig];
} else {
performance_signal_start[message] = t0;
}
}
if (type == LOG_PERF) {
if (!first_timepoint) {
first_timepoint = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()).time_since_epoch().count();
}
double t0 = (std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()).time_since_epoch().count() - *first_timepoint) / 1.e9;
if (message.substr(0, 5) == "done ") {
auto orig = message.substr(5);
performance_statistics[orig] += t0 - performance_signal_start[orig];
} else {
performance_signal_start[message] = t0;
}
}
if (type > max_severity) {
max_severity = type;
}
if ((log2 || wlog2) && type >= verbosity) {
if (format == FMT_PLAIN) {
if (type > max_severity) {
max_severity = type;
}
if ((log2 || wlog2) && type >= verbosity) {
if (format == FMT_PLAIN) {
if (log2) {
plain_text_message(*log2, current_product, type, message, instance);
} else if (wlog2) {
plain_text_message(*wlog2, current_product, type, message, instance);
}
} else if (format == FMT_JSON) {
} else if (format == FMT_JSON) {
if (log2) {
json_message(*log2, current_product, type, message, instance);
} else if (wlog2) {
json_message(*wlog2, current_product, type, message, instance);
}
}
}
}
}
}
void Logger::Message(Logger::Severity type, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance) {
Message(type, std::string(exception.what()), instance);
Message(type, std::string(exception.what()), instance);
}
template <typename T>
void status(T& log1, const std::string& message, bool new_line) {
log1 << message.c_str();
if (new_line) {
log1 << std::endl;
} else {
log1 << std::flush;
}
log1 << message.c_str();
if (new_line) {
log1 << std::endl;
} else {
log1 << std::flush;
}
}
void Logger::Status(const std::string& message, bool new_line) {
if (log1) {
status(*log1, message, new_line);
} else if (wlog1) {
status(*wlog1, message, new_line);
}
if (log1) {
status(*log1, message, new_line);
} else if (wlog1) {
status(*wlog1, message, new_line);
}
}
void Logger::ProgressBar(int progress) {
Status("\r[" + std::string(progress,'#') + std::string(50 - progress,' ') + "]", false);
Status("\r[" + std::string(progress, '#') + std::string(50 - progress, ' ') + "]", false);
}
std::string Logger::GetLog() {
return log_stream.str();
return log_stream.str();
}
void Logger::PrintPerformanceStats() {
std::vector<std::pair<double, std::string>> items;
for (auto& p : performance_statistics) {
items.push_back({ p.second, p.first });
}
std::vector<std::pair<double, std::string>> items;
for (auto& p : performance_statistics) {
items.push_back({p.second, p.first});
}
std::sort(items.begin(), items.end());
std::reverse(items.begin(), items.end());
std::sort(items.begin(), items.end());
std::reverse(items.begin(), items.end());
size_t max_size = 0;
for (auto& p : items) {
if (p.second.size() > max_size) {
max_size = p.second.size();
}
}
size_t max_size = 0;
for (auto& p : items) {
if (p.second.size() > max_size) {
max_size = p.second.size();
}
}
for (auto& p : items) {
auto s = p.second + std::string(max_size - p.second.size(), ' ') + ": " + std::to_string(p.first);
Message(LOG_PERF, s);
}
for (auto& p : items) {
auto s = p.second + std::string(max_size - p.second.size(), ' ') + ": " + std::to_string(p.first);
Message(LOG_PERF, s);
}
}
void Logger::Verbosity(Logger::Severity v) { verbosity = v; }
@@ -252,4 +250,4 @@ boost::optional<IfcUtil::IfcBaseClass*> Logger::current_product;
boost::optional<long long> Logger::first_timepoint;
std::map<std::string, double> Logger::performance_statistics;
std::map<std::string, double> Logger::performance_signal_start;
bool Logger::print_perf_stats_on_element = false;
bool Logger::print_perf_stats_on_element = false;
+74 -67
View File
@@ -20,93 +20,100 @@
#ifndef IFCLOGGER_H
#define IFCLOGGER_H
#include "../ifcparse/IfcBaseClass.h"
#include "ifc_parse_api.h"
#include "IfcBaseClass.h"
#include <map>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <exception>
#include <boost/optional.hpp>
#include <boost/scope_exit.hpp>
#include "ifc_parse_api.h"
#include <exception>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
class IFC_PARSE_API Logger {
public:
typedef enum { LOG_PERF, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, LOG_ERROR } Severity;
typedef enum { FMT_PLAIN, FMT_JSON } Format;
private:
public:
typedef enum {
LOG_PERF,
LOG_DEBUG,
LOG_NOTICE,
LOG_WARNING,
LOG_ERROR
} Severity;
typedef enum {
FMT_PLAIN,
FMT_JSON
} Format;
// To both stream variants need to exist at runtime or should this be a
// template argument of Logger or controlled using preprocessor directives?
static std::ostream* log1;
static std::ostream* log2;
static std::wostream* wlog1;
static std::wostream* wlog2;
private:
// To both stream variants need to exist at runtime or should this be a
// template argument of Logger or controlled using preprocessor directives?
static std::ostream* log1;
static std::ostream* log2;
static std::stringstream log_stream;
static std::wostream* wlog1;
static std::wostream* wlog2;
static Severity verbosity;
static Format format;
static boost::optional<IfcUtil::IfcBaseClass*> current_product;
static Severity max_severity;
static std::stringstream log_stream;
static boost::optional<long long> first_timepoint;
static std::map<std::string, double> performance_statistics;
static std::map<std::string, double> performance_signal_start;
static Severity verbosity;
static Format format;
static boost::optional<IfcUtil::IfcBaseClass*> current_product;
static Severity max_severity;
static bool print_perf_stats_on_element;
static boost::optional<long long> first_timepoint;
static std::map<std::string, double> performance_statistics;
static std::map<std::string, double> performance_signal_start;
public:
static void SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product);
static bool print_perf_stats_on_element;
/// Determines to what stream respectively progress and errors are logged
static void SetOutput(std::wostream* l1, std::wostream* l2);
/// Determines to what stream respectively progress and errors are logged
static void SetOutput(std::ostream* l1, std::ostream* l2);
public:
static void SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product);
/// Determines the types of log messages to get logged
static void Verbosity(Severity v);
static Severity Verbosity();
static Severity MaxSeverity();
/// Determines to what stream respectively progress and errors are logged
static void SetOutput(std::wostream* l1, std::wostream* l2);
/// Determines output format: plain text or sequence of JSON objects
static void OutputFormat(Format f);
static Format OutputFormat();
/// Log a message to the output stream
static void Message(Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0);
static void Message(Severity type, const std::exception& message, const IfcUtil::IfcBaseInterface* instance = 0);
static void Notice(const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, message, instance); }
/// Determines to what stream respectively progress and errors are logged
static void SetOutput(std::ostream* l1, std::ostream* l2);
/// Determines the types of log messages to get logged
static void Verbosity(Severity v);
static Severity Verbosity();
static Severity MaxSeverity();
/// Determines output format: plain text or sequence of JSON objects
static void OutputFormat(Format f);
static Format OutputFormat();
/// Log a message to the output stream
static void Message(Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0);
static void Message(Severity type, const std::exception& message, const IfcUtil::IfcBaseInterface* instance = 0);
static void Notice(const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, message, instance); }
static void Warning(const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, message, instance); }
static void Error(const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, message, instance); }
static void Notice(const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, exception, instance); }
static void Warning(const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, exception, instance); }
static void Error(const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, exception, instance); }
static void Status(const std::string& message, bool new_line=true);
static void Notice(const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, exception, instance); }
static void Warning(const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, exception, instance); }
static void Error(const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, exception, instance); }
static void ProgressBar(int progress);
static std::string GetLog();
static void PrintPerformanceStats();
static void PrintPerformanceStatsOnElement(bool b) { print_perf_stats_on_element = b; }
static void Status(const std::string& message, bool new_line = true);
static void ProgressBar(int progress);
static std::string GetLog();
static void PrintPerformanceStats();
static void PrintPerformanceStatsOnElement(bool b) { print_perf_stats_on_element = b; }
};
#define PERF(x) \
\
Logger::Message(Logger::LOG_PERF, x);\
\
BOOST_SCOPE_EXIT(void) { \
Logger::Message(Logger::LOG_PERF, "done " + std::string(x));\
} BOOST_SCOPE_EXIT_END
#define PERF(x) \
\
Logger::Message(Logger::LOG_PERF, x); \
\
BOOST_SCOPE_EXIT(void) { \
Logger::Message(Logger::LOG_PERF, "done " + std::string(x)); \
} \
BOOST_SCOPE_EXIT_END
#endif
+1925 -1889
View File
File diff suppressed because it is too large Load Diff
+209 -206
View File
@@ -27,251 +27,254 @@
#ifndef IFCPARSE_H
#define IFCPARSE_H
#include "../ifcparse/macros.h"
#if defined(IFCOPENSHELL_BRANCH) && defined(IFCOPENSHELL_COMMIT)
#define IFCOPENSHELL_VERSION STRINGIFY(IFCOPENSHELL_BRANCH) "-" STRINGIFY(IFCOPENSHELL_COMMIT)
#else
#define IFCOPENSHELL_VERSION "0.7.0"
#define IFCOPENSHELL_VERSION "0.8.0"
#endif
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <fstream>
#include <cstring>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/dynamic_bitset.hpp>
#include "aggregate_of_instance.h"
#include "Argument.h"
#include "ifc_parse_api.h"
#include "IfcBaseClass.h"
#include "IfcCharacterDecoder.h"
#include "IfcLogger.h"
#include "IfcSpfStream.h"
#include "macros.h"
#include "../ifcparse/IfcCharacterDecoder.h"
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/IfcLogger.h"
#include "../ifcparse/Argument.h"
#include "../ifcparse/aggregate_of_instance.h"
#include "../ifcparse/IfcSpfStream.h"
#include <boost/dynamic_bitset.hpp>
#include <boost/shared_ptr.hpp>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
namespace IfcParse {
class IfcFile;
class IfcSpfLexer;
class IfcFile;
class IfcSpfLexer;
enum TokenType {
Token_NONE,
Token_STRING,
Token_IDENTIFIER,
Token_OPERATOR,
Token_ENUMERATION,
Token_KEYWORD,
Token_INT,
Token_BOOL,
Token_FLOAT,
Token_BINARY
};
enum TokenType {
Token_NONE,
Token_STRING,
Token_IDENTIFIER,
Token_OPERATOR,
Token_ENUMERATION,
Token_KEYWORD,
Token_INT,
Token_BOOL,
Token_FLOAT,
Token_BINARY
};
struct Token {
IfcSpfLexer* lexer; //TODO: remove it from here
unsigned startPos;
TokenType type;
union {
char value_char; //types: OPERATOR
int value_int; //types: INT, IDENTIFIER
double value_double; //types: FLOAT
};
struct Token {
IfcSpfLexer* lexer; //TODO: remove it from here
unsigned startPos;
TokenType type;
union {
char value_char; //types: OPERATOR
int value_int; //types: INT, IDENTIFIER
double value_double; //types: FLOAT
};
Token() : lexer(0), startPos(0), type(Token_NONE) {}
Token(IfcSpfLexer* _lexer, unsigned _startPos, unsigned /*_endPos*/, TokenType _type)
: lexer(_lexer), startPos(_startPos), type(_type) {}
};
Token() : lexer(0),
startPos(0),
type(Token_NONE) {}
Token(IfcSpfLexer* _lexer, unsigned _startPos, unsigned /*_endPos*/, TokenType _type)
: lexer(_lexer),
startPos(_startPos),
type(_type) {}
};
/// Provides functions to convert Tokens to binary data
/// Tokens are merely offsets to where they can be read in the file
class IFC_PARSE_API TokenFunc {
private:
static bool startsWith(const Token& t, char c);
public:
/// Returns the offset at which the token is read from the file
// static unsigned int Offset(const Token& t);
/// Returns whether the token can be interpreted as a string
static bool isString(const Token& t);
/// Returns whether the token can be interpreted as an identifier
static bool isIdentifier(const Token& t);
/// Returns whether the token can be interpreted as a syntactical operator
static bool isOperator(const Token& t);
/// Returns whether the token is a given operator
static bool isOperator(const Token& t, char op);
/// Returns whether the token can be interpreted as an enumerated value
static bool isEnumeration(const Token& t);
/// Returns whether the token can be interpreted as a datatype name
static bool isKeyword(const Token& t);
/// Returns whether the token can be interpreted as an integer
static bool isInt(const Token& t);
/// Returns whether the token can be interpreted as a boolean
static bool isBool(const Token& t);
/// Returns whether the token can be interpreted as a logical
static bool isLogical(const Token& t);
/// Returns whether the token can be interpreted as a floating point number
static bool isFloat(const Token& t);
/// Returns whether the token can be interpreted as a binary type
static bool isBinary(const Token& t);
/// Returns the token interpreted as an integer
static int asInt(const Token& t);
/// Returns the token interpreted as an identifier
static int asIdentifier(const Token& t);
/// Returns the token interpreted as an boolean (.T. or .F.)
static bool asBool(const Token& t);
/// Returns the token interpreted as an logical (.T. or .F. or .U.)
static boost::logic::tribool asLogical(const Token& t);
/// Returns the token as a floating point number
static double asFloat(const Token& t);
/// Returns the token as a string (without the dot or apostrophe)
static std::string asString(const Token& t);
/// Returns the token as a string in internal buffer (for optimization purposes)
static const std::string &asStringRef(const Token& t);
/// Returns the token as a string (without the dot or apostrophe)
static boost::dynamic_bitset<> asBinary(const Token& t);
/// Returns a string representation of the token (including the dot or apostrophe)
static std::string toString(const Token& t);
};
/// Provides functions to convert Tokens to binary data
/// Tokens are merely offsets to where they can be read in the file
class IFC_PARSE_API TokenFunc {
private:
static bool startsWith(const Token& t, char c);
//
// Functions for creating Tokens from an arbitary file offset
// The first 4 bits are reserved for Tokens of type ()=,;$*
//
Token OperatorTokenPtr(IfcSpfLexer* tokens, unsigned start, unsigned end);
Token GeneralTokenPtr(IfcSpfLexer* tokens, unsigned start, unsigned end);
Token NoneTokenPtr();
public:
/// Returns the offset at which the token is read from the file
// static unsigned int Offset(const Token& t);
/// Returns whether the token can be interpreted as a string
static bool isString(const Token& t);
/// Returns whether the token can be interpreted as an identifier
static bool isIdentifier(const Token& t);
/// Returns whether the token can be interpreted as a syntactical operator
static bool isOperator(const Token& t);
/// Returns whether the token is a given operator
static bool isOperator(const Token& t, char op);
/// Returns whether the token can be interpreted as an enumerated value
static bool isEnumeration(const Token& t);
/// Returns whether the token can be interpreted as a datatype name
static bool isKeyword(const Token& t);
/// Returns whether the token can be interpreted as an integer
static bool isInt(const Token& t);
/// Returns whether the token can be interpreted as a boolean
static bool isBool(const Token& t);
/// Returns whether the token can be interpreted as a logical
static bool isLogical(const Token& t);
/// Returns whether the token can be interpreted as a floating point number
static bool isFloat(const Token& t);
/// Returns whether the token can be interpreted as a binary type
static bool isBinary(const Token& t);
/// Returns the token interpreted as an integer
static int asInt(const Token& t);
/// Returns the token interpreted as an identifier
static int asIdentifier(const Token& t);
/// Returns the token interpreted as an boolean (.T. or .F.)
static bool asBool(const Token& t);
/// Returns the token interpreted as an logical (.T. or .F. or .U.)
static boost::logic::tribool asLogical(const Token& t);
/// Returns the token as a floating point number
static double asFloat(const Token& t);
/// Returns the token as a string (without the dot or apostrophe)
static std::string asString(const Token& t);
/// Returns the token as a string in internal buffer (for optimization purposes)
static const std::string& asStringRef(const Token& t);
/// Returns the token as a string (without the dot or apostrophe)
static boost::dynamic_bitset<> asBinary(const Token& t);
/// Returns a string representation of the token (including the dot or apostrophe)
static std::string toString(const Token& t);
};
/// A stream of tokens to be read from a IfcSpfStream.
class IFC_PARSE_API IfcSpfLexer {
private:
IfcCharacterDecoder* decoder;
unsigned int skipWhitespace();
unsigned int skipComment();
public:
std::string &GetTempString() const {
static my_thread_local std::string s;
return s;
}
IfcSpfStream* stream;
IfcFile* file;
IfcSpfLexer(IfcSpfStream* s, IfcFile* f);
Token Next();
~IfcSpfLexer();
void TokenString(unsigned int offset, std::string &result);
};
//
// Functions for creating Tokens from an arbitary file offset
// The first 4 bits are reserved for Tokens of type ()=,;$*
//
Token OperatorTokenPtr(IfcSpfLexer* tokens, unsigned start, unsigned end);
Token GeneralTokenPtr(IfcSpfLexer* tokens, unsigned start, unsigned end);
Token NoneTokenPtr();
/// Argument of type list, e.g.
/// #1=IfcDirection((1.,0.,0.));
/// ==========
class IFC_PARSE_API ArgumentList: public Argument {
private:
size_t size_;
Argument** list_;
/// A stream of tokens to be read from a IfcSpfStream.
class IFC_PARSE_API IfcSpfLexer {
private:
IfcCharacterDecoder* decoder;
unsigned int skipWhitespace();
unsigned int skipComment();
public:
ArgumentList() : size_(0), list_(0) {}
ArgumentList(size_t n) : size_(n), list_(new Argument*[size_] {0}) {}
~ArgumentList();
public:
std::string& GetTempString() const {
static my_thread_local std::string s;
return s;
}
IfcSpfStream* stream;
IfcFile* file;
IfcSpfLexer(IfcSpfStream* s, IfcFile* f);
Token Next();
~IfcSpfLexer();
void TokenString(unsigned int offset, std::string& result);
};
void read(IfcSpfLexer* t, std::vector<unsigned int>& ids);
/// Argument of type list, e.g.
/// #1=IfcDirection((1.,0.,0.));
/// ==========
class IFC_PARSE_API ArgumentList : public Argument {
private:
size_t size_;
Argument** list_;
IfcUtil::ArgumentType type() const;
operator std::vector<int>() const;
operator std::vector<double>() const;
operator std::vector<std::string>() const;
operator std::vector<boost::dynamic_bitset<> >() const;
operator aggregate_of_instance::ptr() const;
public:
ArgumentList() : size_(0),
list_(0) {}
ArgumentList(size_t n) : size_(n),
list_(new Argument* [size_] { 0 }) {}
~ArgumentList();
operator std::vector< std::vector<int> >() const;
operator std::vector< std::vector<double> >() const;
operator aggregate_of_aggregate_of_instance::ptr() const;
void read(IfcSpfLexer* t, std::vector<unsigned int>& ids);
bool isNull() const;
unsigned int size() const;
IfcUtil::ArgumentType type() const;
Argument* operator [] (unsigned int i) const;
operator std::vector<int>() const;
operator std::vector<double>() const;
operator std::vector<std::string>() const;
operator std::vector<boost::dynamic_bitset<>>() const;
operator aggregate_of_instance::ptr() const;
std::string toString(bool upper=false) const;
operator std::vector<std::vector<int>>() const;
operator std::vector<std::vector<double>>() const;
operator aggregate_of_aggregate_of_instance::ptr() const;
Argument**& arguments() { return list_; }
size_t& size() { return size_; }
};
bool isNull() const;
unsigned int size() const;
Argument* operator[](unsigned int i) const;
/// Argument being null, e.g. '$'
/// == ===
class IFC_PARSE_API NullArgument : public Argument {
public:
NullArgument() {}
IfcUtil::ArgumentType type() const { return IfcUtil::Argument_NULL; }
bool isNull() const { return true; }
unsigned int size() const { return 1; }
Argument* operator [] (unsigned int /*i*/) const { throw IfcException("Argument is not a list of attributes"); }
std::string toString(bool /*upper=false*/) const { return "$"; }
};
std::string toString(bool upper = false) const;
/// Argument of type scalar or string, e.g.
/// #1=IfcVector(#2,1.0);
/// == ===
class IFC_PARSE_API TokenArgument : public Argument {
private:
public:
Token token;
TokenArgument(const Token& t);
Argument**& arguments() { return list_; }
size_t& size() { return size_; }
};
IfcUtil::ArgumentType type() const;
/// Argument being null, e.g. '$'
/// == ===
class IFC_PARSE_API NullArgument : public Argument {
public:
NullArgument() {}
IfcUtil::ArgumentType type() const { return IfcUtil::Argument_NULL; }
bool isNull() const { return true; }
unsigned int size() const { return 1; }
Argument* operator[](unsigned int /*i*/) const { throw IfcException("Argument is not a list of attributes"); }
std::string toString(bool /*upper=false*/) const { return "$"; }
};
operator int() const;
operator bool() const;
operator boost::logic::tribool() const;
operator double() const;
operator std::string() const;
operator boost::dynamic_bitset<>() const;
operator IfcUtil::IfcBaseClass*() const;
/// Argument of type scalar or string, e.g.
/// #1=IfcVector(#2,1.0);
/// == ===
class IFC_PARSE_API TokenArgument : public Argument {
private:
public:
Token token;
TokenArgument(const Token& t);
bool isNull() const;
unsigned int size() const;
IfcUtil::ArgumentType type() const;
Argument* operator [] (unsigned int i) const;
std::string toString(bool upper=false) const;
};
operator int() const;
operator bool() const;
operator boost::logic::tribool() const;
operator double() const;
operator std::string() const;
operator boost::dynamic_bitset<>() const;
operator IfcUtil::IfcBaseClass*() const;
/// Argument of an IFC simple type
/// #1=IfcTrimmedCurve(#2,(IFCPARAMETERVALUE(0.)),(IFCPARAMETERVALUE(1.)),.T.,.PARAMETER.);
/// ===================== =====================
class IFC_PARSE_API EntityArgument : public Argument {
private:
IfcUtil::IfcBaseClass* entity;
public:
EntityArgument(const Token& t);
~EntityArgument();
bool isNull() const;
unsigned int size() const;
IfcUtil::ArgumentType type() const;
Argument* operator[](unsigned int i) const;
std::string toString(bool upper = false) const;
};
operator IfcUtil::IfcBaseClass*() const;
/// Argument of an IFC simple type
/// #1=IfcTrimmedCurve(#2,(IFCPARAMETERVALUE(0.)),(IFCPARAMETERVALUE(1.)),.T.,.PARAMETER.);
/// ===================== =====================
class IFC_PARSE_API EntityArgument : public Argument {
private:
IfcUtil::IfcBaseClass* entity;
bool isNull() const;
unsigned int size() const;
public:
EntityArgument(const Token& t);
~EntityArgument();
Argument* operator [] (unsigned int i) const;
std::string toString(bool upper=false) const;
};
IFC_PARSE_API IfcEntityInstanceData* read(unsigned int i, IfcFile* t, boost::optional<unsigned> offset = boost::none);
IfcUtil::ArgumentType type() const;
IFC_PARSE_API aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level = -1);
operator IfcUtil::IfcBaseClass*() const;
IFC_PARSE_API aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level = -1);
}
bool isNull() const;
unsigned int size() const;
IFC_PARSE_API std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f);
Argument* operator[](unsigned int i) const;
std::string toString(bool upper = false) const;
};
IFC_PARSE_API IfcEntityInstanceData* read(unsigned int i, IfcFile* t, boost::optional<unsigned> offset = boost::none);
IFC_PARSE_API aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level = -1);
IFC_PARSE_API aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level = -1);
} // namespace IfcParse
IFC_PARSE_API std::ostream& operator<<(std::ostream& os, const IfcParse::IfcFile& f);
#endif
+68 -50
View File
@@ -20,85 +20,103 @@
#include "IfcSIPrefix.h"
#ifdef HAS_SCHEMA_2x3
#include "../ifcparse/Ifc2x3.h"
#include "Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "../ifcparse/Ifc4.h"
#include "Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "../ifcparse/Ifc4x1.h"
#include "Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "../ifcparse/Ifc4x2.h"
#include "Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "../ifcparse/Ifc4x3_rc1.h"
#include "Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "../ifcparse/Ifc4x3_rc2.h"
#include "Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "../ifcparse/Ifc4x3_rc3.h"
#include "Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "../ifcparse/Ifc4x3_rc4.h"
#include "Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "../ifcparse/Ifc4x3.h"
#include "Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "../ifcparse/Ifc4x3_tc1.h"
#include "Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "../ifcparse/Ifc4x3_add1.h"
#include "Ifc4x3_add1.h"
#endif
double IfcParse::IfcSIPrefixToValue(const std::string& v) {
if ( v == "EXA" ) return 1.e18;
else if ( v == "PETA" ) return 1.e15;
else if ( v == "TERA" ) return 1.e12;
else if ( v == "GIGA" ) return 1.e9;
else if ( v == "MEGA" ) return 1.e6;
else if ( v == "KILO" ) return 1.e3;
else if ( v == "HECTO" ) return 1.e2;
else if ( v == "DECA" ) return 1.e1;
else if ( v == "DECI" ) return 1.e-1;
else if ( v == "CENTI" ) return 1.e-2;
else if ( v == "MILLI" ) return 1.e-3;
else if ( v == "MICRO" ) return 1.e-6;
else if ( v == "NANO" ) return 1.e-9;
else if ( v == "PICO" ) return 1.e-12;
else if ( v == "FEMTO" ) return 1.e-15;
else if ( v == "ATTO" ) return 1.e-18;
else return 1.;
if (v == "EXA") {
return 1.e18;
} else if (v == "PETA") {
return 1.e15;
} else if (v == "TERA") {
return 1.e12;
} else if (v == "GIGA") {
return 1.e9;
} else if (v == "MEGA") {
return 1.e6;
} else if (v == "KILO") {
return 1.e3;
} else if (v == "HECTO") {
return 1.e2;
} else if (v == "DECA") {
return 1.e1;
} else if (v == "DECI") {
return 1.e-1;
} else if (v == "CENTI") {
return 1.e-2;
} else if (v == "MILLI") {
return 1.e-3;
} else if (v == "MICRO") {
return 1.e-6;
} else if (v == "NANO") {
return 1.e-9;
} else if (v == "PICO") {
return 1.e-12;
} else if (v == "FEMTO") {
return 1.e-15;
} else if (v == "ATTO") {
return 1.e-18;
} else {
return 1.;
}
}
template <typename Schema>
double IfcParse::get_SI_equivalent(typename Schema::IfcNamedUnit* named_unit) {
double scale = 1.;
typename Schema::IfcSIUnit* si_unit = 0;
double scale = 1.;
typename Schema::IfcSIUnit* si_unit = 0;
if (named_unit->declaration().is(Schema::IfcConversionBasedUnit::Class())) {
typename Schema::IfcConversionBasedUnit* conv_unit = named_unit->template as<typename Schema::IfcConversionBasedUnit>();
typename Schema::IfcMeasureWithUnit* factor = conv_unit->ConversionFactor();
typename Schema::IfcUnit* component = factor->UnitComponent();
if (component->declaration().is(Schema::IfcSIUnit::Class())) {
si_unit = component->template as<typename Schema::IfcSIUnit>();
typename Schema::IfcValue* v = factor->ValueComponent();
scale = *v->data().getArgument(0);
}
} else if (named_unit->declaration().is(Schema::IfcSIUnit::Class())) {
si_unit = named_unit->template as<typename Schema::IfcSIUnit>();
}
if (si_unit) {
if (si_unit->Prefix()) {
scale *= IfcSIPrefixToValue(Schema::IfcSIPrefix::ToString(*si_unit->Prefix()));
}
} else {
scale = 0.;
}
if (named_unit->declaration().is(Schema::IfcConversionBasedUnit::Class())) {
typename Schema::IfcConversionBasedUnit* conv_unit = named_unit->template as<typename Schema::IfcConversionBasedUnit>();
typename Schema::IfcMeasureWithUnit* factor = conv_unit->ConversionFactor();
typename Schema::IfcUnit* component = factor->UnitComponent();
if (component->declaration().is(Schema::IfcSIUnit::Class())) {
si_unit = component->template as<typename Schema::IfcSIUnit>();
typename Schema::IfcValue* v = factor->ValueComponent();
scale = *v->data().getArgument(0);
}
} else if (named_unit->declaration().is(Schema::IfcSIUnit::Class())) {
si_unit = named_unit->template as<typename Schema::IfcSIUnit>();
}
if (si_unit) {
if (si_unit->Prefix()) {
scale *= IfcSIPrefixToValue(Schema::IfcSIPrefix::ToString(*si_unit->Prefix()));
}
} else {
scale = 0.;
}
return scale;
return scale;
}
#if defined(_MSC_VER) && _MSC_VER < 1900
+5 -5
View File
@@ -20,14 +20,14 @@
#ifndef IFCSIPREFIX
#define IFCSIPREFIX
#include "../ifcparse/IfcParse.h"
#include "ifc_parse_api.h"
#include "IfcParse.h"
namespace IfcParse {
IFC_PARSE_API double IfcSIPrefixToValue(const std::string& prefix);
IFC_PARSE_API double IfcSIPrefixToValue(const std::string& prefix);
template <typename Schema>
IFC_PARSE_API double get_SI_equivalent(typename Schema::IfcNamedUnit*);
}
template <typename Schema>
IFC_PARSE_API double get_SI_equivalent(typename Schema::IfcNamedUnit*);
} // namespace IfcParse
#endif
+168 -133
View File
@@ -1,226 +1,261 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#include "IfcSchema.h"
#include "../ifcparse/IfcBaseClass.h"
#include "IfcBaseClass.h"
#ifdef HAS_SCHEMA_2x3
#include "Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "Ifc4x3_add1.h"
#endif
#include <map>
bool IfcParse::declaration::is(const std::string& name) const {
const std::string* name_ptr = &name;
if (std::any_of(name.begin(), name.end(), [](char c) { return std::islower(c); })) {
temp_string_() = name;
boost::to_upper(temp_string_());
name_ptr = &temp_string_();
}
const std::string* name_ptr = &name;
if (std::any_of(name.begin(), name.end(), [](char c) { return std::islower(c); })) {
temp_string_() = name;
boost::to_upper(temp_string_());
name_ptr = &temp_string_();
}
if (name_upper_ == *name_ptr) return true;
if (name_upper_ == *name_ptr) {
return true;
}
if (this->as_entity() && this->as_entity()->supertype()) {
return this->as_entity()->supertype()->is(name);
} else if (this->as_type_declaration()) {
const IfcParse::named_type* nt = this->as_type_declaration()->declared_type()->as_named_type();
if (nt) return nt->is(name);
}
if (this->as_entity() && this->as_entity()->supertype()) {
return this->as_entity()->supertype()->is(name);
} else if (this->as_type_declaration()) {
const IfcParse::named_type* nt = this->as_type_declaration()->declared_type()->as_named_type();
if (nt) {
return nt->is(name);
}
}
return false;
return false;
}
bool IfcParse::declaration::is(const IfcParse::declaration& decl) const {
if (this == &decl) return true;
if (this == &decl) {
return true;
}
if (this->as_entity() && this->as_entity()->supertype()) {
return this->as_entity()->supertype()->is(decl);
} else if (this->as_type_declaration()) {
const IfcParse::named_type* nt = this->as_type_declaration()->declared_type()->as_named_type();
if (nt) return nt->is(decl);
}
if (this->as_entity() && this->as_entity()->supertype()) {
return this->as_entity()->supertype()->is(decl);
} else if (this->as_type_declaration()) {
const IfcParse::named_type* nt = this->as_type_declaration()->declared_type()->as_named_type();
if (nt) {
return nt->is(decl);
}
}
return false;
return false;
}
bool IfcParse::named_type::is(const std::string& name) const {
return declared_type()->is(name);
return declared_type()->is(name);
}
bool IfcParse::named_type::is(const IfcParse::declaration& decl) const {
return declared_type()->is(decl);
return declared_type()->is(decl);
}
IfcParse::entity::~entity() {
for (auto attribute : attributes_) {
delete attribute;
}
for (auto inverse_attribute : inverse_attributes_) {
delete inverse_attribute;
}
for (auto attribute : attributes_) {
delete attribute;
}
for (auto inverse_attribute : inverse_attributes_) {
delete inverse_attribute;
}
}
static std::map<std::string, const IfcParse::schema_definition*> schemas;
IfcParse::schema_definition::schema_definition(const std::string& name, const std::vector<const declaration*>& declarations, instance_factory* factory)
: name_(name)
, declarations_(declarations)
, factory_(factory)
{
std::sort(declarations_.begin(), declarations_.end(), declaration_by_index_sort());
for (std::vector<const declaration*>::iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
(**it).schema_ = this;
: name_(name),
declarations_(declarations),
factory_(factory) {
std::sort(declarations_.begin(), declarations_.end(), declaration_by_index_sort());
for (std::vector<const declaration*>::iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
(**it).schema_ = this;
if ((**it).as_type_declaration()) type_declarations_.push_back((**it).as_type_declaration());
if ((**it).as_select_type()) select_types_.push_back((**it).as_select_type());
if ((**it).as_enumeration_type()) enumeration_types_.push_back((**it).as_enumeration_type());
if ((**it).as_entity()) entities_.push_back((**it).as_entity());
}
schemas[name_] = this;
if ((**it).as_type_declaration()) {
type_declarations_.push_back((**it).as_type_declaration());
}
if ((**it).as_select_type()) {
select_types_.push_back((**it).as_select_type());
}
if ((**it).as_enumeration_type()) {
enumeration_types_.push_back((**it).as_enumeration_type());
}
if ((**it).as_entity()) {
entities_.push_back((**it).as_entity());
}
}
schemas[name_] = this;
}
IfcParse::schema_definition::~schema_definition() {
for (std::vector<const declaration*>::const_iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
delete *it;
}
delete factory_;
for (std::vector<const declaration*>::const_iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
delete *it;
}
delete factory_;
}
IfcUtil::IfcBaseClass* IfcParse::schema_definition::instantiate(IfcEntityInstanceData * data) const {
if (factory_) {
return (*factory_)(data);
} else {
return new IfcUtil::IfcLateBoundEntity(data->type(), data);
}
IfcUtil::IfcBaseClass* IfcParse::schema_definition::instantiate(IfcEntityInstanceData* data) const {
if (factory_) {
return (*factory_)(data);
} else {
return new IfcUtil::IfcLateBoundEntity(data->type(), data);
}
}
void IfcParse::register_schema(schema_definition* s) {
schemas.insert({ boost::to_upper_copy(s->name()), s });
schemas.insert({boost::to_upper_copy(s->name()), s});
}
#ifdef HAS_SCHEMA_2x3
#include "../ifcparse/Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "../ifcparse/Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "../ifcparse/Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "../ifcparse/Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "../ifcparse/Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "../ifcparse/Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "../ifcparse/Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "../ifcparse/Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "../ifcparse/Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "../ifcparse/Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "../ifcparse/Ifc4x3_add1.h"
#endif
const IfcParse::schema_definition* IfcParse::schema_by_name(const std::string& name) {
// TODO: initialize automatically somehow
// TODO: initialize automatically somehow
#ifdef HAS_SCHEMA_2x3
Ifc2x3::get_schema();
Ifc2x3::get_schema();
#endif
#ifdef HAS_SCHEMA_4
Ifc4::get_schema();
Ifc4::get_schema();
#endif
#ifdef HAS_SCHEMA_4x1
Ifc4x1::get_schema();
Ifc4x1::get_schema();
#endif
#ifdef HAS_SCHEMA_4x2
Ifc4x2::get_schema();
Ifc4x2::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc1
Ifc4x3_rc1::get_schema();
Ifc4x3_rc1::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc2
Ifc4x3_rc2::get_schema();
Ifc4x3_rc2::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc3
Ifc4x3_rc3::get_schema();
Ifc4x3_rc3::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc4
Ifc4x3_rc4::get_schema();
Ifc4x3_rc4::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3
Ifc4x3::get_schema();
Ifc4x3::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3_tc1
Ifc4x3_tc1::get_schema();
Ifc4x3_tc1::get_schema();
#endif
#ifdef HAS_SCHEMA_4x3_add1
Ifc4x3_add1::get_schema();
Ifc4x3_add1::get_schema();
#endif
std::map<std::string, const IfcParse::schema_definition*>::const_iterator it = schemas.find(boost::to_upper_copy(name));
if (it == schemas.end()) {
throw IfcParse::IfcException("No schema named " + name);
}
return it->second;
std::map<std::string, const IfcParse::schema_definition*>::const_iterator it = schemas.find(boost::to_upper_copy(name));
if (it == schemas.end()) {
throw IfcParse::IfcException("No schema named " + name);
}
return it->second;
}
std::vector<std::string> IfcParse::schema_names() {
// Load schema modules
try {
IfcParse::schema_by_name("IFC2X3");
} catch (IfcParse::IfcException&) {}
// Load schema modules
try {
IfcParse::schema_by_name("IFC2X3");
} catch (IfcParse::IfcException&) {
}
// Populate vector with map keys
std::vector<std::string> return_value;
for (auto& pair : schemas) {
return_value.push_back(pair.first);
}
// Populate vector with map keys
std::vector<std::string> return_value;
for (auto& pair : schemas) {
return_value.push_back(pair.first);
}
return return_value;
return return_value;
}
void IfcParse::clear_schemas() {
#ifdef HAS_SCHEMA_2x3
Ifc2x3::clear_schema();
Ifc2x3::clear_schema();
#endif
#ifdef HAS_SCHEMA_4
Ifc4::clear_schema();
Ifc4::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x1
Ifc4x1::clear_schema();
Ifc4x1::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x2
Ifc4x2::clear_schema();
Ifc4x2::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc1
Ifc4x3_rc1::clear_schema();
Ifc4x3_rc1::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc2
Ifc4x3_rc2::clear_schema();
Ifc4x3_rc2::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc3
Ifc4x3_rc3::clear_schema();
Ifc4x3_rc3::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3_rc4
Ifc4x3_rc4::clear_schema();
Ifc4x3_rc4::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3
Ifc4x3::clear_schema();
Ifc4x3::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3_tc1
Ifc4x3_tc1::clear_schema();
Ifc4x3_tc1::clear_schema();
#endif
#ifdef HAS_SCHEMA_4x3_add1
Ifc4x3_add1::clear_schema();
Ifc4x3_add1::clear_schema();
#endif
// clear any remaining registered schemas
// we pop schemas until map is empty, because map iteration is invalidated after each erasure
while (!schemas.empty()) {
delete schemas.begin()->second;
}
// clear any remaining registered schemas
// we pop schemas until map is empty, because map iteration is invalidated after each erasure
while (!schemas.empty()) {
delete schemas.begin()->second;
}
}
+478 -455
View File
@@ -20,474 +20,497 @@
#ifndef IFCSCHEMA_H
#define IFCSCHEMA_H
#include "IfcException.h"
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <cctype>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cctype>
#include <boost/algorithm/string.hpp>
#include "../ifcparse/IfcException.h"
// Forward declarations
class IfcEntityInstanceData;
namespace IfcUtil {
class IfcBaseClass;
class IfcBaseEntity;
class IfcBaseType;
}
class IfcBaseClass;
class IfcBaseEntity;
class IfcBaseType;
} // namespace IfcUtil
namespace IfcParse {
class declaration;
class type_declaration;
class select_type;
class enumeration_type;
class entity;
class named_type;
class simple_type;
class aggregation_type;
class schema_definition;
class IFC_PARSE_API parameter_type {
public:
virtual ~parameter_type() {}
virtual const named_type* as_named_type() const { return static_cast<named_type*>(0); }
virtual const simple_type* as_simple_type() const { return static_cast<simple_type*>(0); }
virtual const aggregation_type* as_aggregation_type() const { return static_cast<aggregation_type*>(0); }
virtual bool is(const std::string& /*name*/) const { return false; }
virtual bool is(const IfcParse::declaration& /*decl*/) const { return false; }
};
class IFC_PARSE_API named_type : public parameter_type {
protected:
declaration* declared_type_;
public:
named_type(declaration* declared_type)
: declared_type_(declared_type) {}
declaration* declared_type() const { return declared_type_; }
class declaration;
class type_declaration;
class select_type;
class enumeration_type;
class entity;
class named_type;
class simple_type;
class aggregation_type;
class schema_definition;
class IFC_PARSE_API parameter_type {
public:
virtual ~parameter_type() {}
virtual const named_type* as_named_type() const { return static_cast<named_type*>(0); }
virtual const simple_type* as_simple_type() const { return static_cast<simple_type*>(0); }
virtual const aggregation_type* as_aggregation_type() const { return static_cast<aggregation_type*>(0); }
virtual bool is(const std::string& /*name*/) const { return false; }
virtual bool is(const IfcParse::declaration& /*decl*/) const { return false; }
};
class IFC_PARSE_API named_type : public parameter_type {
protected:
declaration* declared_type_;
public:
named_type(declaration* declared_type)
: declared_type_(declared_type) {}
declaration* declared_type() const { return declared_type_; }
virtual const named_type* as_named_type() const { return this; }
virtual const named_type* as_named_type() const { return this; }
virtual bool is(const std::string& name) const;
virtual bool is(const IfcParse::declaration& decl) const;
};
class IFC_PARSE_API simple_type : public parameter_type {
public:
typedef enum { binary_type, boolean_type, integer_type, logical_type, number_type, real_type, string_type, datatype_COUNT } data_type;
protected:
data_type declared_type_;
public:
simple_type(data_type declared_type)
: declared_type_(declared_type) {}
virtual bool is(const std::string& name) const;
virtual bool is(const IfcParse::declaration& decl) const;
};
data_type declared_type() const { return declared_type_; }
class IFC_PARSE_API simple_type : public parameter_type {
public:
typedef enum {
binary_type,
boolean_type,
integer_type,
logical_type,
number_type,
real_type,
string_type,
datatype_COUNT
} data_type;
virtual const simple_type* as_simple_type() const { return this; }
};
class IFC_PARSE_API aggregation_type : public parameter_type {
public:
typedef enum { array_type, bag_type, list_type, set_type } aggregate_type;
protected:
aggregate_type type_of_aggregation_;
int bound1_, bound2_;
parameter_type* type_of_element_;
public:
aggregation_type(aggregate_type type_of_aggregation, int bound1, int bound2, parameter_type* type_of_element)
: type_of_aggregation_(type_of_aggregation)
, bound1_(bound1)
, bound2_(bound2)
, type_of_element_(type_of_element)
{}
virtual ~aggregation_type() { delete type_of_element_; }
aggregate_type type_of_aggregation() const { return type_of_aggregation_; }
int bound1() const { return bound1_; }
int bound2() const { return bound2_; }
parameter_type* type_of_element() const { return type_of_element_; }
virtual const aggregation_type* as_aggregation_type() const { return this; }
};
class IFC_PARSE_API declaration {
friend class schema_definition;
protected:
std::string name_, name_upper_;
int index_in_schema_;
mutable const schema_definition* schema_;
std::string& temp_string_() const {
static my_thread_local std::string s;
return s;
}
public:
declaration(const std::string& name, int index_in_schema)
: name_(name)
, name_upper_(boost::to_upper_copy(name))
, index_in_schema_(index_in_schema)
, schema_(0)
{}
virtual ~declaration() {}
const std::string& name() const { return name_; }
const std::string& name_uc() const { return name_upper_; }
virtual const type_declaration* as_type_declaration() const { return static_cast<type_declaration*>(0); }
virtual const select_type* as_select_type() const { return static_cast<select_type*>(0); }
virtual const enumeration_type* as_enumeration_type() const { return static_cast<enumeration_type*>(0); }
virtual const entity* as_entity() const { return static_cast<entity*>(0); }
bool is(const std::string& name) const;
bool is(const IfcParse::declaration& decl) const;
int index_in_schema() const { return index_in_schema_; }
int type() const { return index_in_schema_; }
const schema_definition* schema() const { return schema_; }
};
class IFC_PARSE_API type_declaration : public declaration {
protected:
const parameter_type* declared_type_;
public:
type_declaration(const std::string& name, int index_in_schema, const parameter_type* declared_type)
: declaration(name, index_in_schema)
, declared_type_(declared_type) {}
virtual ~type_declaration() { delete declared_type_; }
const parameter_type* declared_type() const { return declared_type_; }
virtual const type_declaration* as_type_declaration() const { return this; }
};
class IFC_PARSE_API select_type : public declaration {
protected:
std::vector<const declaration*> select_list_;
public:
select_type(const std::string& name, int index_in_schema, const std::vector<const declaration*>& select_list)
: declaration(name, index_in_schema)
, select_list_(select_list) {}
const std::vector<const declaration*>& select_list() const { return select_list_; }
virtual const select_type* as_select_type() const { return this; }
};
class IFC_PARSE_API enumeration_type : public declaration {
protected:
std::vector<std::string> enumeration_items_;
public:
enumeration_type(const std::string& name, int index_in_schema, const std::vector<std::string>& enumeration_items)
: declaration(name, index_in_schema)
, enumeration_items_(enumeration_items) {}
const std::vector<std::string>& enumeration_items() const { return enumeration_items_; }
const char* lookup_enum_value(size_t i) const {
if (i >= enumeration_items_.size()) {
throw IfcParse::IfcException("Unable to find keyword in schema for index " + std::to_string(i));
}
return enumeration_items_[i].c_str();
}
size_t lookup_enum_offset(const std::string& s) const {
size_t i = 0;
for (auto it = enumeration_items_.begin(); it != enumeration_items_.end(); ++it, ++i) {
if (s == *it) {
return i;
}
}
throw IfcParse::IfcException("Unable to find keyword in schema: " + s);
}
virtual const enumeration_type* as_enumeration_type() const { return this; }
};
class IFC_PARSE_API attribute {
protected:
std::string name_;
const parameter_type* type_of_attribute_;
bool optional_;
public:
attribute(const std::string& name, parameter_type* type_of_attribute, bool optional)
: name_(name)
, type_of_attribute_(type_of_attribute)
, optional_(optional) {}
~attribute() { delete type_of_attribute_; }
const std::string& name() const { return name_; }
const parameter_type* type_of_attribute() const { return type_of_attribute_; }
bool optional() const { return optional_; }
};
class IFC_PARSE_API inverse_attribute {
public:
typedef enum { bag_type, set_type, unspecified_type } aggregate_type;
protected:
std::string name_;
aggregate_type type_of_aggregation_;
int bound1_, bound2_;
const entity* entity_reference_;
const attribute* attribute_reference_;
public:
inverse_attribute(const std::string& name, aggregate_type type_of_aggregation, int bound1, int bound2, const entity* entity_reference, const attribute* attribute_reference)
: name_(name)
, type_of_aggregation_(type_of_aggregation)
, bound1_(bound1)
, bound2_(bound2)
, entity_reference_(entity_reference)
, attribute_reference_(attribute_reference) {}
const std::string& name() const { return name_; }
aggregate_type type_of_aggregation() const { return type_of_aggregation_; }
int bound1() const { return bound1_; }
int bound2() const { return bound2_; }
const entity* entity_reference() const { return entity_reference_; }
const attribute* attribute_reference() const { return attribute_reference_; }
};
class IFC_PARSE_API entity : public declaration {
protected:
bool is_abstract_;
const entity* supertype_; /* NB: IFC explicitly allows only single inheritance */
std::vector<const entity*> subtypes_;
std::vector<const attribute*> attributes_;
std::vector<bool> derived_;
std::vector<const inverse_attribute*> inverse_attributes_;
class attribute_by_name_cmp {
private:
std::string name_;
public:
attribute_by_name_cmp(const std::string name)
: name_(name) {}
bool operator()(const attribute* attr) {
return attr->name() == name_;
}
};
const attribute* attribute_by_index_(size_t& index) const {
const attribute* attr = 0;
if (supertype_) {
attr = supertype_->attribute_by_index_(index);
}
if (attr == 0) {
if (index < attributes_.size()) {
attr = attributes_[index];
}
index -= attributes_.size();
}
return attr;
}
public:
entity(const std::string& name, bool is_abstract, int index_in_schema, entity* supertype)
: declaration(name, index_in_schema)
, is_abstract_(is_abstract)
, supertype_(supertype)
{}
virtual ~entity();
bool is_abstract() const { return is_abstract_; }
void set_subtypes(const std::vector<const entity*>& subtypes) {
subtypes_ = subtypes;
}
void set_attributes(const std::vector<const attribute*>& attributes, const std::vector<bool>& derived) {
attributes_ = attributes;
derived_ = derived;
}
void set_inverse_attributes(const std::vector<const inverse_attribute*>& inverse_attributes) {
inverse_attributes_ = inverse_attributes;
}
const std::vector<const entity*>& subtypes() const { return subtypes_; }
const std::vector<const attribute*>& attributes() const { return attributes_; }
const std::vector<bool>& derived() const { return derived_; }
const std::vector<const attribute*> all_attributes() const {
std::vector<const attribute*> attrs;
attrs.reserve(derived_.size());
if (supertype_) {
const std::vector<const attribute*> supertype_attrs = supertype_->all_attributes();
std::copy(supertype_attrs.begin(), supertype_attrs.end(), std::back_inserter(attrs));
}
std::copy(attributes_.begin(), attributes_.end(), std::back_inserter(attrs));
return attrs;
}
const std::vector<const inverse_attribute*> all_inverse_attributes() const {
std::vector<const inverse_attribute*> attrs;
if (supertype_) {
const std::vector<const inverse_attribute*> supertype_inv_attrs = supertype_->all_inverse_attributes();
std::copy(supertype_inv_attrs.begin(), supertype_inv_attrs.end(), std::back_inserter(attrs));
}
std::copy(inverse_attributes_.begin(), inverse_attributes_.end(), std::back_inserter(attrs));
return attrs;
}
const attribute* attribute_by_index(size_t index) const {
const attribute* attr = attribute_by_index_(index);
if (attr == 0) {
throw IfcParse::IfcException("Attribute index out of bounds");
}
return attr;
}
size_t attribute_count() const {
size_t super_count = 0;
if (supertype_) {
super_count = supertype_->attribute_count();
}
return super_count + attributes_.size();
}
ptrdiff_t attribute_index(const attribute* attr) const {
const entity* current = this;
ptrdiff_t index = -1;
do {
if (index > -1) {
index += current->attributes().size();
} else {
std::vector<const attribute*>::const_iterator it;
it = std::find(current->attributes().begin(), current->attributes().end(), attr);
if (it != current->attributes().end()) {
index = std::distance(current->attributes().begin(), it);
}
}
} while ((current = current->supertype_) != 0);
return index;
}
ptrdiff_t attribute_index(const std::string& attr_name) const {
const entity* current = this;
ptrdiff_t index = -1;
attribute_by_name_cmp cmp(attr_name);
do {
if (index > -1) {
index += current->attributes().size();
} else {
std::vector<const attribute*>::const_iterator it;
it = std::find_if(current->attributes().begin(), current->attributes().end(), cmp);
if (it != current->attributes().end()) {
index = std::distance(current->attributes().begin(), it);
}
}
} while ((current = current->supertype_) != 0);
return index;
}
const entity* supertype() const { return supertype_; }
virtual const entity* as_entity() const { return this; }
};
class IFC_PARSE_API instance_factory {
public:
virtual ~instance_factory() {}
virtual IfcUtil::IfcBaseClass* operator()(IfcEntityInstanceData* data) const = 0;
};
class IFC_PARSE_API schema_definition {
private:
std::string name_;
std::vector<const declaration*> declarations_;
std::vector<const type_declaration*> type_declarations_;
std::vector<const select_type*> select_types_;
std::vector<const enumeration_type*> enumeration_types_;
std::vector<const entity*> entities_;
class declaration_by_name_cmp {
public:
bool operator()(const declaration* decl, const std::string& name) {
return decl->name_uc() < name;
}
};
class declaration_by_index_sort {
public:
bool operator()(const declaration* a, const declaration* b) {
return a->index_in_schema() < b->index_in_schema();
}
};
instance_factory* factory_;
std::string& temp_string_() const {
static my_thread_local std::string s;
return s;
}
public:
schema_definition(const std::string& name, const std::vector<const declaration*>& declarations, instance_factory* factory);
~schema_definition();
const declaration* declaration_by_name(const std::string& name) const {
const std::string* name_ptr = &name;
if (std::any_of(name.begin(), name.end(), [](char c) { return std::islower(c); })) {
temp_string_() = name;
boost::to_upper(temp_string_());
name_ptr = &temp_string_();
}
std::vector<const declaration*>::const_iterator it = std::lower_bound(declarations_.begin(), declarations_.end(), *name_ptr, declaration_by_name_cmp());
if (it == declarations_.end() || (**it).name_uc() != *name_ptr) {
throw IfcParse::IfcException("Entity with name '" + name + "' not found in schema '" + name_ + "'");
} else {
return *it;
}
}
const declaration* declaration_by_name(int name) const {
return declarations_[name];
}
const std::vector<const declaration*>& declarations() const { return declarations_; }
const std::vector<const type_declaration*>& type_declarations() const { return type_declarations_; }
const std::vector<const select_type*>& select_types() const { return select_types_; }
const std::vector<const enumeration_type*>& enumeration_types() const { return enumeration_types_; }
const std::vector<const entity*>& entities() const { return entities_; }
const std::string& name() const { return name_; }
IfcUtil::IfcBaseClass* instantiate(IfcEntityInstanceData* data) const;
};
IFC_PARSE_API const schema_definition* schema_by_name(const std::string&);
IFC_PARSE_API std::vector<std::string> schema_names();
IFC_PARSE_API void register_schema(schema_definition*);
IFC_PARSE_API void clear_schemas();
}
protected:
data_type declared_type_;
public:
simple_type(data_type declared_type)
: declared_type_(declared_type) {}
data_type declared_type() const { return declared_type_; }
virtual const simple_type* as_simple_type() const { return this; }
};
class IFC_PARSE_API aggregation_type : public parameter_type {
public:
typedef enum {
array_type,
bag_type,
list_type,
set_type
} aggregate_type;
protected:
aggregate_type type_of_aggregation_;
int bound1_, bound2_;
parameter_type* type_of_element_;
public:
aggregation_type(aggregate_type type_of_aggregation, int bound1, int bound2, parameter_type* type_of_element)
: type_of_aggregation_(type_of_aggregation),
bound1_(bound1),
bound2_(bound2),
type_of_element_(type_of_element) {}
virtual ~aggregation_type() { delete type_of_element_; }
aggregate_type type_of_aggregation() const { return type_of_aggregation_; }
int bound1() const { return bound1_; }
int bound2() const { return bound2_; }
parameter_type* type_of_element() const { return type_of_element_; }
virtual const aggregation_type* as_aggregation_type() const { return this; }
};
class IFC_PARSE_API declaration {
friend class schema_definition;
protected:
std::string name_, name_upper_;
int index_in_schema_;
mutable const schema_definition* schema_;
std::string& temp_string_() const {
static my_thread_local std::string s;
return s;
}
public:
declaration(const std::string& name, int index_in_schema)
: name_(name),
name_upper_(boost::to_upper_copy(name)),
index_in_schema_(index_in_schema),
schema_(0) {}
virtual ~declaration() {}
const std::string& name() const { return name_; }
const std::string& name_uc() const { return name_upper_; }
virtual const type_declaration* as_type_declaration() const { return static_cast<type_declaration*>(0); }
virtual const select_type* as_select_type() const { return static_cast<select_type*>(0); }
virtual const enumeration_type* as_enumeration_type() const { return static_cast<enumeration_type*>(0); }
virtual const entity* as_entity() const { return static_cast<entity*>(0); }
bool is(const std::string& name) const;
bool is(const IfcParse::declaration& decl) const;
int index_in_schema() const { return index_in_schema_; }
int type() const { return index_in_schema_; }
const schema_definition* schema() const { return schema_; }
};
class IFC_PARSE_API type_declaration : public declaration {
protected:
const parameter_type* declared_type_;
public:
type_declaration(const std::string& name, int index_in_schema, const parameter_type* declared_type)
: declaration(name, index_in_schema),
declared_type_(declared_type) {}
virtual ~type_declaration() { delete declared_type_; }
const parameter_type* declared_type() const { return declared_type_; }
virtual const type_declaration* as_type_declaration() const { return this; }
};
class IFC_PARSE_API select_type : public declaration {
protected:
std::vector<const declaration*> select_list_;
public:
select_type(const std::string& name, int index_in_schema, const std::vector<const declaration*>& select_list)
: declaration(name, index_in_schema),
select_list_(select_list) {}
const std::vector<const declaration*>& select_list() const { return select_list_; }
virtual const select_type* as_select_type() const { return this; }
};
class IFC_PARSE_API enumeration_type : public declaration {
protected:
std::vector<std::string> enumeration_items_;
public:
enumeration_type(const std::string& name, int index_in_schema, const std::vector<std::string>& enumeration_items)
: declaration(name, index_in_schema),
enumeration_items_(enumeration_items) {}
const std::vector<std::string>& enumeration_items() const { return enumeration_items_; }
const char* lookup_enum_value(size_t i) const {
if (i >= enumeration_items_.size()) {
throw IfcParse::IfcException("Unable to find keyword in schema for index " + std::to_string(i));
}
return enumeration_items_[i].c_str();
}
size_t lookup_enum_offset(const std::string& s) const {
size_t i = 0;
for (auto it = enumeration_items_.begin(); it != enumeration_items_.end(); ++it, ++i) {
if (s == *it) {
return i;
}
}
throw IfcParse::IfcException("Unable to find keyword in schema: " + s);
}
virtual const enumeration_type* as_enumeration_type() const { return this; }
};
class IFC_PARSE_API attribute {
protected:
std::string name_;
const parameter_type* type_of_attribute_;
bool optional_;
public:
attribute(const std::string& name, parameter_type* type_of_attribute, bool optional)
: name_(name),
type_of_attribute_(type_of_attribute),
optional_(optional) {}
~attribute() { delete type_of_attribute_; }
const std::string& name() const { return name_; }
const parameter_type* type_of_attribute() const { return type_of_attribute_; }
bool optional() const { return optional_; }
};
class IFC_PARSE_API inverse_attribute {
public:
typedef enum {
bag_type,
set_type,
unspecified_type
} aggregate_type;
protected:
std::string name_;
aggregate_type type_of_aggregation_;
int bound1_, bound2_;
const entity* entity_reference_;
const attribute* attribute_reference_;
public:
inverse_attribute(const std::string& name, aggregate_type type_of_aggregation, int bound1, int bound2, const entity* entity_reference, const attribute* attribute_reference)
: name_(name),
type_of_aggregation_(type_of_aggregation),
bound1_(bound1),
bound2_(bound2),
entity_reference_(entity_reference),
attribute_reference_(attribute_reference) {}
const std::string& name() const { return name_; }
aggregate_type type_of_aggregation() const { return type_of_aggregation_; }
int bound1() const { return bound1_; }
int bound2() const { return bound2_; }
const entity* entity_reference() const { return entity_reference_; }
const attribute* attribute_reference() const { return attribute_reference_; }
};
class IFC_PARSE_API entity : public declaration {
protected:
bool is_abstract_;
const entity* supertype_; /* NB: IFC explicitly allows only single inheritance */
std::vector<const entity*> subtypes_;
std::vector<const attribute*> attributes_;
std::vector<bool> derived_;
std::vector<const inverse_attribute*> inverse_attributes_;
class attribute_by_name_cmp {
private:
std::string name_;
public:
attribute_by_name_cmp(const std::string name)
: name_(name) {}
bool operator()(const attribute* attr) {
return attr->name() == name_;
}
};
const attribute* attribute_by_index_(size_t& index) const {
const attribute* attr = 0;
if (supertype_) {
attr = supertype_->attribute_by_index_(index);
}
if (attr == 0) {
if (index < attributes_.size()) {
attr = attributes_[index];
}
index -= attributes_.size();
}
return attr;
}
public:
entity(const std::string& name, bool is_abstract, int index_in_schema, entity* supertype)
: declaration(name, index_in_schema),
is_abstract_(is_abstract),
supertype_(supertype) {}
virtual ~entity();
bool is_abstract() const { return is_abstract_; }
void set_subtypes(const std::vector<const entity*>& subtypes) {
subtypes_ = subtypes;
}
void set_attributes(const std::vector<const attribute*>& attributes, const std::vector<bool>& derived) {
attributes_ = attributes;
derived_ = derived;
}
void set_inverse_attributes(const std::vector<const inverse_attribute*>& inverse_attributes) {
inverse_attributes_ = inverse_attributes;
}
const std::vector<const entity*>& subtypes() const { return subtypes_; }
const std::vector<const attribute*>& attributes() const { return attributes_; }
const std::vector<bool>& derived() const { return derived_; }
const std::vector<const attribute*> all_attributes() const {
std::vector<const attribute*> attrs;
attrs.reserve(derived_.size());
if (supertype_) {
const std::vector<const attribute*> supertype_attrs = supertype_->all_attributes();
std::copy(supertype_attrs.begin(), supertype_attrs.end(), std::back_inserter(attrs));
}
std::copy(attributes_.begin(), attributes_.end(), std::back_inserter(attrs));
return attrs;
}
const std::vector<const inverse_attribute*> all_inverse_attributes() const {
std::vector<const inverse_attribute*> attrs;
if (supertype_) {
const std::vector<const inverse_attribute*> supertype_inv_attrs = supertype_->all_inverse_attributes();
std::copy(supertype_inv_attrs.begin(), supertype_inv_attrs.end(), std::back_inserter(attrs));
}
std::copy(inverse_attributes_.begin(), inverse_attributes_.end(), std::back_inserter(attrs));
return attrs;
}
const attribute* attribute_by_index(size_t index) const {
const attribute* attr = attribute_by_index_(index);
if (attr == 0) {
throw IfcParse::IfcException("Attribute index out of bounds");
}
return attr;
}
size_t attribute_count() const {
size_t super_count = 0;
if (supertype_) {
super_count = supertype_->attribute_count();
}
return super_count + attributes_.size();
}
ptrdiff_t attribute_index(const attribute* attr) const {
const entity* current = this;
ptrdiff_t index = -1;
do {
if (index > -1) {
index += current->attributes().size();
} else {
std::vector<const attribute*>::const_iterator it;
it = std::find(current->attributes().begin(), current->attributes().end(), attr);
if (it != current->attributes().end()) {
index = std::distance(current->attributes().begin(), it);
}
}
} while ((current = current->supertype_) != 0);
return index;
}
ptrdiff_t attribute_index(const std::string& attr_name) const {
const entity* current = this;
ptrdiff_t index = -1;
attribute_by_name_cmp cmp(attr_name);
do {
if (index > -1) {
index += current->attributes().size();
} else {
std::vector<const attribute*>::const_iterator it;
it = std::find_if(current->attributes().begin(), current->attributes().end(), cmp);
if (it != current->attributes().end()) {
index = std::distance(current->attributes().begin(), it);
}
}
} while ((current = current->supertype_) != 0);
return index;
}
const entity* supertype() const { return supertype_; }
virtual const entity* as_entity() const { return this; }
};
class IFC_PARSE_API instance_factory {
public:
virtual ~instance_factory() {}
virtual IfcUtil::IfcBaseClass* operator()(IfcEntityInstanceData* data) const = 0;
};
class IFC_PARSE_API schema_definition {
private:
std::string name_;
std::vector<const declaration*> declarations_;
std::vector<const type_declaration*> type_declarations_;
std::vector<const select_type*> select_types_;
std::vector<const enumeration_type*> enumeration_types_;
std::vector<const entity*> entities_;
class declaration_by_name_cmp {
public:
bool operator()(const declaration* decl, const std::string& name) {
return decl->name_uc() < name;
}
};
class declaration_by_index_sort {
public:
bool operator()(const declaration* a, const declaration* b) {
return a->index_in_schema() < b->index_in_schema();
}
};
instance_factory* factory_;
std::string& temp_string_() const {
static my_thread_local std::string s;
return s;
}
public:
schema_definition(const std::string& name, const std::vector<const declaration*>& declarations, instance_factory* factory);
~schema_definition();
const declaration* declaration_by_name(const std::string& name) const {
const std::string* name_ptr = &name;
if (std::any_of(name.begin(), name.end(), [](char c) { return std::islower(c); })) {
temp_string_() = name;
boost::to_upper(temp_string_());
name_ptr = &temp_string_();
}
std::vector<const declaration*>::const_iterator it = std::lower_bound(declarations_.begin(), declarations_.end(), *name_ptr, declaration_by_name_cmp());
if (it == declarations_.end() || (**it).name_uc() != *name_ptr) {
throw IfcParse::IfcException("Entity with name '" + name + "' not found in schema '" + name_ + "'");
} else {
return *it;
}
}
const declaration* declaration_by_name(int name) const {
return declarations_[name];
}
const std::vector<const declaration*>& declarations() const { return declarations_; }
const std::vector<const type_declaration*>& type_declarations() const { return type_declarations_; }
const std::vector<const select_type*>& select_types() const { return select_types_; }
const std::vector<const enumeration_type*>& enumeration_types() const { return enumeration_types_; }
const std::vector<const entity*>& entities() const { return entities_; }
const std::string& name() const { return name_; }
IfcUtil::IfcBaseClass* instantiate(IfcEntityInstanceData* data) const;
};
IFC_PARSE_API const schema_definition* schema_by_name(const std::string&);
IFC_PARSE_API std::vector<std::string> schema_names();
IFC_PARSE_API void register_schema(schema_definition*);
IFC_PARSE_API void clear_schemas();
} // namespace IfcParse
#endif
+108 -103
View File
@@ -17,17 +17,17 @@
* *
********************************************************************************/
#include "../ifcparse/IfcFile.h"
#include "IfcSpfHeader.h"
static const char * const ISO_10303_21 = "ISO-10303-21";
static const char * const HEADER = "HEADER";
static const char * const FILE_DESCRIPTION = "FILE_DESCRIPTION";
static const char * const FILE_NAME = "FILE_NAME";
static const char * const FILE_SCHEMA = "FILE_SCHEMA";
static const char * const ENDSEC = "ENDSEC";
static const char * const DATA = "DATA";
#include "IfcFile.h"
static const char* const ISO_10303_21 = "ISO-10303-21";
static const char* const HEADER = "HEADER";
static const char* const FILE_DESCRIPTION = "FILE_DESCRIPTION";
static const char* const FILE_NAME = "FILE_NAME";
static const char* const FILE_SCHEMA = "FILE_SCHEMA";
static const char* const ENDSEC = "ENDSEC";
static const char* const DATA = "DATA";
// The following header entities are not normally encountered in IFC files and are not parsed.
// static const char * const FILE_POPULATION = "FILE_POPULATION";
// static const char * const SECTION_LANGUAGE = "SECTION_LANGUAGE";
@@ -35,143 +35,148 @@ static const char * const DATA = "DATA";
using namespace IfcParse;
HeaderEntity::HeaderEntity(const char * const datatype, size_t size, IfcFile* file)
: IfcEntityInstanceData(file, size)
, _datatype(datatype)
, size_(size)
{
if (file) {
offset_in_file_ = file->stream->Tell();
load();
}
HeaderEntity::HeaderEntity(const char* const datatype, size_t size, IfcFile* file)
: IfcEntityInstanceData(file, size),
_datatype(datatype),
size_(size) {
if (file) {
offset_in_file_ = file->stream->Tell();
load();
}
}
HeaderEntity::~HeaderEntity()
{
clearArguments();
HeaderEntity::~HeaderEntity() {
clearArguments();
}
void IfcSpfHeader::readSemicolon() {
if (!TokenFunc::isOperator(file_->tokens->Next(), ';')) {
throw IfcException(std::string("Expected ;"));
}
if (!TokenFunc::isOperator(file_->tokens->Next(), ';')) {
throw IfcException(std::string("Expected ;"));
}
}
void IfcSpfHeader::readParen() {
if (!TokenFunc::isOperator(file_->tokens->Next(), '(')) {
throw IfcException(std::string("Expected ("));
}
if (!TokenFunc::isOperator(file_->tokens->Next(), '(')) {
throw IfcException(std::string("Expected ("));
}
}
void IfcSpfHeader::readTerminal(const std::string& term, Trail trail) {
if (TokenFunc::asStringRef(file_->tokens->Next()) != term) {
throw IfcException(std::string("Expected " + term));
}
if (trail == TRAILING_SEMICOLON) {
readSemicolon();
} else if (trail == TRAILING_PAREN) {
readParen();
}
if (TokenFunc::asStringRef(file_->tokens->Next()) != term) {
throw IfcException(std::string("Expected " + term));
}
if (trail == TRAILING_SEMICOLON) {
readSemicolon();
} else if (trail == TRAILING_PAREN) {
readParen();
}
}
void IfcSpfHeader::read() {
readTerminal(ISO_10303_21, TRAILING_SEMICOLON);
readTerminal(HEADER, TRAILING_SEMICOLON);
readTerminal(ISO_10303_21, TRAILING_SEMICOLON);
readTerminal(HEADER, TRAILING_SEMICOLON);
// | The header section of every exchange structure shall contain one
// | instance of each of the following entities: file_description, file_name,
// | and file_schema, and they shall appear in that order. Instances of
// | file_population, section_language and section_context may appear after
// | file_schema. If instances of user-defined header section entities are
// | present, they shall appear after the header section entity instances
// | defined in this section.
//
// ISO 10303-21 Second edition 2002-01-15 p. 16
// | The header section of every exchange structure shall contain one
// | instance of each of the following entities: file_description, file_name,
// | and file_schema, and they shall appear in that order. Instances of
// | file_population, section_language and section_context may appear after
// | file_schema. If instances of user-defined header section entities are
// | present, they shall appear after the header section entity instances
// | defined in this section.
//
// ISO 10303-21 Second edition 2002-01-15 p. 16
readTerminal(FILE_DESCRIPTION, NONE);
delete _file_description;
_file_description = new FileDescription(file_);
// readSemicolon();
readTerminal(FILE_DESCRIPTION, NONE);
delete _file_description;
_file_description = new FileDescription(file_);
// readSemicolon();
readTerminal(FILE_NAME, NONE);
delete _file_name;
_file_name = new FileName(file_);
// readSemicolon();
readTerminal(FILE_NAME, NONE);
delete _file_name;
_file_name = new FileName(file_);
// readSemicolon();
readTerminal(FILE_SCHEMA, NONE);
delete _file_schema;
_file_schema = new FileSchema(file_);
// readSemicolon();
readTerminal(FILE_SCHEMA, NONE);
delete _file_schema;
_file_schema = new FileSchema(file_);
// readSemicolon();
}
bool IfcSpfHeader::tryRead() {
try {
read();
return true;
} catch (const std::exception& e) {
Logger::Error(e);
return false;
}
try {
read();
return true;
} catch (const std::exception& e) {
Logger::Error(e);
return false;
}
}
void IfcSpfHeader::write(std::ostream& os) const {
os << ISO_10303_21 << ";" << "\n";
os << HEADER << ";" << "\n";
os << file_description().toString(true) << ";" << "\n";
os << file_name().toString(true) << ";" << "\n";
os << file_schema().toString(true) << ";" << "\n";
os << ENDSEC << ";" << "\n";
os << DATA << ";" << "\n";
os << ISO_10303_21 << ";"
<< "\n";
os << HEADER << ";"
<< "\n";
os << file_description().toString(true) << ";"
<< "\n";
os << file_name().toString(true) << ";"
<< "\n";
os << file_schema().toString(true) << ";"
<< "\n";
os << ENDSEC << ";"
<< "\n";
os << DATA << ";"
<< "\n";
}
const FileDescription& IfcSpfHeader::file_description() const {
if (_file_description) {
return *_file_description;
} else {
throw IfcException("File description not set");
}
if (_file_description) {
return *_file_description;
} else {
throw IfcException("File description not set");
}
}
const FileName& IfcSpfHeader::file_name() const {
if (_file_name) {
return *_file_name;
} else {
throw IfcException("File name not set");
}
if (_file_name) {
return *_file_name;
} else {
throw IfcException("File name not set");
}
}
const FileSchema& IfcSpfHeader::file_schema() const {
if (_file_schema) {
return *_file_schema;
} else {
throw IfcException("File schema not set");
}
if (_file_schema) {
return *_file_schema;
} else {
throw IfcException("File schema not set");
}
}
FileDescription& IfcSpfHeader::file_description() {
if (_file_description) {
return *_file_description;
} else {
throw IfcException("File description not set");
}
if (_file_description) {
return *_file_description;
} else {
throw IfcException("File description not set");
}
}
FileName& IfcSpfHeader::file_name() {
if (_file_name) {
return *_file_name;
} else {
throw IfcException("File name not set");
}
if (_file_name) {
return *_file_name;
} else {
throw IfcException("File name not set");
}
}
FileSchema& IfcSpfHeader::file_schema() {
if (_file_schema) {
return *_file_schema;
} else {
throw IfcException("File schema not set");
}
if (_file_schema) {
return *_file_schema;
} else {
throw IfcException("File schema not set");
}
}
FileDescription::FileDescription(IfcFile* file) : HeaderEntity(FILE_DESCRIPTION, 2, file) {}
FileName::FileName(IfcFile* file) : HeaderEntity(FILE_NAME, 7, file) {}
FileSchema::FileSchema(IfcFile* file) : HeaderEntity(FILE_SCHEMA, 1, file) {}
FileSchema::FileSchema(IfcFile* file) : HeaderEntity(FILE_SCHEMA, 1, file) {}
+100 -99
View File
@@ -16,140 +16,141 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef IFCSPFHEADER_H
#define IFCSPFHEADER_H
#include "ifc_parse_api.h"
#include "../ifcparse/IfcSpfStream.h"
#include "../ifcparse/IfcWrite.h"
#include "IfcSpfStream.h"
#include "IfcWrite.h"
namespace IfcParse {
class IFC_PARSE_API HeaderEntity : public IfcEntityInstanceData {
private:
const char * const _datatype;
size_t size_;
private:
const char* const _datatype;
size_t size_;
HeaderEntity(const HeaderEntity&); //N/A
HeaderEntity& operator =(const HeaderEntity&); //N/A
protected:
HeaderEntity(const char * const datatype, size_t size, IfcParse::IfcFile* file);
virtual ~HeaderEntity();
HeaderEntity(const HeaderEntity&); //N/A
HeaderEntity& operator=(const HeaderEntity&); //N/A
protected:
HeaderEntity(const char* const datatype, size_t size, IfcParse::IfcFile* file);
virtual ~HeaderEntity();
void setValue(unsigned int i, const std::string& s) {
IfcWrite::IfcWriteArgument* argument = new IfcWrite::IfcWriteArgument;
argument->set(s);
setArgument(i, argument);
}
void setValue(unsigned int i, const std::string& s) {
IfcWrite::IfcWriteArgument* argument = new IfcWrite::IfcWriteArgument;
argument->set(s);
setArgument(i, argument);
}
void setValue(unsigned int i, const std::vector<std::string>& s) {
IfcWrite::IfcWriteArgument* argument = new IfcWrite::IfcWriteArgument;
argument->set(s);
setArgument(i, argument);
}
void setValue(unsigned int i, const std::vector<std::string>& s) {
IfcWrite::IfcWriteArgument* argument = new IfcWrite::IfcWriteArgument;
argument->set(s);
setArgument(i, argument);
}
public:
virtual size_t getArgumentCount() const {
return size_;
}
public:
virtual size_t getArgumentCount() const {
return size_;
}
std::string toString(bool upper=false) const {
std::stringstream ss;
ss << _datatype << IfcEntityInstanceData::toString(upper);
return ss.str();
}
std::string toString(bool upper = false) const {
std::stringstream ss;
ss << _datatype << IfcEntityInstanceData::toString(upper);
return ss.str();
}
};
class IFC_PARSE_API FileDescription : public HeaderEntity {
public:
explicit FileDescription(IfcFile* = 0);
public:
explicit FileDescription(IfcFile* = 0);
std::vector<std::string> description() const { return *getArgument(0); }
std::string implementation_level() const { return *getArgument(1); }
std::vector<std::string> description() const { return *getArgument(0); }
std::string implementation_level() const { return *getArgument(1); }
void description(const std::vector<std::string>& value) { setValue(0, value); }
void implementation_level(const std::string& value) { setValue(1, value); }
void description(const std::vector<std::string>& value) { setValue(0, value); }
void implementation_level(const std::string& value) { setValue(1, value); }
};
class IFC_PARSE_API FileName : public HeaderEntity {
public:
explicit FileName(IfcFile* = 0);
class IFC_PARSE_API FileName : public HeaderEntity {
public:
explicit FileName(IfcFile* = 0);
std::string name() const { return *getArgument(0); }
std::string time_stamp() const { return *getArgument(1); }
std::vector<std::string> author() const { return *getArgument(2); }
std::vector<std::string> organization() const { return *getArgument(3); }
std::string preprocessor_version() const { return *getArgument(4); }
std::string originating_system() const { return *getArgument(5); }
std::string authorization() const { return *getArgument(6); }
std::string name() const { return *getArgument(0); }
std::string time_stamp() const { return *getArgument(1); }
std::vector<std::string> author() const { return *getArgument(2); }
std::vector<std::string> organization() const { return *getArgument(3); }
std::string preprocessor_version() const { return *getArgument(4); }
std::string originating_system() const { return *getArgument(5); }
std::string authorization() const { return *getArgument(6); }
void name(const std::string& value) { setValue(0, value); }
void time_stamp(const std::string& value) { setValue(1, value); }
void author(const std::vector<std::string>& value) { setValue(2, value); }
void organization(const std::vector<std::string>& value) { setValue(3, value); }
void preprocessor_version(const std::string& value) { setValue(4, value); }
void originating_system(const std::string& value) { setValue(5, value); }
void authorization(const std::string& value) { setValue(6, value); }
void name(const std::string& value) { setValue(0, value); }
void time_stamp(const std::string& value) { setValue(1, value); }
void author(const std::vector<std::string>& value) { setValue(2, value); }
void organization(const std::vector<std::string>& value) { setValue(3, value); }
void preprocessor_version(const std::string& value) { setValue(4, value); }
void originating_system(const std::string& value) { setValue(5, value); }
void authorization(const std::string& value) { setValue(6, value); }
};
class IFC_PARSE_API FileSchema : public HeaderEntity {
public:
explicit FileSchema(IfcFile* = 0);
class IFC_PARSE_API FileSchema : public HeaderEntity {
public:
explicit FileSchema(IfcFile* = 0);
std::vector<std::string> schema_identifiers() const { return *getArgument(0); }
std::vector<std::string> schema_identifiers() const { return *getArgument(0); }
void schema_identifiers(const std::vector<std::string>& value) { setValue(0, value); }
void schema_identifiers(const std::vector<std::string>& value) { setValue(0, value); }
};
class IFC_PARSE_API IfcSpfHeader {
private:
IfcFile* file_;
FileDescription* _file_description;
FileName* _file_name;
FileSchema* _file_schema;
void readParen();
void readSemicolon();
enum Trail {
TRAILING_SEMICOLON,
TRAILING_PAREN,
NONE
};
void readTerminal(const std::string& term, Trail trail);
public:
explicit IfcSpfHeader(IfcParse::IfcFile* file = 0)
: file_(file), _file_description(0), _file_name(0), _file_schema(0)
{
_file_description = new FileDescription(file_);
_file_name = new FileName(file_);
_file_schema = new FileSchema(file_);
}
private:
IfcFile* file_;
FileDescription* _file_description;
FileName* _file_name;
FileSchema* _file_schema;
void readParen();
void readSemicolon();
enum Trail {
TRAILING_SEMICOLON,
TRAILING_PAREN,
NONE
};
void readTerminal(const std::string& term, Trail trail);
~IfcSpfHeader()
{
delete _file_schema;
delete _file_name;
delete _file_description;
}
public:
explicit IfcSpfHeader(IfcParse::IfcFile* file = 0)
: file_(file),
_file_description(0),
_file_name(0),
_file_schema(0) {
_file_description = new FileDescription(file_);
_file_name = new FileName(file_);
_file_schema = new FileSchema(file_);
}
IfcParse::IfcFile* file() { return file_; }
void file(IfcParse::IfcFile * file) { file_ = file; }
~IfcSpfHeader() {
delete _file_schema;
delete _file_name;
delete _file_description;
}
void read();
bool tryRead();
void write(std::ostream& os) const;
IfcParse::IfcFile* file() { return file_; }
void file(IfcParse::IfcFile* file) { file_ = file; }
const FileDescription& file_description() const;
const FileName& file_name() const;
const FileSchema& file_schema() const;
void read();
bool tryRead();
FileDescription& file_description();
FileName& file_name();
FileSchema& file_schema();
void write(std::ostream& os) const;
const FileDescription& file_description() const;
const FileName& file_name() const;
const FileSchema& file_schema() const;
FileDescription& file_description();
FileName& file_name();
FileSchema& file_schema();
};
}
} // namespace IfcParse
#endif
+40 -39
View File
@@ -16,17 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
/*********************************************************************************
* *
* Reads a file and provides functions to access its *
* contents randomly and character by character *
* *
********************************************************************************/
#ifndef IFCSPFSTREAM_H
#define IFCSPFSTREAM_H
#include "ifc_parse_api.h"
#include <fstream>
#include <string>
@@ -34,49 +36,48 @@
#include <boost/iostreams/device/mapped_file.hpp>
#endif
#include "ifc_parse_api.h"
namespace IfcParse {
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
/// The file is interpreted as a sequence of tokens which are lazily
/// interpreted only when requested.
class IFC_PARSE_API IfcSpfStream {
private:
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
/// The file is interpreted as a sequence of tokens which are lazily
/// interpreted only when requested.
class IFC_PARSE_API IfcSpfStream {
private:
#ifdef USE_MMAP
boost::iostreams::mapped_file_source mfs;
boost::iostreams::mapped_file_source mfs;
#endif
FILE* stream;
const char* buffer;
unsigned int ptr;
unsigned int len;
public:
bool valid;
bool eof;
unsigned int size;
FILE* stream;
const char* buffer;
unsigned int ptr;
unsigned int len;
public:
bool valid;
bool eof;
unsigned int size;
#ifdef USE_MMAP
IfcSpfStream(const std::string& fn, bool mmap=false);
IfcSpfStream(const std::string& fn, bool mmap = false);
#else
IfcSpfStream(const std::string& fn);
IfcSpfStream(const std::string& fn);
#endif
IfcSpfStream(std::istream& f, int len);
IfcSpfStream(void* data, int len);
~IfcSpfStream();
/// Returns the character at the cursor
char Peek();
/// Returns the character at specified offset
char Read(unsigned int offset);
/// Increment the file cursor and reads new page if necessary
void Inc();
void Close();
/// Moves the file cursor to an arbitrary offset in the file
void Seek(unsigned int offset);
/// Returns the cursor position
unsigned int Tell();
IfcSpfStream(std::istream& f, int len);
IfcSpfStream(void* data, int len);
~IfcSpfStream();
/// Returns the character at the cursor
char Peek();
/// Returns the character at specified offset
char Read(unsigned int offset);
/// Increment the file cursor and reads new page if necessary
void Inc();
void Close();
/// Moves the file cursor to an arbitrary offset in the file
void Seek(unsigned int offset);
/// Returns the cursor position
unsigned int Tell();
bool is_eof_at(unsigned int);
void increment_at(unsigned int&);
char peek_at(unsigned int);
};
}
bool is_eof_at(unsigned int);
void increment_at(unsigned int&);
char peek_at(unsigned int);
};
} // namespace IfcParse
#endif
+181 -184
View File
@@ -34,7 +34,7 @@
#define NOGDI NOGDI
#endif
#ifndef NOSERVICE
#define NOSERVICE NOSERVICE
#define NOSERVICE NOSERVICE
#endif
#ifndef NOKERNEL
#define NOKERNEL NOKERNEL
@@ -51,75 +51,75 @@
#include <Windows.h>
#endif
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/Argument.h"
#include "../ifcparse/utils.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/aggregate_of_instance.h"
#include "aggregate_of_instance.h"
#include "Argument.h"
#include "IfcBaseClass.h"
#include "IfcException.h"
#include "utils.h"
#include <algorithm>
#include <boost/algorithm/string/replace.hpp>
#include <boost/optional.hpp>
#include <iostream>
#include <algorithm>
void aggregate_of_instance::push(IfcUtil::IfcBaseClass* l) {
if (l) {
ls.push_back(l);
}
if (l) {
ls.push_back(l);
}
}
void aggregate_of_instance::push(const aggregate_of_instance::ptr& l) {
if (l) {
for( it i = l->begin(); i != l->end(); ++i ) {
if ( *i ) ls.push_back(*i);
}
}
if (l) {
for (it i = l->begin(); i != l->end(); ++i) {
if (*i) {
ls.push_back(*i);
}
}
}
}
unsigned int aggregate_of_instance::size() const { return (unsigned int) ls.size(); }
unsigned int aggregate_of_instance::size() const { return (unsigned int)ls.size(); }
void aggregate_of_instance::reserve(unsigned capacity) { ls.reserve((size_t)capacity); }
aggregate_of_instance::it aggregate_of_instance::begin() { return ls.begin(); }
aggregate_of_instance::it aggregate_of_instance::end() { return ls.end(); }
IfcUtil::IfcBaseClass* aggregate_of_instance::operator[] (int i) {
return ls[i];
IfcUtil::IfcBaseClass* aggregate_of_instance::operator[](int i) {
return ls[i];
}
bool aggregate_of_instance::contains(IfcUtil::IfcBaseClass* instance) const {
return std::find(ls.begin(), ls.end(), instance) != ls.end();
return std::find(ls.begin(), ls.end(), instance) != ls.end();
}
void aggregate_of_instance::remove(IfcUtil::IfcBaseClass* instance) {
std::vector<IfcUtil::IfcBaseClass*>::iterator it;
while ((it = std::find(ls.begin(), ls.end(), instance)) != ls.end()) {
ls.erase(it);
}
std::vector<IfcUtil::IfcBaseClass*>::iterator it;
while ((it = std::find(ls.begin(), ls.end(), instance)) != ls.end()) {
ls.erase(it);
}
}
aggregate_of_instance::ptr aggregate_of_instance::filtered(const std::set<const IfcParse::declaration*>& entities) {
aggregate_of_instance::ptr return_value(new aggregate_of_instance);
for (it it = begin(); it != end(); ++it) {
bool contained = false;
for (std::set<const IfcParse::declaration*>::const_iterator jt = entities.begin(); jt != entities.end(); ++jt) {
if ((*it)->declaration().is(**jt)) {
contained = true;
break;
}
}
if (!contained) {
return_value->push(*it);
}
}
return return_value;
aggregate_of_instance::ptr return_value(new aggregate_of_instance);
for (it it = begin(); it != end(); ++it) {
bool contained = false;
for (std::set<const IfcParse::declaration*>::const_iterator jt = entities.begin(); jt != entities.end(); ++jt) {
if ((*it)->declaration().is(**jt)) {
contained = true;
break;
}
}
if (!contained) {
return_value->push(*it);
}
}
return return_value;
}
aggregate_of_instance::ptr aggregate_of_instance::unique() {
std::set<IfcUtil::IfcBaseClass*> encountered;
aggregate_of_instance::ptr return_value(new aggregate_of_instance);
for (it it = begin(); it != end(); ++it) {
if (encountered.find(*it) == encountered.end()) {
return_value->push(*it);
encountered.insert(*it);
}
}
return return_value;
std::set<IfcUtil::IfcBaseClass*> encountered;
aggregate_of_instance::ptr return_value(new aggregate_of_instance);
for (it it = begin(); it != end(); ++it) {
if (encountered.find(*it) == encountered.end()) {
return_value->push(*it);
encountered.insert(*it);
}
}
return return_value;
}
//Note: some of these methods are overloaded in derived classes
@@ -133,70 +133,67 @@ Argument::operator IfcUtil::IfcBaseClass*() const { throw IfcParse::IfcException
Argument::operator std::vector<double>() const { throw IfcParse::IfcException("Argument is not a list of floats"); }
Argument::operator std::vector<int>() const { throw IfcParse::IfcException("Argument is not a list of ints"); }
Argument::operator std::vector<std::string>() const { throw IfcParse::IfcException("Argument is not a list of strings"); }
Argument::operator std::vector<boost::dynamic_bitset<> >() const { throw IfcParse::IfcException("Argument is not a list of binaries"); }
Argument::operator std::vector<boost::dynamic_bitset<>>() const { throw IfcParse::IfcException("Argument is not a list of binaries"); }
Argument::operator aggregate_of_instance::ptr() const { throw IfcParse::IfcException("Argument is not a list of entity instances"); }
Argument::operator std::vector< std::vector<int> >() const { throw IfcParse::IfcException("Argument is not a list of list of ints"); }
Argument::operator std::vector< std::vector<double> >() const { throw IfcParse::IfcException("Argument is not a list of list of floats"); }
Argument::operator std::vector<std::vector<int>>() const { throw IfcParse::IfcException("Argument is not a list of list of ints"); }
Argument::operator std::vector<std::vector<double>>() const { throw IfcParse::IfcException("Argument is not a list of list of floats"); }
Argument::operator aggregate_of_aggregate_of_instance::ptr() const { throw IfcParse::IfcException("Argument is not a list of list of entity instances"); }
static const char* const argument_type_string[] = {
"NULL",
"DERIVED",
"INT",
"BOOL",
"LOGICAL",
"DOUBLE",
"STRING",
"BINARY",
"ENUMERATION",
"ENTITY INSTANCE",
"NULL",
"DERIVED",
"INT",
"BOOL",
"LOGICAL",
"DOUBLE",
"STRING",
"BINARY",
"ENUMERATION",
"ENTITY INSTANCE",
"EMPTY AGGREGATE",
"AGGREGATE OF INT",
"AGGREGATE OF DOUBLE",
"AGGREGATE OF STRING",
"AGGREGATE OF BINARY",
"AGGREGATE OF ENTITY INSTANCE",
"EMPTY AGGREGATE",
"AGGREGATE OF INT",
"AGGREGATE OF DOUBLE",
"AGGREGATE OF STRING",
"AGGREGATE OF BINARY",
"AGGREGATE OF ENTITY INSTANCE",
"AGGREGATE OF EMPTY AGGREGATE",
"AGGREGATE OF AGGREGATE OF INT",
"AGGREGATE OF AGGREGATE OF DOUBLE",
"AGGREGATE OF AGGREGATE OF ENTITY INSTANCE",
"AGGREGATE OF EMPTY AGGREGATE",
"AGGREGATE OF AGGREGATE OF INT",
"AGGREGATE OF AGGREGATE OF DOUBLE",
"AGGREGATE OF AGGREGATE OF ENTITY INSTANCE",
"UNKNOWN"
};
"UNKNOWN"};
const char* IfcUtil::ArgumentTypeToString(ArgumentType argument_type) {
return argument_type_string[static_cast<int>(argument_type)];
return argument_type_string[static_cast<int>(argument_type)];
}
bool IfcUtil::valid_binary_string(const std::string& s) {
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
if (*it != '0' && *it != '1') return false;
}
return true;
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
if (*it != '0' && *it != '1') {
return false;
}
}
return true;
}
void IfcUtil::sanitate_material_name(std::string &str)
{
void IfcUtil::sanitate_material_name(std::string& str) {
// Spaces in material names have been observed to cause problems with obj and dae importers.
// Handle other potential problematic characters here too if observing problems.
boost::replace_all(str, " ", "_");
}
void IfcUtil::escape_xml(std::string &str)
{
boost::replace_all(str, "&", "&amp;");
void IfcUtil::escape_xml(std::string& str) {
boost::replace_all(str, "&", "&amp;");
boost::replace_all(str, "\"", "&quot;");
boost::replace_all(str, "'", "&apos;");
boost::replace_all(str, "<", "&lt;");
boost::replace_all(str, ">", "&gt;");
}
void IfcUtil::unescape_xml(std::string &str)
{
boost::replace_all(str, "&amp;", "&");
void IfcUtil::unescape_xml(std::string& str) {
boost::replace_all(str, "&amp;", "&");
boost::replace_all(str, "&quot;", "\"");
boost::replace_all(str, "&apos;", "'");
boost::replace_all(str, "&lt;", "<");
@@ -204,138 +201,138 @@ void IfcUtil::unescape_xml(std::string &str)
}
Argument* IfcUtil::IfcBaseEntity::get(const std::string& name) const {
return data().getArgument(declaration().attribute_index(name));
return data().getArgument(declaration().attribute_index(name));
}
aggregate_of_instance::ptr IfcUtil::IfcBaseEntity::get_inverse(const std::string& name) const {
const std::vector<const IfcParse::inverse_attribute*> attrs = declaration().as_entity()->all_inverse_attributes();
std::vector<const IfcParse::inverse_attribute*>::const_iterator it = attrs.begin();
for (; it != attrs.end(); ++it) {
if ((*it)->name() == name) {
return data().getInverse(
(*it)->entity_reference(),
(int) (*it)->entity_reference()->attribute_index((*it)->attribute_reference()));
}
}
throw IfcParse::IfcException(name + " not found on " + declaration().name());
const std::vector<const IfcParse::inverse_attribute*> attrs = declaration().as_entity()->all_inverse_attributes();
std::vector<const IfcParse::inverse_attribute*>::const_iterator it = attrs.begin();
for (; it != attrs.end(); ++it) {
if ((*it)->name() == name) {
return data().getInverse(
(*it)->entity_reference(),
(int)(*it)->entity_reference()->attribute_index((*it)->attribute_reference()));
}
}
throw IfcParse::IfcException(name + " not found on " + declaration().name());
}
void IfcUtil::IfcBaseClass::data(IfcEntityInstanceData* d) {
delete data_;
data_ = d;
delete data_;
data_ = d;
}
IfcUtil::ArgumentType IfcUtil::make_aggregate(IfcUtil::ArgumentType elem_type) {
if (elem_type == IfcUtil::Argument_INT) {
return IfcUtil::Argument_AGGREGATE_OF_INT;
} else if (elem_type == IfcUtil::Argument_DOUBLE) {
return IfcUtil::Argument_AGGREGATE_OF_DOUBLE;
} else if (elem_type == IfcUtil::Argument_STRING) {
return IfcUtil::Argument_AGGREGATE_OF_STRING;
} else if (elem_type == IfcUtil::Argument_BINARY) {
return IfcUtil::Argument_AGGREGATE_OF_BINARY;
} else if (elem_type == IfcUtil::Argument_ENTITY_INSTANCE) {
return IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (elem_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
return IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT;
} else if (elem_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
return IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE;
} else if (elem_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
return IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (elem_type == IfcUtil::Argument_EMPTY_AGGREGATE) {
return IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE;
} else {
return IfcUtil::Argument_UNKNOWN;
}
if (elem_type == IfcUtil::Argument_INT) {
return IfcUtil::Argument_AGGREGATE_OF_INT;
} else if (elem_type == IfcUtil::Argument_DOUBLE) {
return IfcUtil::Argument_AGGREGATE_OF_DOUBLE;
} else if (elem_type == IfcUtil::Argument_STRING) {
return IfcUtil::Argument_AGGREGATE_OF_STRING;
} else if (elem_type == IfcUtil::Argument_BINARY) {
return IfcUtil::Argument_AGGREGATE_OF_BINARY;
} else if (elem_type == IfcUtil::Argument_ENTITY_INSTANCE) {
return IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (elem_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
return IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT;
} else if (elem_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
return IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE;
} else if (elem_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
return IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (elem_type == IfcUtil::Argument_EMPTY_AGGREGATE) {
return IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE;
} else {
return IfcUtil::Argument_UNKNOWN;
}
}
IfcUtil::ArgumentType IfcUtil::from_parameter_type(const IfcParse::parameter_type* pt) {
// TODO: How to detect derived types here without a reference to the refering entity?
// TODO: How to detect derived types here without a reference to the refering entity?
const IfcParse::aggregation_type* at = pt->as_aggregation_type();
const IfcParse::named_type* nt = pt->as_named_type();
const IfcParse::simple_type* st = pt->as_simple_type();
if (at) {
return make_aggregate(from_parameter_type(at->type_of_element()));
} else if (nt) {
if (nt->declared_type()->as_entity()) {
return IfcUtil::Argument_ENTITY_INSTANCE;
} else if (nt->declared_type()->as_enumeration_type()) {
return IfcUtil::Argument_ENUMERATION;
} else if (nt->declared_type()->as_select_type()) {
return IfcUtil::Argument_ENTITY_INSTANCE;
} else if (nt->declared_type()->as_type_declaration()) {
return from_parameter_type(nt->declared_type()->as_type_declaration()->declared_type());
}
} else if (st) {
switch (st->declared_type()) {
case IfcParse::simple_type::binary_type:
return IfcUtil::Argument_BINARY;
case IfcParse::simple_type::boolean_type:
return IfcUtil::Argument_BOOL;
case IfcParse::simple_type::integer_type:
return IfcUtil::Argument_INT;
case IfcParse::simple_type::logical_type:
return IfcUtil::Argument_LOGICAL;
case IfcParse::simple_type::number_type:
return IfcUtil::Argument_DOUBLE;
case IfcParse::simple_type::real_type:
return IfcUtil::Argument_DOUBLE;
case IfcParse::simple_type::string_type:
return IfcUtil::Argument_STRING;
case IfcParse::simple_type::datatype_COUNT:
throw IfcParse::IfcException("Invalid simple type encountered");
}
}
const IfcParse::aggregation_type* at = pt->as_aggregation_type();
const IfcParse::named_type* nt = pt->as_named_type();
const IfcParse::simple_type* st = pt->as_simple_type();
return IfcUtil::Argument_UNKNOWN;
if (at) {
return make_aggregate(from_parameter_type(at->type_of_element()));
} else if (nt) {
if (nt->declared_type()->as_entity()) {
return IfcUtil::Argument_ENTITY_INSTANCE;
} else if (nt->declared_type()->as_enumeration_type()) {
return IfcUtil::Argument_ENUMERATION;
} else if (nt->declared_type()->as_select_type()) {
return IfcUtil::Argument_ENTITY_INSTANCE;
} else if (nt->declared_type()->as_type_declaration()) {
return from_parameter_type(nt->declared_type()->as_type_declaration()->declared_type());
}
} else if (st) {
switch (st->declared_type()) {
case IfcParse::simple_type::binary_type:
return IfcUtil::Argument_BINARY;
case IfcParse::simple_type::boolean_type:
return IfcUtil::Argument_BOOL;
case IfcParse::simple_type::integer_type:
return IfcUtil::Argument_INT;
case IfcParse::simple_type::logical_type:
return IfcUtil::Argument_LOGICAL;
case IfcParse::simple_type::number_type:
return IfcUtil::Argument_DOUBLE;
case IfcParse::simple_type::real_type:
return IfcUtil::Argument_DOUBLE;
case IfcParse::simple_type::string_type:
return IfcUtil::Argument_STRING;
case IfcParse::simple_type::datatype_COUNT:
throw IfcParse::IfcException("Invalid simple type encountered");
}
}
return IfcUtil::Argument_UNKNOWN;
}
#ifdef _MSC_VER
std::string IfcUtil::path::to_utf8(const std::wstring& str) {
int buffer_size = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, 0, 0, 0, 0);
char* buffer = new char[buffer_size];
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, buffer, buffer_size, 0, 0);
std::string str_utf8(buffer);
delete[] buffer;
return str_utf8;
int buffer_size = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, 0, 0, 0, 0);
char* buffer = new char[buffer_size];
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, buffer, buffer_size, 0, 0);
std::string str_utf8(buffer);
delete[] buffer;
return str_utf8;
}
std::wstring IfcUtil::path::from_utf8(const std::string& str) {
int buffer_size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);
wchar_t* buffer = new wchar_t[buffer_size];
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buffer, buffer_size);
std::wstring str_wide(buffer);
delete[] buffer;
return str_wide;
int buffer_size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);
wchar_t* buffer = new wchar_t[buffer_size];
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buffer, buffer_size);
std::wstring str_wide(buffer);
delete[] buffer;
return str_wide;
}
IFC_PARSE_API bool IfcUtil::path::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);
delete_file(new_filename);
const bool success = !!MoveFileW(old_filename_w.c_str(), new_filename_w.c_str());
return success;
std::wstring old_filename_w = from_utf8(old_filename);
std::wstring new_filename_w = from_utf8(new_filename);
delete_file(new_filename);
const bool success = !!MoveFileW(old_filename_w.c_str(), new_filename_w.c_str());
return success;
}
IFC_PARSE_API bool IfcUtil::path::delete_file(const std::string& filename) {
std::wstring filename_w = from_utf8(filename);
const bool success = !!DeleteFileW(filename_w.c_str());
return success;
std::wstring filename_w = from_utf8(filename);
const bool success = !!DeleteFileW(filename_w.c_str());
return success;
}
#else
IFC_PARSE_API bool IfcUtil::path::rename_file(const std::string& old_filename, const std::string& new_filename) {
// Whether or not rename() replaces an existing file is implementation-specific,
// so remove() possible existing file always.
delete_file(new_filename);
return std::rename(old_filename.c_str(), new_filename.c_str()) == 0;
// Whether or not rename() replaces an existing file is implementation-specific,
// so remove() possible existing file always.
delete_file(new_filename);
return std::rename(old_filename.c_str(), new_filename.c_str()) == 0;
}
IFC_PARSE_API bool IfcUtil::path::delete_file(const std::string& filename) {
return std::remove(filename.c_str());
return std::remove(filename.c_str());
}
#endif
+244 -222
View File
@@ -17,282 +17,304 @@
* *
********************************************************************************/
#include <iomanip>
#include <locale>
#include <limits>
#include "IfcWrite.h"
#include "IfcCharacterDecoder.h"
#include "IfcFile.h"
#include "IfcParse.h"
#include <boost/algorithm/string.hpp>
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcCharacterDecoder.h"
#include "../ifcparse/IfcFile.h"
#include <iomanip>
#include <limits>
#include <locale>
using namespace IfcWrite;
class SizeVisitor : public boost::static_visitor<int> {
public:
int operator()(const boost::blank& /*i*/) const { return -1; }
int operator()(const IfcWriteArgument::Derived& /*i*/) const { return -1; }
int operator()(const int& /*i*/) const { return -1; }
int operator()(const bool& /*i*/) const { return -1; }
int operator()(const boost::logic::tribool& /*i*/) const { return -1; }
int operator()(const double& /*i*/) const { return -1; }
int operator()(const std::string& /*i*/) const { return -1; }
int operator()(const boost::dynamic_bitset<>& /*i*/) const { return -1; }
int operator()(const IfcWriteArgument::empty_aggregate_t&) const { return 0; }
int operator()(const IfcWriteArgument::empty_aggregate_of_aggregate_t&) const { return 0; }
int operator()(const std::vector<int>& i) const { return (int)i.size(); }
int operator()(const std::vector<double>& i) const { return (int)i.size(); }
int operator()(const std::vector< std::vector<int> >& i) const { return (int)i.size(); }
int operator()(const std::vector< std::vector<double> >& i) const { return (int)i.size(); }
int operator()(const std::vector<std::string>& i) const { return (int)i.size(); }
int operator()(const std::vector< boost::dynamic_bitset<> >& i) const { return (int)i.size(); }
int operator()(const IfcWriteArgument::EnumerationReference& /*i*/) const { return -1; }
int operator()(const IfcUtil::IfcBaseClass* const& /*i*/) const { return -1; }
int operator()(const aggregate_of_instance::ptr& i) const { return i->size(); }
int operator()(const aggregate_of_aggregate_of_instance::ptr& i) const { return i->size(); }
public:
int operator()(const boost::blank& /*i*/) const { return -1; }
int operator()(const IfcWriteArgument::Derived& /*i*/) const { return -1; }
int operator()(const int& /*i*/) const { return -1; }
int operator()(const bool& /*i*/) const { return -1; }
int operator()(const boost::logic::tribool& /*i*/) const { return -1; }
int operator()(const double& /*i*/) const { return -1; }
int operator()(const std::string& /*i*/) const { return -1; }
int operator()(const boost::dynamic_bitset<>& /*i*/) const { return -1; }
int operator()(const IfcWriteArgument::empty_aggregate_t&) const { return 0; }
int operator()(const IfcWriteArgument::empty_aggregate_of_aggregate_t&) const { return 0; }
int operator()(const std::vector<int>& i) const { return (int)i.size(); }
int operator()(const std::vector<double>& i) const { return (int)i.size(); }
int operator()(const std::vector<std::vector<int>>& i) const { return (int)i.size(); }
int operator()(const std::vector<std::vector<double>>& i) const { return (int)i.size(); }
int operator()(const std::vector<std::string>& i) const { return (int)i.size(); }
int operator()(const std::vector<boost::dynamic_bitset<>>& i) const { return (int)i.size(); }
int operator()(const IfcWriteArgument::EnumerationReference& /*i*/) const { return -1; }
int operator()(const IfcUtil::IfcBaseClass* const& /*i*/) const { return -1; }
int operator()(const aggregate_of_instance::ptr& i) const { return i->size(); }
int operator()(const aggregate_of_aggregate_of_instance::ptr& i) const { return i->size(); }
};
class StringBuilderVisitor : public boost::static_visitor<void> {
private:
StringBuilderVisitor(const StringBuilderVisitor&); //N/A
StringBuilderVisitor& operator =(const StringBuilderVisitor&); //N/A
private:
StringBuilderVisitor(const StringBuilderVisitor&); //N/A
StringBuilderVisitor& operator=(const StringBuilderVisitor&); //N/A
std::ostringstream& data;
template <typename T> void serialize(const std::vector<T>& i) {
data << "(";
for (typename std::vector<T>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) data << ",";
data << *it;
}
data << ")";
}
// The REAL token definition from the IFC SPF standard does not necessarily match
// the output of the C++ ostream formatting operation.
// REAL = [ SIGN ] DIGIT { DIGIT } "." { DIGIT } [ "E" [ SIGN ] DIGIT { DIGIT } ] .
std::string format_double(const double& d) {
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss << std::setprecision(std::numeric_limits<double>::digits10) << d;
const std::string str = oss.str();
oss.str("");
std::string::size_type e = str.find('e');
if (e == std::string::npos) {
e = str.find('E');
}
const std::string mantissa = str.substr(0,e);
oss << mantissa;
if (mantissa.find('.') == std::string::npos) {
oss << ".";
}
if (e != std::string::npos) {
oss << "E";
oss << str.substr(e+1);
}
return oss.str();
}
std::ostringstream& data;
template <typename T>
void serialize(const std::vector<T>& i) {
data << "(";
for (typename std::vector<T>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) {
data << ",";
}
data << *it;
}
data << ")";
}
// The REAL token definition from the IFC SPF standard does not necessarily match
// the output of the C++ ostream formatting operation.
// REAL = [ SIGN ] DIGIT { DIGIT } "." { DIGIT } [ "E" [ SIGN ] DIGIT { DIGIT } ] .
std::string format_double(const double& d) {
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss << std::setprecision(std::numeric_limits<double>::digits10) << d;
const std::string str = oss.str();
oss.str("");
std::string::size_type e = str.find('e');
if (e == std::string::npos) {
e = str.find('E');
}
const std::string mantissa = str.substr(0, e);
oss << mantissa;
if (mantissa.find('.') == std::string::npos) {
oss << ".";
}
if (e != std::string::npos) {
oss << "E";
oss << str.substr(e + 1);
}
return oss.str();
}
std::string format_binary(const boost::dynamic_bitset<>& b) {
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss.put('"');
oss << std::hex << std::setw(1);
unsigned c = (unsigned)b.size();
unsigned n = (4 - (c % 4)) & 3;
oss << n;
for (unsigned i = 0; i < c + n;) {
unsigned accum = 0;
for (int j = 0; j < 4; ++j, ++i) {
unsigned bit = i < n ? 0 : b.test(c - i + n - 1) ? 1 : 0;
accum |= bit << (3-j);
}
oss << accum;
}
oss.put('"');
return oss.str();
}
std::string format_binary(const boost::dynamic_bitset<>& b) {
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss.put('"');
oss << std::hex << std::setw(1);
unsigned c = (unsigned)b.size();
unsigned n = (4 - (c % 4)) & 3;
oss << n;
for (unsigned i = 0; i < c + n;) {
unsigned accum = 0;
for (int j = 0; j < 4; ++j, ++i) {
unsigned bit = i < n ? 0 : b.test(c - i + n - 1) ? 1
: 0;
accum |= bit << (3 - j);
}
oss << accum;
}
oss.put('"');
return oss.str();
}
bool upper;
public:
StringBuilderVisitor(std::ostringstream& stream, bool upper = false)
: data(stream), upper(upper) {}
void operator()(const boost::blank& /*i*/) { data << "$"; }
void operator()(const IfcWriteArgument::Derived& /*i*/) { data << "*"; }
void operator()(const int& i) { data << i; }
void operator()(const bool& i) { data << (i ? ".T." : ".F."); }
void operator()(const boost::logic::tribool& i) { data << (i ? ".T." : (boost::logic::indeterminate(i) ? ".U." : ".F.")); }
void operator()(const double& i) { data << format_double(i); }
void operator()(const boost::dynamic_bitset<>& i) { data << format_binary(i); }
void operator()(const std::string& i) {
std::string s = i;
if (upper) {
data << static_cast<std::string>(IfcCharacterEncoder(s));
} else {
data << '\'' << s << '\'';
}
}
void operator()(const std::vector<int>& i);
void operator()(const std::vector<double>& i);
void operator()(const std::vector<std::string>& i);
void operator()(const std::vector< boost::dynamic_bitset<> >& i);
void operator()(const IfcWriteArgument::EnumerationReference& i) {
data << "." << i.enumeration_value << ".";
}
void operator()(const IfcUtil::IfcBaseClass* const& i) {
const IfcEntityInstanceData& e = i->data();
if (!e.type()->as_entity()) {
data << e.toString(upper);
} else {
data << "#" << e.id();
}
}
void operator()(const aggregate_of_instance::ptr& i) {
data << "(";
for (aggregate_of_instance::it it = i->begin(); it != i->end(); ++it) {
if (it != i->begin()) data << ",";
(*this)(*it);
}
data << ")";
}
void operator()(const std::vector< std::vector<int> >& i);
void operator()(const std::vector< std::vector<double> >& i);
void operator()(const aggregate_of_aggregate_of_instance::ptr& i) {
data << "(";
for (aggregate_of_aggregate_of_instance::outer_it outer_it = i->begin(); outer_it != i->end(); ++outer_it) {
if (outer_it != i->begin()) data << ",";
data << "(";
for (aggregate_of_aggregate_of_instance::inner_it inner_it = outer_it->begin(); inner_it != outer_it->end(); ++inner_it) {
if (inner_it != outer_it->begin()) data << ",";
(*this)(*inner_it);
}
data << ")";
}
data << ")";
}
void operator()(const IfcWriteArgument::empty_aggregate_t&) const { data << "()"; }
void operator()(const IfcWriteArgument::empty_aggregate_of_aggregate_t&) const { data << "()"; }
operator std::string() { return data.str(); }
bool upper;
public:
StringBuilderVisitor(std::ostringstream& stream, bool upper = false)
: data(stream),
upper(upper) {}
void operator()(const boost::blank& /*i*/) { data << "$"; }
void operator()(const IfcWriteArgument::Derived& /*i*/) { data << "*"; }
void operator()(const int& i) { data << i; }
void operator()(const bool& i) { data << (i ? ".T." : ".F."); }
void operator()(const boost::logic::tribool& i) { data << (i ? ".T." : (boost::logic::indeterminate(i) ? ".U." : ".F.")); }
void operator()(const double& i) { data << format_double(i); }
void operator()(const boost::dynamic_bitset<>& i) { data << format_binary(i); }
void operator()(const std::string& i) {
std::string s = i;
if (upper) {
data << static_cast<std::string>(IfcCharacterEncoder(s));
} else {
data << '\'' << s << '\'';
}
}
void operator()(const std::vector<int>& i);
void operator()(const std::vector<double>& i);
void operator()(const std::vector<std::string>& i);
void operator()(const std::vector<boost::dynamic_bitset<>>& i);
void operator()(const IfcWriteArgument::EnumerationReference& i) {
data << "." << i.enumeration_value << ".";
}
void operator()(const IfcUtil::IfcBaseClass* const& i) {
const IfcEntityInstanceData& e = i->data();
if (!e.type()->as_entity()) {
data << e.toString(upper);
} else {
data << "#" << e.id();
}
}
void operator()(const aggregate_of_instance::ptr& i) {
data << "(";
for (aggregate_of_instance::it it = i->begin(); it != i->end(); ++it) {
if (it != i->begin()) {
data << ",";
}
(*this)(*it);
}
data << ")";
}
void operator()(const std::vector<std::vector<int>>& i);
void operator()(const std::vector<std::vector<double>>& i);
void operator()(const aggregate_of_aggregate_of_instance::ptr& i) {
data << "(";
for (aggregate_of_aggregate_of_instance::outer_it outer_it = i->begin(); outer_it != i->end(); ++outer_it) {
if (outer_it != i->begin()) {
data << ",";
}
data << "(";
for (aggregate_of_aggregate_of_instance::inner_it inner_it = outer_it->begin(); inner_it != outer_it->end(); ++inner_it) {
if (inner_it != outer_it->begin()) {
data << ",";
}
(*this)(*inner_it);
}
data << ")";
}
data << ")";
}
void operator()(const IfcWriteArgument::empty_aggregate_t&) const { data << "()"; }
void operator()(const IfcWriteArgument::empty_aggregate_of_aggregate_t&) const { data << "()"; }
operator std::string() { return data.str(); }
};
template <>
void StringBuilderVisitor::serialize(const std::vector<std::string>& i) {
data << "(";
for (std::vector<std::string>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) data << ",";
std::string s = IfcCharacterEncoder(*it);
data << s;
}
data << ")";
data << "(";
for (std::vector<std::string>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) {
data << ",";
}
std::string s = IfcCharacterEncoder(*it);
data << s;
}
data << ")";
}
template <>
void StringBuilderVisitor::serialize(const std::vector<double>& i) {
data << "(";
for (std::vector<double>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) data << ",";
data << format_double(*it);
}
data << ")";
data << "(";
for (std::vector<double>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) {
data << ",";
}
data << format_double(*it);
}
data << ")";
}
template <>
void StringBuilderVisitor::serialize(const std::vector< boost::dynamic_bitset<> >& i) {
data << "(";
for (std::vector< boost::dynamic_bitset<> >::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) data << ",";
data << format_binary(*it);
}
data << ")";
void StringBuilderVisitor::serialize(const std::vector<boost::dynamic_bitset<>>& i) {
data << "(";
for (std::vector<boost::dynamic_bitset<>>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) {
data << ",";
}
data << format_binary(*it);
}
data << ")";
}
void StringBuilderVisitor::operator()(const std::vector<int>& i) { serialize(i); }
void StringBuilderVisitor::operator()(const std::vector<double>& i) { serialize(i); }
void StringBuilderVisitor::operator()(const std::vector<std::string>& i) { serialize(i); }
void StringBuilderVisitor::operator()(const std::vector< boost::dynamic_bitset<> >& i) { serialize(i); }
void StringBuilderVisitor::operator()(const std::vector< std::vector<int> >& i) {
data << "(";
for (std::vector< std::vector<int> >::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) data << ",";
serialize(*it);
}
data << ")";
void StringBuilderVisitor::operator()(const std::vector<boost::dynamic_bitset<>>& i) { serialize(i); }
void StringBuilderVisitor::operator()(const std::vector<std::vector<int>>& i) {
data << "(";
for (std::vector<std::vector<int>>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) {
data << ",";
}
serialize(*it);
}
data << ")";
}
void StringBuilderVisitor::operator()(const std::vector< std::vector<double> >& i) {
data << "(";
for (std::vector< std::vector<double> >::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) data << ",";
serialize(*it);
}
data << ")";
void StringBuilderVisitor::operator()(const std::vector<std::vector<double>>& i) {
data << "(";
for (std::vector<std::vector<double>>::const_iterator it = i.begin(); it != i.end(); ++it) {
if (it != i.begin()) {
data << ",";
}
serialize(*it);
}
data << ")";
}
IfcWriteArgument::operator int() const { return as<int>(); }
IfcWriteArgument::operator bool() const { return as<bool>(); }
IfcWriteArgument::operator boost::logic::tribool() const { return as<boost::logic::tribool>(); }
IfcWriteArgument::operator double() const { return as<double>(); }
IfcWriteArgument::operator std::string() const {
if (type() == IfcUtil::Argument_ENUMERATION) {
return as<EnumerationReference>().enumeration_value;
}
return as<std::string>();
IfcWriteArgument::operator std::string() const {
if (type() == IfcUtil::Argument_ENUMERATION) {
return as<EnumerationReference>().enumeration_value;
}
return as<std::string>();
}
IfcWriteArgument::operator IfcUtil::IfcBaseClass*() const { return as<IfcUtil::IfcBaseClass*>(); }
IfcWriteArgument::operator boost::dynamic_bitset<>() const { return as< boost::dynamic_bitset<> >(); }
IfcWriteArgument::operator std::vector<double>() const { return as<std::vector<double> >(); }
IfcWriteArgument::operator std::vector<int>() const { return as<std::vector<int> >(); }
IfcWriteArgument::operator std::vector<std::string>() const { return as<std::vector<std::string > >(); }
IfcWriteArgument::operator std::vector< boost::dynamic_bitset<> >() const { return as< std::vector< boost::dynamic_bitset<> > >(); }
IfcWriteArgument::operator boost::dynamic_bitset<>() const { return as<boost::dynamic_bitset<>>(); }
IfcWriteArgument::operator std::vector<double>() const { return as<std::vector<double>>(); }
IfcWriteArgument::operator std::vector<int>() const { return as<std::vector<int>>(); }
IfcWriteArgument::operator std::vector<std::string>() const { return as<std::vector<std::string>>(); }
IfcWriteArgument::operator std::vector<boost::dynamic_bitset<>>() const { return as<std::vector<boost::dynamic_bitset<>>>(); }
IfcWriteArgument::operator aggregate_of_instance::ptr() const { return as<aggregate_of_instance::ptr>(); }
IfcWriteArgument::operator std::vector< std::vector<int> >() const { return as<std::vector< std::vector<int> > >(); }
IfcWriteArgument::operator std::vector< std::vector<double> >() const { return as<std::vector< std::vector<double> > >(); }
IfcWriteArgument::operator std::vector<std::vector<int>>() const { return as<std::vector<std::vector<int>>>(); }
IfcWriteArgument::operator std::vector<std::vector<double>>() const { return as<std::vector<std::vector<double>>>(); }
IfcWriteArgument::operator aggregate_of_aggregate_of_instance::ptr() const { return as<aggregate_of_aggregate_of_instance::ptr>(); }
bool IfcWriteArgument::isNull() const { return type() == IfcUtil::Argument_NULL; }
Argument* IfcWriteArgument::operator [] (unsigned int /*i*/) const { throw IfcParse::IfcException("Invalid cast"); }
Argument* IfcWriteArgument::operator[](unsigned int /*i*/) const { throw IfcParse::IfcException("Invalid cast"); }
std::string IfcWriteArgument::toString(bool upper) const {
std::ostringstream str;
str.imbue(std::locale::classic());
StringBuilderVisitor v(str, upper);
container.apply_visitor(v);
return v;
std::ostringstream str;
str.imbue(std::locale::classic());
StringBuilderVisitor v(str, upper);
container.apply_visitor(v);
return v;
}
unsigned int IfcWriteArgument::size() const {
SizeVisitor v;
const int size = container.apply_visitor(v);
if (size == -1) {
throw IfcParse::IfcException("Invalid cast");
} else {
return size;
}
SizeVisitor v;
const int size = container.apply_visitor(v);
if (size == -1) {
throw IfcParse::IfcException("Invalid cast");
} else {
return size;
}
}
IfcUtil::ArgumentType IfcWriteArgument::type() const {
return static_cast<IfcUtil::ArgumentType>(container.which());
return static_cast<IfcUtil::ArgumentType>(container.which());
}
// Overload to detect null values
void IfcWriteArgument::set(const aggregate_of_instance::ptr& v) {
if (v) {
container = v;
} else {
container = boost::blank();
}
if (v) {
container = v;
} else {
container = boost::blank();
}
}
// Overload to detect null values
void IfcWriteArgument::set(const aggregate_of_aggregate_of_instance::ptr& v) {
if (v) {
container = v;
} else {
container = boost::blank();
}
if (v) {
container = v;
} else {
container = boost::blank();
}
}
// Overload to detect null values
void IfcWriteArgument::set(IfcUtil::IfcBaseInterface*const& v) {
if (v) {
container = v->as<IfcUtil::IfcBaseClass>();
} else {
container = boost::blank();
}
}
void IfcWriteArgument::set(IfcUtil::IfcBaseInterface* const& v) {
if (v) {
container = v->as<IfcUtil::IfcBaseClass>();
} else {
container = boost::blank();
}
}
+122 -123
View File
@@ -28,148 +28,147 @@
#ifndef IFCWRITE_H
#define IFCWRITE_H
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <boost/dynamic_bitset.hpp>
// #include <boost/logic/tribool.hpp>
#include "ifc_parse_api.h"
#include "IfcBaseClass.h"
#include "IfcParse.h"
#include <boost/utility/enable_if.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/optional.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include "ifc_parse_api.h"
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/IfcParse.h"
#include <boost/utility/enable_if.hpp>
#include <boost/variant.hpp>
// #include <boost/logic/tribool.hpp>
namespace IfcWrite {
/// This class is a writable container for attributes. A fundamental
/// difference with the attribute types counterparts defined in the
/// IfcParse namespace is that this class has a Boost.Variant member
/// for storing its value, whereas the IfcParse classes only contain
/// lazy references to byte offsets in the IFC-SPF file.
class IFC_PARSE_API IfcWriteArgument : public Argument {
public:
class EnumerationReference {
public:
int data;
const char* enumeration_value;
EnumerationReference(int data, const char* enumeration_value)
: data(data), enumeration_value(enumeration_value) {}
};
class Derived {};
class empty_aggregate_t {};
class empty_aggregate_of_aggregate_t {};
private:
boost::variant<
// A null argument, it will always serialize to $
boost::blank,
// A derived argument, it will always serialize to *
Derived,
// An integer argument, e.g. 123
/// This class is a writable container for attributes. A fundamental
/// difference with the attribute types counterparts defined in the
/// IfcParse namespace is that this class has a Boost.Variant member
/// for storing its value, whereas the IfcParse classes only contain
/// lazy references to byte offsets in the IFC-SPF file.
class IFC_PARSE_API IfcWriteArgument : public Argument {
public:
class EnumerationReference {
public:
int data;
const char* enumeration_value;
EnumerationReference(int data, const char* enumeration_value)
: data(data),
enumeration_value(enumeration_value) {}
};
class Derived {};
class empty_aggregate_t {};
class empty_aggregate_of_aggregate_t {};
// SCALARS:
int,
// A boolean argument, it will serialize to either .T. or .F.
bool,
// A logical argument, it will serialize to either .T. or .F. or .U.
boost::logic::tribool,
// A floating point argument, e.g. 12.3
double,
// A character string argument, e.g. 'IfcOpenShell'
std::string,
// A binary argument, e.g. "092A" -> 100100101010
boost::dynamic_bitset<>,
// An enumeration argument, e.g. .USERDEFINED.
// To initialize the argument a string representation
// has to be explicitly passed of the enumeration value
// which is stored internally as an integer. The argument
// itself does not keep track of what schema enumeration
// type is represented.
EnumerationReference,
// An entity instance argument. It will either serialize to
// e.g. #123 or datatype identifier for simple types, e.g.
// IFCREAL(12.3)
IfcUtil::IfcBaseClass*,
private:
boost::variant<
// A null argument, it will always serialize to $
boost::blank,
// A derived argument, it will always serialize to *
Derived,
// An integer argument, e.g. 123
// AGGREGATES:
empty_aggregate_t,
// An aggregate of integers, e.g. (1,2,3)
std::vector<int>,
// An aggregate of floats, e.g. (12.3,4.)
std::vector<double>,
// An aggregate of strings, e.g. ('Ifc','Open','Shell')
std::vector<std::string>,
// An aggregate of binaries, e.g. ("23B", "092A") -> (111011, 100100101010)
std::vector<boost::dynamic_bitset<> >,
// An aggregate of entity instances. It will either serialize to
// e.g. (#1,#2,#3) or datatype identifier for simple types,
// e.g. (IFCREAL(1.2),IFCINTEGER(3.))
aggregate_of_instance::ptr,
// SCALARS:
int,
// A boolean argument, it will serialize to either .T. or .F.
bool,
// A logical argument, it will serialize to either .T. or .F. or .U.
boost::logic::tribool,
// A floating point argument, e.g. 12.3
double,
// A character string argument, e.g. 'IfcOpenShell'
std::string,
// A binary argument, e.g. "092A" -> 100100101010
boost::dynamic_bitset<>,
// An enumeration argument, e.g. .USERDEFINED.
// To initialize the argument a string representation
// has to be explicitly passed of the enumeration value
// which is stored internally as an integer. The argument
// itself does not keep track of what schema enumeration
// type is represented.
EnumerationReference,
// An entity instance argument. It will either serialize to
// e.g. #123 or datatype identifier for simple types, e.g.
// IFCREAL(12.3)
IfcUtil::IfcBaseClass*,
// AGGREGATES OF AGGREGATES:
empty_aggregate_of_aggregate_t,
// An aggregate of an aggregate of ints. E.g. ((1, 2), (3))
std::vector< std::vector<int> >,
// An aggregate of an aggregate of floats. E.g. ((1., 2.3), (4.))
std::vector< std::vector<double> >,
// An aggregate of an aggregate of entities. E.g. ((#1, #2), (#3))
aggregate_of_aggregate_of_instance::ptr
> container;
public:
// AGGREGATES:
empty_aggregate_t,
// An aggregate of integers, e.g. (1,2,3)
std::vector<int>,
// An aggregate of floats, e.g. (12.3,4.)
std::vector<double>,
// An aggregate of strings, e.g. ('Ifc','Open','Shell')
std::vector<std::string>,
// An aggregate of binaries, e.g. ("23B", "092A") -> (111011, 100100101010)
std::vector<boost::dynamic_bitset<>>,
// An aggregate of entity instances. It will either serialize to
// e.g. (#1,#2,#3) or datatype identifier for simple types,
// e.g. (IFCREAL(1.2),IFCINTEGER(3.))
aggregate_of_instance::ptr,
template <typename T>
const T& as() const {
if (const T* val = boost::get<T>(&container)) {
return *val;
} else {
throw IfcParse::IfcException("Invalid cast");
}
}
// AGGREGATES OF AGGREGATES:
empty_aggregate_of_aggregate_t,
// An aggregate of an aggregate of ints. E.g. ((1, 2), (3))
std::vector<std::vector<int>>,
// An aggregate of an aggregate of floats. E.g. ((1., 2.3), (4.))
std::vector<std::vector<double>>,
// An aggregate of an aggregate of entities. E.g. ((#1, #2), (#3))
aggregate_of_aggregate_of_instance::ptr>
container;
template <typename T>
typename boost::disable_if<boost::is_base_of<IfcUtil::IfcBaseInterface, typename boost::remove_pointer<T>::type>, void>::type
set(const T& t) {
container = t;
}
public:
template <typename T>
const T& as() const {
if (const T* val = boost::get<T>(&container)) {
return *val;
} else {
throw IfcParse::IfcException("Invalid cast");
}
}
// Overload to detect null values
void set(const aggregate_of_instance::ptr& v);
template <typename T>
typename boost::disable_if<boost::is_base_of<IfcUtil::IfcBaseInterface, typename boost::remove_pointer<T>::type>, void>::type
set(const T& t) {
container = t;
}
// Overload to detect null values
void set(const aggregate_of_aggregate_of_instance::ptr& v);
// Overload to detect null values
void set(const aggregate_of_instance::ptr& v);
// Overload to detect null values
void set(IfcUtil::IfcBaseInterface*const & v);
operator int() const;
operator bool() const;
operator boost::logic::tribool() const;
// Overload to detect null values
void set(const aggregate_of_aggregate_of_instance::ptr& v);
operator double() const;
operator std::string() const;
operator boost::dynamic_bitset<>() const;
operator IfcUtil::IfcBaseClass*() const;
// Overload to detect null values
void set(IfcUtil::IfcBaseInterface* const& v);
operator std::vector<int>() const;
operator std::vector<double>() const;
operator std::vector<std::string>() const;
operator std::vector<boost::dynamic_bitset<> >() const;
operator aggregate_of_instance::ptr() const;
operator int() const;
operator bool() const;
operator boost::logic::tribool() const;
operator std::vector< std::vector<int> >() const;
operator std::vector< std::vector<double> >() const;
operator aggregate_of_aggregate_of_instance::ptr() const;
operator double() const;
operator std::string() const;
operator boost::dynamic_bitset<>() const;
operator IfcUtil::IfcBaseClass*() const;
bool isNull() const;
Argument* operator [] (unsigned int i) const;
std::string toString(bool upper=false) const;
unsigned int size() const;
IfcUtil::ArgumentType type() const;
};
operator std::vector<int>() const;
operator std::vector<double>() const;
operator std::vector<std::string>() const;
operator std::vector<boost::dynamic_bitset<>>() const;
operator aggregate_of_instance::ptr() const;
}
operator std::vector<std::vector<int>>() const;
operator std::vector<std::vector<double>>() const;
operator aggregate_of_aggregate_of_instance::ptr() const;
bool isNull() const;
Argument* operator[](unsigned int i) const;
std::string toString(bool upper = false) const;
unsigned int size() const;
IfcUtil::ArgumentType type() const;
};
} // namespace IfcWrite
#endif
+162 -141
View File
@@ -20,170 +20,191 @@
#ifndef IFCENTITYLIST_H
#define IFCENTITYLIST_H
#include "../ifcparse/IfcBaseClass.h"
#include "IfcBaseClass.h"
#include <boost/shared_ptr.hpp>
#include <set>
template <class T>
class aggregate_of;
class IFC_PARSE_API aggregate_of_instance {
std::vector<IfcUtil::IfcBaseClass*> ls;
public:
typedef boost::shared_ptr<aggregate_of_instance> ptr;
typedef std::vector<IfcUtil::IfcBaseClass*>::const_iterator it;
void push(IfcUtil::IfcBaseClass* l);
void push(const ptr& l);
it begin();
it end();
IfcUtil::IfcBaseClass* operator[] (int i);
unsigned int size() const;
std::vector<IfcUtil::IfcBaseClass*> ls;
public:
typedef boost::shared_ptr<aggregate_of_instance> ptr;
typedef std::vector<IfcUtil::IfcBaseClass*>::const_iterator it;
void push(IfcUtil::IfcBaseClass* l);
void push(const ptr& l);
it begin();
it end();
IfcUtil::IfcBaseClass* operator[](int i);
unsigned int size() const;
void reserve(unsigned capacity);
bool contains(IfcUtil::IfcBaseClass*) const;
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
for (it i = begin(); i != end(); ++i) {
if ((*i)->as<U>()) {
r->push((*i)->as<U>());
}
}
return r;
}
void remove(IfcUtil::IfcBaseClass*);
aggregate_of_instance::ptr filtered(const std::set<const IfcParse::declaration*>& entities);
aggregate_of_instance::ptr unique();
bool contains(IfcUtil::IfcBaseClass*) const;
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
for (it i = begin(); i != end(); ++i) {
if ((*i)->as<U>()) {
r->push((*i)->as<U>());
}
}
return r;
}
void remove(IfcUtil::IfcBaseClass*);
aggregate_of_instance::ptr filtered(const std::set<const IfcParse::declaration*>& entities);
aggregate_of_instance::ptr unique();
};
template <class T>
class aggregate_of {
std::vector<T*> ls;
public:
typedef boost::shared_ptr< aggregate_of<T> > ptr;
typedef typename std::vector<T*>::const_iterator it;
void push(T* t) { if (t) { ls.push_back(t); } }
void push(ptr t) { if (t) { for (typename T::list::it it = t->begin(); it != t->end(); ++it) push(*it); } }
it begin() { return ls.begin(); }
it end() { return ls.end(); }
unsigned int size() const { return (unsigned int)ls.size(); }
aggregate_of_instance::ptr generalize() {
aggregate_of_instance::ptr r(new aggregate_of_instance());
for (it i = begin(); i != end(); ++i) r->push((*i)->template as<IfcUtil::IfcBaseClass>());
return r;
}
bool contains(T* t) const { return std::find(ls.begin(), ls.end(), t) != ls.end(); }
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
const bool all = !U::Class().as_entity();
for (it i = begin(); i != end(); ++i) if (all || (*i)->declaration().is(U::Class())) r->push((U*)*i);
return r;
}
void remove(T* t) {
typename std::vector<T*>::iterator it;
while ((it = std::find(ls.begin(), ls.end(), t)) != ls.end()) {
ls.erase(it);
}
}
std::vector<T*> ls;
public:
typedef boost::shared_ptr<aggregate_of<T>> ptr;
typedef typename std::vector<T*>::const_iterator it;
void push(T* t) {
if (t) {
ls.push_back(t);
}
}
void push(ptr t) {
if (t) {
for (typename T::list::it it = t->begin(); it != t->end(); ++it) {
push(*it);
}
}
}
it begin() { return ls.begin(); }
it end() { return ls.end(); }
unsigned int size() const { return (unsigned int)ls.size(); }
aggregate_of_instance::ptr generalize() {
aggregate_of_instance::ptr r(new aggregate_of_instance());
for (it i = begin(); i != end(); ++i) {
r->push((*i)->template as<IfcUtil::IfcBaseClass>());
}
return r;
}
bool contains(T* t) const { return std::find(ls.begin(), ls.end(), t) != ls.end(); }
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
const bool all = !U::Class().as_entity();
for (it i = begin(); i != end(); ++i) {
if (all || (*i)->declaration().is(U::Class())) {
r->push((U*)*i);
}
}
return r;
}
void remove(T* t) {
typename std::vector<T*>::iterator it;
while ((it = std::find(ls.begin(), ls.end(), t)) != ls.end()) {
ls.erase(it);
}
}
};
template <class T>
class aggregate_of_aggregate_of;
class IFC_PARSE_API aggregate_of_aggregate_of_instance {
std::vector< std::vector<IfcUtil::IfcBaseClass*> > ls;
public:
typedef boost::shared_ptr< aggregate_of_aggregate_of_instance > ptr;
typedef std::vector< std::vector<IfcUtil::IfcBaseClass*> >::const_iterator outer_it;
typedef std::vector<IfcUtil::IfcBaseClass*>::const_iterator inner_it;
void push(const std::vector<IfcUtil::IfcBaseClass*>& l) {
ls.push_back(l);
}
void push(const aggregate_of_instance::ptr& l) {
if (l) {
std::vector<IfcUtil::IfcBaseClass*> li;
for (std::vector<IfcUtil::IfcBaseClass*>::const_iterator jt = l->begin(); jt != l->end(); ++jt) {
li.push_back(*jt);
}
push(li);
}
}
outer_it begin() const { return ls.begin(); }
outer_it end() const { return ls.end(); }
int size() const { return (int)ls.size(); }
int totalSize() const {
int accum = 0;
for (outer_it it = begin(); it != end(); ++it) {
accum += (int)it->size();
}
return accum;
}
bool contains(IfcUtil::IfcBaseClass* instance) const {
for (outer_it it = begin(); it != end(); ++it) {
const std::vector<IfcUtil::IfcBaseClass*>& inner = *it;
if (std::find(inner.begin(), inner.end(), instance) != inner.end()) {
return true;
}
}
return false;
}
template <class U>
typename aggregate_of_aggregate_of<U>::ptr as() {
typename aggregate_of_aggregate_of<U>::ptr r(new aggregate_of_aggregate_of<U>);
const bool all = !U::Class().as_entity();
for (outer_it outer = begin(); outer != end(); ++outer) {
const std::vector<IfcUtil::IfcBaseClass*>& from = *outer;
typename std::vector<U*> to;
for (inner_it inner = from.begin(); inner != from.end(); ++inner) {
if (all || (*inner)->declaration().is(U::Class())) to.push_back((U*)*inner);
}
r->push(to);
}
return r;
}
std::vector<std::vector<IfcUtil::IfcBaseClass*>> ls;
public:
typedef boost::shared_ptr<aggregate_of_aggregate_of_instance> ptr;
typedef std::vector<std::vector<IfcUtil::IfcBaseClass*>>::const_iterator outer_it;
typedef std::vector<IfcUtil::IfcBaseClass*>::const_iterator inner_it;
void push(const std::vector<IfcUtil::IfcBaseClass*>& l) {
ls.push_back(l);
}
void push(const aggregate_of_instance::ptr& l) {
if (l) {
std::vector<IfcUtil::IfcBaseClass*> li;
for (std::vector<IfcUtil::IfcBaseClass*>::const_iterator jt = l->begin(); jt != l->end(); ++jt) {
li.push_back(*jt);
}
push(li);
}
}
outer_it begin() const { return ls.begin(); }
outer_it end() const { return ls.end(); }
int size() const { return (int)ls.size(); }
int totalSize() const {
int accum = 0;
for (outer_it it = begin(); it != end(); ++it) {
accum += (int)it->size();
}
return accum;
}
bool contains(IfcUtil::IfcBaseClass* instance) const {
for (outer_it it = begin(); it != end(); ++it) {
const std::vector<IfcUtil::IfcBaseClass*>& inner = *it;
if (std::find(inner.begin(), inner.end(), instance) != inner.end()) {
return true;
}
}
return false;
}
template <class U>
typename aggregate_of_aggregate_of<U>::ptr as() {
typename aggregate_of_aggregate_of<U>::ptr r(new aggregate_of_aggregate_of<U>);
const bool all = !U::Class().as_entity();
for (outer_it outer = begin(); outer != end(); ++outer) {
const std::vector<IfcUtil::IfcBaseClass*>& from = *outer;
typename std::vector<U*> to;
for (inner_it inner = from.begin(); inner != from.end(); ++inner) {
if (all || (*inner)->declaration().is(U::Class())) {
to.push_back((U*)*inner);
}
}
r->push(to);
}
return r;
}
};
template <class T>
class aggregate_of_aggregate_of {
std::vector< std::vector<T*> > ls;
public:
typedef typename boost::shared_ptr< aggregate_of_aggregate_of<T> > ptr;
typedef typename std::vector< std::vector<T*> >::const_iterator outer_it;
typedef typename std::vector<T*>::const_iterator inner_it;
void push(const std::vector<T*>& t) { ls.push_back(t); }
outer_it begin() { return ls.begin(); }
outer_it end() { return ls.end(); }
int size() const { return (int)ls.size(); }
int totalSize() const {
int accum = 0;
for (outer_it it = begin(); it != end(); ++it) {
accum += it->size();
}
return accum;
}
bool contains(T* t) const {
for (outer_it it = begin(); it != end(); ++it) {
const std::vector<T*>& inner = *it;
if (std::find(inner.begin(), inner.end(), t) != inner.end()) {
return true;
}
}
return false;
}
aggregate_of_aggregate_of_instance::ptr generalize() {
aggregate_of_aggregate_of_instance::ptr r(new aggregate_of_aggregate_of_instance());
for (outer_it outer = begin(); outer != end(); ++outer) {
const std::vector<T*>& from = *outer;
std::vector<IfcUtil::IfcBaseClass*> to;
for (inner_it inner = from.begin(); inner != from.end(); ++inner) {
to.push_back(*inner);
}
r->push(to);
}
return r;
}
std::vector<std::vector<T*>> ls;
public:
typedef typename boost::shared_ptr<aggregate_of_aggregate_of<T>> ptr;
typedef typename std::vector<std::vector<T*>>::const_iterator outer_it;
typedef typename std::vector<T*>::const_iterator inner_it;
void push(const std::vector<T*>& t) { ls.push_back(t); }
outer_it begin() { return ls.begin(); }
outer_it end() { return ls.end(); }
int size() const { return (int)ls.size(); }
int totalSize() const {
int accum = 0;
for (outer_it it = begin(); it != end(); ++it) {
accum += it->size();
}
return accum;
}
bool contains(T* t) const {
for (outer_it it = begin(); it != end(); ++it) {
const std::vector<T*>& inner = *it;
if (std::find(inner.begin(), inner.end(), t) != inner.end()) {
return true;
}
}
return false;
}
aggregate_of_aggregate_of_instance::ptr generalize() {
aggregate_of_aggregate_of_instance::ptr r(new aggregate_of_aggregate_of_instance());
for (outer_it outer = begin(); outer != end(); ++outer) {
const std::vector<T*>& from = *outer;
std::vector<IfcUtil::IfcBaseClass*> to;
for (inner_it inner = from.begin(); inner != from.end(); ++inner) {
to.push_back(*inner);
}
r->push(to);
}
return r;
}
};
#endif
+15 -15
View File
@@ -21,30 +21,30 @@
#define IFC_PARSE_API_H
#ifdef IFC_SHARED_BUILD
#ifdef _WIN32
#ifdef IFC_PARSE_EXPORTS
#define IFC_PARSE_API __declspec(dllexport)
#else
#define IFC_PARSE_API __declspec(dllimport)
#endif
#else // simply assume *nix + GCC-like compiler
#define IFC_PARSE_API __attribute__((visibility("default")))
#endif
#ifdef _WIN32
#ifdef IFC_PARSE_EXPORTS
#define IFC_PARSE_API __declspec(dllexport)
#else
#define IFC_PARSE_API
#define IFC_PARSE_API __declspec(dllimport)
#endif
#else // simply assume *nix + GCC-like compiler
#define IFC_PARSE_API __attribute__((visibility("default")))
#endif
#else
#define IFC_PARSE_API
#endif
#if defined(__clang__)
# define my_thread_local thread_local
#define my_thread_local thread_local
#elif defined(__GNUC__)
# define my_thread_local __thread
#define my_thread_local __thread
#elif __STDC_VERSION__ >= 201112L
# define my_thread_local _Thread_local
#define my_thread_local _Thread_local
#elif defined(_MSC_VER)
# define my_thread_local __declspec(thread)
#define my_thread_local __declspec(thread)
#elif defined(SWIG)
#else
# error Cannot define thread_local
#error Cannot define thread_local
#endif
#endif
+3 -5
View File
@@ -20,17 +20,15 @@
#ifndef IFCOPENSHELL_MACROS_H
#define IFCOPENSHELL_MACROS_H
#define POSTFIX_SCHEMA__(a, b) a ## _ ## b
#define POSTFIX_SCHEMA__(a, b) a##_##b
#define POSTFIX_SCHEMA_(a, b) POSTFIX_SCHEMA__(a, b)
#define POSTFIX_SCHEMA(t) POSTFIX_SCHEMA_(t, IfcSchema)
#define STRINGIFY_(x) #x
#define STRINGIFY(x) STRINGIFY_(x)
#define MAKE_INIT_FN__(a, b) init_ ## a ## _ ## b
#define MAKE_INIT_FN__(a, b) init_##a##_##b
#define MAKE_INIT_FN_(a, b) MAKE_INIT_FN__(a, b)
#define MAKE_INIT_FN(t) MAKE_INIT_FN_(t, IfcSchema)
#endif
#endif
File diff suppressed because it is too large Load Diff
+19 -19
View File
@@ -17,7 +17,7 @@
* *
********************************************************************************/
#include "../ifcparse/ifc_parse_api.h"
#include "ifc_parse_api.h"
#include <string>
@@ -26,34 +26,34 @@
namespace IfcUtil {
/// Replaces spaces and potentially other problem causing characters with underscores.
IFC_PARSE_API void sanitate_material_name(std::string &str);
/// Replaces spaces and potentially other problem causing characters with underscores.
IFC_PARSE_API void sanitate_material_name(std::string& str);
IFC_PARSE_API void escape_xml(std::string &str);
IFC_PARSE_API void unescape_xml(std::string &str);
IFC_PARSE_API void escape_xml(std::string& str);
IFC_PARSE_API void unescape_xml(std::string& str);
namespace path {
namespace path {
IFC_PARSE_API bool delete_file(const std::string& filename);
IFC_PARSE_API bool rename_file(const std::string& old_filename, const std::string& new_filename);
IFC_PARSE_API bool delete_file(const std::string& filename);
IFC_PARSE_API bool rename_file(const std::string& old_filename, const std::string& new_filename);
#if defined(_MSC_VER) && defined(_UNICODE)
/// Uses windows.h string conversion functions
IFC_PARSE_API std::string to_utf8(const std::wstring& str);
/// Uses windows.h string conversion functions
IFC_PARSE_API std::string to_utf8(const std::wstring& str);
/// Uses windows.h string conversion functions
IFC_PARSE_API std::wstring from_utf8(const std::string& str);
/// Uses windows.h string conversion functions
IFC_PARSE_API std::wstring from_utf8(const std::string& str);
#else
/// Identity operation
IFC_PARSE_API inline std::string to_utf8(const std::string& str) { return str; }
/// Identity operation
IFC_PARSE_API inline std::string to_utf8(const std::string& str) { return str; }
/// Identity operation
IFC_PARSE_API inline std::string from_utf8(const std::string& str) { return str; }
/// Identity operation
IFC_PARSE_API inline std::string from_utf8(const std::string& str) { return str; }
#endif
}
} // namespace path
}
} // namespace IfcUtil
#endif