mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 22:31:55 +00:00
Add string decode/encode api
This commit is contained in:
@@ -95,6 +95,8 @@ from .sql import sqlite, sqlite_entity
|
|||||||
|
|
||||||
rocksdb_lazy_instance = file_module.rocksdb_lazy_instance
|
rocksdb_lazy_instance = file_module.rocksdb_lazy_instance
|
||||||
|
|
||||||
|
decode_spf_string = ifcopenshell_wrapper.decode_spf_string
|
||||||
|
encode_spf_string = ifcopenshell_wrapper.encode_spf_string
|
||||||
get_log = ifcopenshell_wrapper.get_log
|
get_log = ifcopenshell_wrapper.get_log
|
||||||
logger = ifcopenshell_wrapper.logger if hasattr(ifcopenshell_wrapper, "logger") else None
|
logger = ifcopenshell_wrapper.logger if hasattr(ifcopenshell_wrapper, "logger") else None
|
||||||
if hasattr(ifcopenshell_wrapper, "logger_or_root"):
|
if hasattr(ifcopenshell_wrapper, "logger_or_root"):
|
||||||
@@ -114,6 +116,8 @@ def optional_logger_args(logger: ifcopenshell_wrapper.logger | None) -> tuple[lo
|
|||||||
# (it's a requirement for a typed library)
|
# (it's a requirement for a typed library)
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"clear_plugin_search_paths",
|
"clear_plugin_search_paths",
|
||||||
|
"decode_spf_string",
|
||||||
|
"encode_spf_string",
|
||||||
"entity_instance",
|
"entity_instance",
|
||||||
"file",
|
"file",
|
||||||
"get_plugin_search_paths",
|
"get_plugin_search_paths",
|
||||||
|
|||||||
@@ -1649,6 +1649,8 @@ def construct_iterator_with_include_exclude_id(
|
|||||||
geometry_library, settings, file, elems, include, num_threads, logger=None
|
geometry_library, settings, file, elems, include, num_threads, logger=None
|
||||||
): ...
|
): ...
|
||||||
def convert_loop_to_function_item(loop): ...
|
def convert_loop_to_function_item(loop): ...
|
||||||
|
def decode_spf_string(value: str) -> str: ...
|
||||||
|
def encode_spf_string(value: str) -> str: ...
|
||||||
|
|
||||||
class attribute_value_derived: ...
|
class attribute_value_derived: ...
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
|
||||||
|
|
||||||
|
def test_spf_strings_can_be_encoded_and_decoded():
|
||||||
|
decoded = "Café's \\"
|
||||||
|
encoded = r"'Caf\X2\00E9\X0\''s \\'"
|
||||||
|
|
||||||
|
assert ifcopenshell.encode_spf_string(decoded) == encoded
|
||||||
|
assert ifcopenshell.decode_spf_string(encoded) == decoded
|
||||||
|
|
||||||
|
|
||||||
def test_skip_over_non_entity_instance():
|
def test_skip_over_non_entity_instance():
|
||||||
data = """
|
data = """
|
||||||
ISO-10303-21;
|
ISO-10303-21;
|
||||||
|
|||||||
@@ -67,10 +67,6 @@ class IFC_PARSE_API character_decoder {
|
|||||||
std::string get(size_t& offset);
|
std::string get(size_t& offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ifcopenshell
|
|
||||||
|
|
||||||
namespace ifcopenshell {
|
|
||||||
|
|
||||||
class IFC_PARSE_API character_encoder {
|
class IFC_PARSE_API character_encoder {
|
||||||
private:
|
private:
|
||||||
std::u32string str_;
|
std::u32string str_;
|
||||||
@@ -80,6 +76,6 @@ class IFC_PARSE_API character_encoder {
|
|||||||
operator std::string();
|
operator std::string();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace IfcWrite
|
} // namespace ifcopenshell
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -550,6 +550,26 @@ std::string token::to_string() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ifcopenshell::encode_spf_string(const std::string& value) {
|
||||||
|
return character_encoder(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ifcopenshell::decode_spf_string(const std::string& value) {
|
||||||
|
std::string wrapped;
|
||||||
|
auto value_p = &value;
|
||||||
|
if (!value.empty() && value.front() != '\'') {
|
||||||
|
wrapped = "'" + value + "'";
|
||||||
|
value_p = &wrapped;
|
||||||
|
}
|
||||||
|
file_reader<full_buffer_impl> reader(*value_p, caller_fed_tag{});
|
||||||
|
spf_lexer<file_reader<full_buffer_impl>> lexer(&reader);
|
||||||
|
token decoded = lexer.next();
|
||||||
|
if (!decoded.is_string()) {
|
||||||
|
throw exception("Expected an SPF string");
|
||||||
|
}
|
||||||
|
return decoded.as_string();
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template<typename Variant, typename T>
|
template<typename Variant, typename T>
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ extern IFC_PARSE_API const char *IFCOPENSHELL_VERSION;
|
|||||||
|
|
||||||
namespace ifcopenshell {
|
namespace ifcopenshell {
|
||||||
|
|
||||||
|
IFC_PARSE_API std::string encode_spf_string(const std::string& value);
|
||||||
|
|
||||||
|
IFC_PARSE_API std::string decode_spf_string(const std::string& value);
|
||||||
|
|
||||||
/// A stream of tokens to be read from a file_reader.
|
/// A stream of tokens to be read from a file_reader.
|
||||||
template <typename Reader>
|
template <typename Reader>
|
||||||
class IFC_PARSE_API spf_lexer {
|
class IFC_PARSE_API spf_lexer {
|
||||||
|
|||||||
@@ -2,9 +2,19 @@
|
|||||||
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include <ifcparse/file.h>
|
#include <ifcparse/file.h>
|
||||||
|
#include <ifcparse/parse.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
TEST_CASE("SPF strings can be encoded and decoded", "[ifcparse]") {
|
||||||
|
const std::string decoded = "Caf\xC3\xA9" "'s \\";
|
||||||
|
const std::string encoded = R"('Caf\X2\00E9\X0\''s \\')";
|
||||||
|
|
||||||
|
CHECK(ifcopenshell::encode_spf_string(decoded) == encoded);
|
||||||
|
CHECK(ifcopenshell::decode_spf_string(encoded) == decoded);
|
||||||
|
CHECK(ifcopenshell::decode_spf_string(encoded.substr(1, encoded.size() - 2)) == decoded);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("IfcPropertySetDefinitionSet references are resolved without replacing their owner", "[ifcparse]") {
|
TEST_CASE("IfcPropertySetDefinitionSet references are resolved without replacing their owner", "[ifcparse]") {
|
||||||
const std::string fixture = std::string(IFCOPENSHELL_TEST_FIXTURES) + "/ColumnPSetsOfSets.ifc";
|
const std::string fixture = std::string(IFCOPENSHELL_TEST_FIXTURES) + "/ColumnPSetsOfSets.ifc";
|
||||||
ifcopenshell::file file(fixture);
|
ifcopenshell::file file(fixture);
|
||||||
|
|||||||
@@ -962,6 +962,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
%include "../ifcparse/ifc_parse_api.h"
|
%include "../ifcparse/ifc_parse_api.h"
|
||||||
|
|
||||||
|
namespace ifcopenshell {
|
||||||
|
std::string encode_spf_string(const std::string& value);
|
||||||
|
std::string decode_spf_string(const std::string& value);
|
||||||
|
}
|
||||||
|
|
||||||
%include "../ifcparse/spf_header.h"
|
%include "../ifcparse/spf_header.h"
|
||||||
|
|
||||||
%pythoncode %{
|
%pythoncode %{
|
||||||
|
|||||||
Reference in New Issue
Block a user