mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Merge branch 'master' into v0.6.0
# Conflicts: # src/ifcconvert/IfcConvert.cpp # src/ifcgeom/IfcGeomRenderStyles.cpp # src/ifcgeom/IfcGeomWires.cpp # src/ifcparse/IfcLogger.cpp # src/ifcparse/IfcLogger.h # src/ifcparse/IfcParse.cpp # src/ifcparse/IfcUtil.cpp # src/serializers/ColladaSerializer.cpp # src/serializers/schema_dependent/XmlSerializer.cpp
This commit is contained in:
@@ -52,10 +52,6 @@ namespace IfcUtil {
|
||||
IFC_PARSE_API const char* ArgumentTypeToString(ArgumentType argument_type);
|
||||
|
||||
IFC_PARSE_API bool valid_binary_string(const std::string& s);
|
||||
/// 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);
|
||||
}
|
||||
|
||||
class IFC_PARSE_API Argument {
|
||||
|
||||
+95
-30
@@ -32,58 +32,113 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
namespace {
|
||||
static const char* severity_strings[] = {"Notice", "Warning", "Error"};
|
||||
|
||||
template <typename T>
|
||||
struct severity_strings {
|
||||
static const std::array<std::basic_string<T>, 3> value;
|
||||
};
|
||||
|
||||
void plain_text_message(std::ostream& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
os << "[" << severity_strings[type] << "] ";
|
||||
template <>
|
||||
const std::array<std::basic_string<char>, 3> severity_strings<char>::value = { "Notice", "Warning", "Error" };
|
||||
|
||||
template <>
|
||||
const std::array<std::basic_string<wchar_t>, 3> severity_strings<wchar_t>::value = { 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::IfcBaseClass* instance) {
|
||||
os << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
|
||||
if (current_product) {
|
||||
std::string global_id = *(**current_product).data().getArgument((**current_product).declaration().as_entity()->attribute_index("GlobalId"));
|
||||
os << "{" << global_id << "} ";
|
||||
std::string global_id = *(**current_product).get("GlobalId"));
|
||||
os << "{" << global_id.c_str() << "} ";
|
||||
}
|
||||
os << message << std::endl;
|
||||
os << message.c_str() << std::endl;
|
||||
if (instance) {
|
||||
std::string instance_string = instance->data().toString();
|
||||
std::string instance_string = entity->data().toString();
|
||||
if (instance_string.size() > 259) {
|
||||
instance_string = instance_string.substr(0, 256) + "...";
|
||||
}
|
||||
os << instance_string << std::endl;
|
||||
os << instance_string.c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void json_message(std::ostream& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
ptree pt;
|
||||
pt.put("level", severity_strings[type]);
|
||||
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::IfcBaseClass* 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 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", (**current_product).data().toString());
|
||||
pt.put(product_string, string_as<typename T::char_type>((**current_product).data().toString()));
|
||||
}
|
||||
pt.put("message", message);
|
||||
pt.put(message_string, string_as<typename T::char_type>(message));
|
||||
if (instance) {
|
||||
pt.put("instance", instance->data().toString());
|
||||
pt.put(instance_string, string_as<typename T::char_type>(instance->data().toString()));
|
||||
}
|
||||
boost::property_tree::write_json(os, pt, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
void Logger::SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product) {
|
||||
current_product = product;
|
||||
}
|
||||
|
||||
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
wlog1 = wlog2 = 0;
|
||||
log1 = l1;
|
||||
log2 = l2;
|
||||
if ( ! log2 ) {
|
||||
if (!log2) {
|
||||
log2 = &log_stream;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
if (type > max_severity) {
|
||||
max_severity = type;
|
||||
void Logger::SetOutput(std::wostream* l1, std::wostream* l2) {
|
||||
log1 = log2 = 0;
|
||||
wlog1 = l1;
|
||||
wlog2 = l2;
|
||||
if (!wlog2) {
|
||||
log2 = &log_stream;
|
||||
}
|
||||
if (log2 && type >= verbosity) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Logger::log(T& log2, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
log2 << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
|
||||
if (current_product) {
|
||||
log2 << "{" << (*current_product)->GlobalId().c_str() << "} ";
|
||||
}
|
||||
log2 << message.c_str() << std::endl;
|
||||
if (instance) {
|
||||
log2 << instance->data().toString().c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
if ((log2 || wlog2) && type >= verbosity) {
|
||||
if (format == FMT_PLAIN) {
|
||||
plain_text_message(*log2, current_product, type, message, instance);
|
||||
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) {
|
||||
json_message(*log2, current_product, type, message, instance);
|
||||
if (log2) {
|
||||
json_message(*log2, current_product, type, message, instance);
|
||||
} else if (wlog2) {
|
||||
json_message(*wlog2, current_product, type, message, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,18 +147,26 @@ void Logger::Message(Logger::Severity type, const std::exception& exception, con
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Status(const std::string& message, bool new_line) {
|
||||
if (log1) {
|
||||
(*log1) << message;
|
||||
if ( new_line ) (*log1) << std::endl;
|
||||
else (*log1) << std::flush;
|
||||
status(*log1, message, new_line);
|
||||
} else if (wlog1) {
|
||||
status(*wlog1, message, new_line);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::ProgressBar(int progress) {
|
||||
if (log1) {
|
||||
Status("\r[" + std::string(progress,'#') + std::string(50 - progress,' ') + "]", false);
|
||||
}
|
||||
Status("\r[" + std::string(progress,'#') + std::string(50 - progress,' ') + "]", false);
|
||||
}
|
||||
|
||||
std::string Logger::GetLog() {
|
||||
@@ -120,6 +183,8 @@ Logger::Format Logger::OutputFormat() { return format; }
|
||||
|
||||
std::ostream* Logger::log1 = 0;
|
||||
std::ostream* Logger::log2 = 0;
|
||||
std::wostream* Logger::wlog1 = 0;
|
||||
std::wostream* Logger::wlog2 = 0;
|
||||
std::stringstream Logger::log_stream;
|
||||
Logger::Severity Logger::verbosity = Logger::LOG_NOTICE;
|
||||
Logger::Severity Logger::max_severity = Logger::LOG_NOTICE;
|
||||
|
||||
@@ -38,19 +38,31 @@ public:
|
||||
typedef enum { LOG_NOTICE, LOG_WARNING, LOG_ERROR } Severity;
|
||||
typedef enum { FMT_PLAIN, FMT_JSON } Format;
|
||||
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::wostream* wlog1;
|
||||
static std::wostream* wlog2;
|
||||
|
||||
static std::stringstream log_stream;
|
||||
|
||||
static Severity verbosity;
|
||||
static Format format;
|
||||
static boost::optional<IfcUtil::IfcBaseClass*> current_product;
|
||||
static Severity max_severity;
|
||||
static boost::optional<IfcSchema::IfcProduct*> current_product;
|
||||
|
||||
template <typename T>
|
||||
static void log(T& log2, Logger::Severity type, const std::string& message, IfcUtil::IfcBaseClass* instance);
|
||||
public:
|
||||
static void SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product);
|
||||
|
||||
static void SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product) {
|
||||
current_product = product;
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include <ctime>
|
||||
#include <boost/circular_buffer.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
@@ -40,6 +36,7 @@
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcSIPrefix.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/utils.h"
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#include <boost/filesystem/path.hpp>
|
||||
@@ -117,9 +114,8 @@ IfcSpfStream::IfcSpfStream(const std::string& fn)
|
||||
, eof(false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
int fn_buffer_size = MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, 0, 0);
|
||||
wchar_t* fn_wide = new wchar_t[fn_buffer_size];
|
||||
MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, fn_wide, fn_buffer_size);
|
||||
std::wstring fn_ws = IfcUtil::path::from_utf8(fn);
|
||||
const wchar_t* fn_wide = fn_ws.c_str();
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (mmap) {
|
||||
@@ -131,7 +127,6 @@ IfcSpfStream::IfcSpfStream(const std::string& fn)
|
||||
}
|
||||
#endif
|
||||
|
||||
delete[] fn_wide;
|
||||
#else
|
||||
|
||||
#ifdef USE_MMAP
|
||||
|
||||
@@ -17,8 +17,43 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#ifndef NOMSG
|
||||
#define NOMSG NOMSG
|
||||
#endif
|
||||
#ifndef NODRAWTEXT
|
||||
#define NODRAWTEXT NODRAWTEXT
|
||||
#endif
|
||||
#ifndef NOGDI
|
||||
#define NOGDI NOGDI
|
||||
#endif
|
||||
#ifndef NOSERVICE
|
||||
#define NOSERVICE NOSERVICE
|
||||
#endif
|
||||
#ifndef NOKERNEL
|
||||
#define NOKERNEL NOKERNEL
|
||||
#endif
|
||||
#ifndef NOUSER
|
||||
#define NOUSER NOUSER
|
||||
#endif
|
||||
#ifndef NOMCX
|
||||
#define NOMCX NOMCX
|
||||
#endif
|
||||
#ifndef NOIME
|
||||
#define NOIME NOIME
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
#include "../ifcparse/Argument.h"
|
||||
#include "../ifcparse/utils.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcEntityList.h"
|
||||
|
||||
@@ -240,4 +275,52 @@ IfcUtil::ArgumentType IfcUtil::from_parameter_type(const IfcParse::parameter_typ
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
IFC_PARSE_API bool IfcUtil::path::delete_file(const std::string& filename) {
|
||||
return std::remove(filename.c_str());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 "../ifcparse/ifc_parse_api.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef IFCPARSE_UTILS_H
|
||||
#define IFCPARSE_UTILS_H
|
||||
|
||||
namespace IfcUtil {
|
||||
|
||||
/// 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);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
/// 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);
|
||||
#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 from_utf8(const std::string& str) { return str; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user