mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-18 19:30:25 +00:00
clang-format: format test
This commit is contained in:
committed by
Thomas Krijnen
parent
17838f2426
commit
63177a7c35
+35
-36
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
+581
-645
File diff suppressed because it is too large
Load Diff
+326
-308
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+209
-206
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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, "&", "&");
|
||||
void IfcUtil::escape_xml(std::string& str) {
|
||||
boost::replace_all(str, "&", "&");
|
||||
boost::replace_all(str, "\"", """);
|
||||
boost::replace_all(str, "'", "'");
|
||||
boost::replace_all(str, "<", "<");
|
||||
boost::replace_all(str, ">", ">");
|
||||
}
|
||||
|
||||
void IfcUtil::unescape_xml(std::string &str)
|
||||
{
|
||||
boost::replace_all(str, "&", "&");
|
||||
void IfcUtil::unescape_xml(std::string& str) {
|
||||
boost::replace_all(str, "&", "&");
|
||||
boost::replace_all(str, """, "\"");
|
||||
boost::replace_all(str, "'", "'");
|
||||
boost::replace_all(str, "<", "<");
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+578
-552
File diff suppressed because it is too large
Load Diff
+19
-19
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user