From 6518148b5068eba87840e4e10fe8565dda5fddf6 Mon Sep 17 00:00:00 2001 From: pythonology Date: Thu, 4 Jul 2019 00:15:41 -0400 Subject: [PATCH] pclass: Rename Type::is_byte_based -> Type::is_byte_aligned Also introduced the Type::cast convenience method. This is primarily to fix type casting over in kipy when deserializing XML values. This was necessary since properties in kipy are not type-aware, and as such couldn't determine if the value was actually a string, or meant to be casted to something else. --- include/ki/pclass/PrimitiveType.h | 25 +++++++++++++++---------- include/ki/pclass/Type.h | 10 ++++++++-- src/pclass/Type.cpp | 9 ++++++++- src/serialization/BinarySerializer.cpp | 8 ++++---- test/src/unit-serialization.cpp | 2 +- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/include/ki/pclass/PrimitiveType.h b/include/ki/pclass/PrimitiveType.h index f327b69..c4ff62c 100644 --- a/include/ki/pclass/PrimitiveType.h +++ b/include/ki/pclass/PrimitiveType.h @@ -8,18 +8,18 @@ namespace pclass namespace detail { /** - * Provides implementations to PrimitiveType::is_byte_based, + * Provides implementations to PrimitiveType::is_byte_aligned, * PrimitiveType::write_to, and PrimitiveType::read_from. */ template struct primitive_type_helper { - static bool is_byte_based() + static bool is_byte_aligned() { // Provide a compiler error if this is not specialized static_assert( sizeof(ValueT) == 0, - "Missing specialization of primitive_type_helper::is_byte_based" + "Missing specialization of primitive_type_helper::is_byte_aligned" ); } @@ -51,7 +51,7 @@ namespace pclass typename std::enable_if::value>::type > { - static bool is_byte_based() + static bool is_byte_aligned() { return true; } @@ -79,7 +79,7 @@ namespace pclass using type = ki::BitInteger; public: - static bool is_byte_based() + static bool is_byte_aligned() { return false; } @@ -107,7 +107,7 @@ namespace pclass using underlying_type = ki::BitInteger<1, true>; public: - static bool is_byte_based() + static bool is_byte_aligned() { return false; } @@ -142,7 +142,7 @@ namespace pclass using uint_type = typename bits::value>::uint_type; public: - static bool is_byte_based() + static bool is_byte_aligned() { return true; } @@ -177,7 +177,7 @@ namespace pclass using type = std::basic_string<_Elem, _Traits, _Alloc>; public: - static bool is_byte_based() + static bool is_byte_aligned() { return true; } @@ -250,9 +250,14 @@ namespace pclass } ~PrimitiveType() = default; - bool is_byte_based() const override + bool is_byte_aligned() const override { - return detail::primitive_type_helper::is_byte_based(); + return detail::primitive_type_helper::is_byte_aligned(); + } + + Value cast(Value &value) const override + { + return value.as(); } void write_to(BitStream &stream, const bool is_file, Value &value) const override diff --git a/include/ki/pclass/Type.h b/include/ki/pclass/Type.h index b82a12d..df91c29 100644 --- a/include/ki/pclass/Type.h +++ b/include/ki/pclass/Type.h @@ -56,15 +56,21 @@ namespace pclass Kind get_kind() const; /** - * @returns Whether or not this type works in bytes, rather than bits. + * @returns Whether or not this type should be byte aligned. */ - virtual bool is_byte_based() const; + virtual bool is_byte_aligned() const; /** * The TypeSystem used to define this Type instance. */ const TypeSystem &get_type_system() const; + /** + * Casts the provided value to this type. + * @returns A new Value instance that has been casted to this type. + */ + virtual Value cast(Value &value) const; + /** * Create an instance of the type being represented. * @returns A pointer to a new PropertyClass instance. diff --git a/src/pclass/Type.cpp b/src/pclass/Type.cpp index 1e8443f..943973e 100644 --- a/src/pclass/Type.cpp +++ b/src/pclass/Type.cpp @@ -38,11 +38,18 @@ namespace pclass return m_type_system; } - bool Type::is_byte_based() const + bool Type::is_byte_aligned() const { return true; } + Value Type::cast(Value &value) const + { + std::ostringstream oss; + oss << "Type '" << m_name << "' does not implement Type::cast."; + throw runtime_error(oss.str()); + } + void Type::write_to(BitStream &stream, const bool is_file, Value &value) const { std::ostringstream oss; diff --git a/src/serialization/BinarySerializer.cpp b/src/serialization/BinarySerializer.cpp index d16c5ac..d9ea869 100644 --- a/src/serialization/BinarySerializer.cpp +++ b/src/serialization/BinarySerializer.cpp @@ -201,8 +201,8 @@ namespace serialization for (auto i = 0; i < prop.get_element_count(); ++i) { - // Realign the stream if this property works in bytes - if (prop.get_type().is_byte_based()) + // Realign the stream if necessary + if (prop.get_type().is_byte_aligned()) stream.realign(); if (prop.is_pointer() @@ -407,8 +407,8 @@ namespace serialization for (auto i = 0; i < prop.get_element_count(); ++i) { - // Realign the stream if this property works in bytes - if (prop.get_type().is_byte_based()) + // Realign the stream if necessary + if (prop.get_type().is_byte_aligned()) stream.realign(); if (prop.is_pointer() && diff --git a/test/src/unit-serialization.cpp b/test/src/unit-serialization.cpp index 7f1aa05..e7c13c5 100644 --- a/test/src/unit-serialization.cpp +++ b/test/src/unit-serialization.cpp @@ -93,7 +93,7 @@ namespace detail template <> struct primitive_type_helper { - static bool is_byte_based() + static bool is_byte_aligned() { return true; }