mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 14:33:28 +00:00
#1311 better error handling during parse for schema and header
This commit is contained in:
@@ -54,16 +54,36 @@ from . import guid
|
|||||||
from .file import file
|
from .file import file
|
||||||
from .entity_instance import entity_instance
|
from .entity_instance import entity_instance
|
||||||
|
|
||||||
|
READ_ERROR = ifcopenshell_wrapper.file_open_status.READ_ERROR
|
||||||
|
NO_HEADER = ifcopenshell_wrapper.file_open_status.NO_HEADER
|
||||||
|
UNSUPPORTED_SCHEMA = ifcopenshell_wrapper.file_open_status.UNSUPPORTED_SCHEMA
|
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaError(Error):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def open(fn):
|
def open(fn):
|
||||||
f = ifcopenshell_wrapper.open(os.path.abspath(fn))
|
f = ifcopenshell_wrapper.open(os.path.abspath(fn))
|
||||||
if f.good():
|
if f.good():
|
||||||
return file(f)
|
return file(f)
|
||||||
else:
|
else:
|
||||||
raise IOError("Unable to open file for reading")
|
exc, msg = {
|
||||||
|
READ_ERROR: (IOError, "Unable to open file for reading"),
|
||||||
|
NO_HEADER: (Error, "Unable to parse IFC SPF header"),
|
||||||
|
UNSUPPORTED_SCHEMA: (
|
||||||
|
SchemaError,
|
||||||
|
"Unsupported schema: %s" % ",".join(f.header.file_schema.schema_identifiers),
|
||||||
|
),
|
||||||
|
}[f.good().value()]
|
||||||
|
raise exc(msg)
|
||||||
|
|
||||||
|
|
||||||
def create_entity(type, schema='IFC4', *args, **kwargs):
|
def create_entity(type, schema="IFC4", *args, **kwargs):
|
||||||
e = entity_instance((schema, type))
|
e = entity_instance((schema, type))
|
||||||
attrs = list(enumerate(args)) + [(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()]
|
attrs = list(enumerate(args)) + [(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()]
|
||||||
for idx, arg in attrs:
|
for idx, arg in attrs:
|
||||||
|
|||||||
+33
-2
@@ -33,6 +33,36 @@
|
|||||||
|
|
||||||
namespace IfcParse {
|
namespace IfcParse {
|
||||||
|
|
||||||
|
class IFC_PARSE_API file_open_status {
|
||||||
|
public:
|
||||||
|
enum file_open_enum {
|
||||||
|
SUCCESS,
|
||||||
|
READ_ERROR,
|
||||||
|
NO_HEADER,
|
||||||
|
UNSUPPORTED_SCHEMA
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
file_open_enum error_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
file_open_status(file_open_enum error)
|
||||||
|
: error_(error)
|
||||||
|
{}
|
||||||
|
|
||||||
|
operator file_open_enum() const {
|
||||||
|
return error_;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_open_enum value() const {
|
||||||
|
return error_;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return error_ == SUCCESS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// This class provides several static convenience functions and variables
|
/// This class provides several static convenience functions and variables
|
||||||
/// and provide access to the entities in an IFC file
|
/// and provide access to the entities in an IFC file
|
||||||
class IFC_PARSE_API IfcFile {
|
class IFC_PARSE_API IfcFile {
|
||||||
@@ -78,7 +108,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
typedef std::map<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*> entity_entity_map_t;
|
typedef std::map<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*> entity_entity_map_t;
|
||||||
|
|
||||||
bool parsing_complete_, good_;
|
bool parsing_complete_;
|
||||||
|
file_open_status good_ = file_open_status::SUCCESS;
|
||||||
|
|
||||||
const IfcParse::schema_definition* schema_;
|
const IfcParse::schema_definition* schema_;
|
||||||
const IfcParse::declaration* ifcroot_type_;
|
const IfcParse::declaration* ifcroot_type_;
|
||||||
@@ -116,7 +147,7 @@ public:
|
|||||||
|
|
||||||
virtual ~IfcFile();
|
virtual ~IfcFile();
|
||||||
|
|
||||||
bool good() const { return good_; }
|
file_open_status good() const { return good_; }
|
||||||
|
|
||||||
/// Returns the first entity in the file, this probably is the entity
|
/// Returns the first entity in the file, this probably is the entity
|
||||||
/// with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
|
/// with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
|
||||||
|
|||||||
+13
-12
@@ -1326,7 +1326,6 @@ IfcFile::IfcFile(IfcParse::IfcSpfStream* s) {
|
|||||||
|
|
||||||
IfcFile::IfcFile(const IfcParse::schema_definition* schema)
|
IfcFile::IfcFile(const IfcParse::schema_definition* schema)
|
||||||
: parsing_complete_(true)
|
: parsing_complete_(true)
|
||||||
, good_(true)
|
|
||||||
, schema_(schema)
|
, schema_(schema)
|
||||||
, ifcroot_type_(schema_->declaration_by_name("IfcRoot"))
|
, ifcroot_type_(schema_->declaration_by_name("IfcRoot"))
|
||||||
, MaxId(0)
|
, MaxId(0)
|
||||||
@@ -1341,8 +1340,6 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
|
|||||||
// number parsing. See comment above on line 41.
|
// number parsing. See comment above on line 41.
|
||||||
init_locale();
|
init_locale();
|
||||||
|
|
||||||
good_ = false;
|
|
||||||
|
|
||||||
parsing_complete_ = false;
|
parsing_complete_ = false;
|
||||||
MaxId = 0;
|
MaxId = 0;
|
||||||
tokens = 0;
|
tokens = 0;
|
||||||
@@ -1353,24 +1350,30 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
|
|||||||
|
|
||||||
stream = s;
|
stream = s;
|
||||||
if (!stream->valid) {
|
if (!stream->valid) {
|
||||||
|
good_ = file_open_status::READ_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = new IfcSpfLexer(stream, this);
|
tokens = new IfcSpfLexer(stream, this);
|
||||||
_header.file(this);
|
|
||||||
_header.tryRead();
|
|
||||||
|
|
||||||
std::vector<std::string> schemas;
|
std::vector<std::string> schemas;
|
||||||
try {
|
|
||||||
schemas = _header.file_schema().schema_identifiers();
|
_header.file(this);
|
||||||
} catch (...) {
|
if (_header.tryRead()) {
|
||||||
// Purposely empty catch block
|
try {
|
||||||
|
schemas = _header.file_schema().schema_identifiers();
|
||||||
|
} catch (...) {
|
||||||
|
// Purposely empty catch block
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
good_ = file_open_status::NO_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schemas.size() == 1) {
|
if (schemas.size() == 1) {
|
||||||
try {
|
try {
|
||||||
schema_ = IfcParse::schema_by_name(schemas.front());
|
schema_ = IfcParse::schema_by_name(schemas.front());
|
||||||
} catch (const IfcParse::IfcException& e) {
|
} catch (const IfcParse::IfcException& e) {
|
||||||
|
good_ = file_open_status::UNSUPPORTED_SCHEMA;
|
||||||
Logger::Error(e);
|
Logger::Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1381,8 +1384,6 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
good_ = true;
|
|
||||||
|
|
||||||
ifcroot_type_ = schema_->declaration_by_name("IfcRoot");
|
ifcroot_type_ = schema_->declaration_by_name("IfcRoot");
|
||||||
|
|
||||||
boost::circular_buffer<Token> token_stream(3, Token());
|
boost::circular_buffer<Token> token_stream(3, Token());
|
||||||
|
|||||||
Reference in New Issue
Block a user