mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Auto-detect filetype
This commit is contained in:
@@ -499,3 +499,43 @@ IfcParse::IfcFile::~IfcFile() {
|
||||
delete p.second;
|
||||
}
|
||||
}
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
IfcParse::filetype IfcParse::guess_file_type(const std::string& fn) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
if (!fs::exists(fn)) {
|
||||
// @todo this is just weird, but for consistency with earlier behaviour
|
||||
// for now the only intent for this function is to auto-detect RocksDB
|
||||
return FT_IFCSPF;
|
||||
}
|
||||
|
||||
if (fs::is_directory(fn)) {
|
||||
// Typical RocksDB file to look for
|
||||
auto currentFile = fs::path(fn) / "CURRENT";
|
||||
|
||||
if (!fs::exists(currentFile) || !fs::is_regular_file(currentFile)) {
|
||||
return FT_UNKNOWN;
|
||||
}
|
||||
|
||||
std::ifstream infile(currentFile);
|
||||
if (!infile) {
|
||||
return FT_UNKNOWN;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
if (!std::getline(infile, line)) {
|
||||
return FT_UNKNOWN;
|
||||
}
|
||||
|
||||
// RocksDB's CURRENT file typically contains a line like "MANIFEST-000001".
|
||||
if (line.find("MANIFEST-") == 0) {
|
||||
return FT_ROCKSDB;
|
||||
}
|
||||
} else {
|
||||
// @todo just return SPF for now, but ideally this will be augmented with all other options
|
||||
return FT_IFCSPF;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-6
@@ -572,12 +572,16 @@ namespace impl {
|
||||
}
|
||||
|
||||
enum filetype {
|
||||
ifcspf,
|
||||
ifcxml,
|
||||
rocksdb,
|
||||
autodetect
|
||||
FT_IFCSPF,
|
||||
FT_IFCXML,
|
||||
FT_IFCZIP,
|
||||
FT_ROCKSDB,
|
||||
FT_UNKNOWN,
|
||||
FT_AUTODETECT
|
||||
};
|
||||
|
||||
filetype guess_file_type(const std::string& fn);
|
||||
|
||||
/// This class provides access to the entity instances in an IFC file
|
||||
/// The file takes ownership of instances added to this file and deletes them when the file is deleted.
|
||||
class IFC_PARSE_API IfcFile {
|
||||
@@ -623,13 +627,13 @@ private:
|
||||
#ifdef USE_MMAP
|
||||
IfcFile(const std::string& path, bool mmap = false);
|
||||
#else
|
||||
IfcFile(const std::string& path, filetype ty=ifcspf);
|
||||
IfcFile(const std::string& path, filetype ty=FT_AUTODETECT);
|
||||
#endif
|
||||
IfcFile(std::istream& stream, int length);
|
||||
IfcFile(void* data, int length);
|
||||
IfcFile(IfcParse::IfcSpfStream* stream);
|
||||
// @nb path is only used in rocksdb mode, for spf file is in-memory only until write() is called
|
||||
IfcFile(const IfcParse::schema_definition* schema = IfcParse::schema_by_name("IFC4"), filetype ty = ifcspf, const std::string& path = "");
|
||||
IfcFile(const IfcParse::schema_definition* schema = IfcParse::schema_by_name("IFC4"), filetype ty = FT_AUTODETECT, const std::string& path = "");
|
||||
|
||||
~IfcFile();
|
||||
|
||||
|
||||
@@ -1296,7 +1296,10 @@ IfcFile::IfcFile(const std::string& fn, bool mmap) {
|
||||
#else
|
||||
IfcFile::IfcFile(const std::string& path, filetype ty) {
|
||||
// @todo allow for rocksdb from path
|
||||
if (ty == ifcspf) {
|
||||
if (ty == FT_AUTODETECT) {
|
||||
ty = guess_file_type(path);
|
||||
}
|
||||
if (ty == FT_IFCSPF) {
|
||||
IfcSpfStream s(path);
|
||||
storage_.emplace<1>(); // impl::in_memory_file_storage{};
|
||||
// @todo assign in constructor
|
||||
@@ -1307,7 +1310,7 @@ IfcFile::IfcFile(const std::string& path, filetype ty) {
|
||||
byid_ = decltype(byid_)(&std::get<impl::in_memory_file_storage>(storage_).byid_);
|
||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
||||
// byidentity_ = decltype(byidentity_)(&std::get<impl::in_memory_file_storage>(storage_).byidentity_);
|
||||
} else {
|
||||
} else if (ty == FT_ROCKSDB) {
|
||||
// @todo this can only be used for databases that already exist, because otherwise there is no way to specify the schema
|
||||
storage_.emplace<2>(path, this);
|
||||
std::get<impl::rocks_db_file_storage>(storage_).read_schema(schema_);
|
||||
@@ -1315,6 +1318,8 @@ IfcFile::IfcFile(const std::string& path, filetype ty) {
|
||||
byid_ = decltype(byid_)(&std::get<impl::rocks_db_file_storage>(storage_).instance_by_name_);
|
||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::rocks_db_file_storage>(storage_).byref_excl_);
|
||||
// byidentity_ = decltype(byidentity_)(&std::get<impl::rocks_db_file_storage>(storage_).instance_cache_);
|
||||
} else {
|
||||
throw std::runtime_error("Unsupported file format");
|
||||
}
|
||||
ifcroot_type_ = schema_->declaration_by_name("IfcRoot");
|
||||
}
|
||||
@@ -1344,21 +1349,26 @@ IfcFile::IfcFile(const IfcParse::schema_definition* schema, filetype ty, const s
|
||||
: schema_(schema)
|
||||
, ifcroot_type_(schema_->declaration_by_name("IfcRoot"))
|
||||
, max_id_(0)
|
||||
, _header(ty == rocksdb ? this : nullptr)
|
||||
, _header(ty == FT_ROCKSDB ? this : nullptr)
|
||||
{
|
||||
if (ty == ifcspf) {
|
||||
if (ty == FT_AUTODETECT) {
|
||||
ty = guess_file_type(path);
|
||||
}
|
||||
if (ty == FT_IFCSPF) {
|
||||
storage_.emplace<1>();
|
||||
std::get<impl::in_memory_file_storage>(storage_).file = this;
|
||||
|
||||
byid_ = decltype(byid_)(&std::get<impl::in_memory_file_storage>(storage_).byid_);
|
||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
||||
// byidentity_ = decltype(byidentity_)(&std::get<impl::in_memory_file_storage>(storage_).byidentity_);
|
||||
} else {
|
||||
} else if (ty == FT_ROCKSDB) {
|
||||
storage_.emplace<2>(path, this);
|
||||
|
||||
byid_ = decltype(byid_)(&std::get<impl::rocks_db_file_storage>(storage_).instance_by_name_);
|
||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::rocks_db_file_storage>(storage_).byref_excl_);
|
||||
// byidentity_ = decltype(byidentity_)(&std::get<impl::rocks_db_file_storage>(storage_).instance_cache_);
|
||||
} else {
|
||||
throw std::runtime_error("Unsupported file format");
|
||||
}
|
||||
setDefaultHeaderValues();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user