From a2c577ce47da8e2370b4ff8db8ec442212ed7645 Mon Sep 17 00:00:00 2001 From: Joshua Scott Date: Thu, 13 Dec 2018 22:12:04 +0000 Subject: [PATCH] etc: Start using smart pointers --- include/ki/pclass/Property.h | 14 ++--- include/ki/pclass/PropertyList.h | 6 +-- include/ki/pclass/StaticProperty.h | 22 ++++---- include/ki/pclass/TypeSystem.h | 34 +++++++----- include/ki/pclass/VectorProperty.h | 31 ++++++----- include/ki/pclass/types/ClassType.h | 10 ++-- include/ki/pclass/types/EnumType.h | 5 +- .../pclass/types/FloatingPointPrimitiveType.h | 6 +-- include/ki/pclass/types/Type.h | 8 +-- include/ki/serialization/SerializerBinary.h | 48 +++++++++++++++-- include/ki/util/BitStream.h | 12 +++-- include/ki/util/unique.h | 16 ++++++ src/pclass/Property.cpp | 2 +- src/pclass/Type.cpp | 2 +- src/pclass/TypeSystem.cpp | 32 +++-------- src/serialization/SerializerBinary.cpp | 54 +++++++++---------- src/util/BitStream.cpp | 11 ++-- test/src/unit-bitstream.cpp | 9 ++-- test/src/unit-serialization.cpp | 34 ++++++------ 19 files changed, 208 insertions(+), 148 deletions(-) create mode 100644 include/ki/util/unique.h diff --git a/include/ki/pclass/Property.h b/include/ki/pclass/Property.h index fa8141e..e34fb6e 100644 --- a/include/ki/pclass/Property.h +++ b/include/ki/pclass/Property.h @@ -19,11 +19,11 @@ namespace pclass IProperty(PropertyClass &object, const std::string &name, const Type &type); - virtual ~IProperty() {} - IProperty(PropertyClass &object, const IProperty &that); + virtual ~IProperty() {} + const PropertyClass &get_instance() const; std::string get_name() const; hash_t get_name_hash() const; @@ -35,7 +35,7 @@ namespace pclass virtual Value get_value() const = 0; virtual const PropertyClass *get_object() const = 0; - virtual void set_object(PropertyClass *object) = 0; + virtual void set_object(std::unique_ptr &object) = 0; virtual void write_value_to(BitStream &stream) const = 0; virtual void read_value_from(BitStream &stream) = 0; @@ -60,24 +60,24 @@ namespace pclass IDynamicProperty(PropertyClass &object, const std::string &name, const Type &type); - virtual ~IDynamicProperty() {} - IDynamicProperty(PropertyClass &object, const IDynamicProperty &that); + virtual ~IDynamicProperty() {} + bool is_dynamic() const override; virtual std::size_t get_element_count() const = 0; virtual void set_element_count(std::size_t size) = 0; Value get_value() const final override; const PropertyClass *get_object() const final override; - void set_object(PropertyClass *object) final override; + void set_object(std::unique_ptr &object) final override; void write_value_to(BitStream &stream) const final override; void read_value_from(BitStream &stream) final override; virtual Value get_value(int index) const = 0; virtual const PropertyClass *get_object(int index) const = 0; - virtual void set_object(PropertyClass *object, int index) = 0; + virtual void set_object(std::unique_ptr &object, int index) = 0; virtual void write_value_to(BitStream &stream, int index) const = 0; virtual void read_value_from(BitStream &stream, int index) = 0; }; diff --git a/include/ki/pclass/PropertyList.h b/include/ki/pclass/PropertyList.h index 63e0524..79e94d5 100644 --- a/include/ki/pclass/PropertyList.h +++ b/include/ki/pclass/PropertyList.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include "ki/pclass/HashCalculator.h" @@ -84,8 +84,8 @@ namespace pclass private: std::vector m_properties; - std::map m_property_name_lookup; - std::map m_property_hash_lookup; + std::unordered_map m_property_name_lookup; + std::unordered_map m_property_hash_lookup; void add_property(IProperty &prop); }; diff --git a/include/ki/pclass/StaticProperty.h b/include/ki/pclass/StaticProperty.h index 112ef44..2981cbb 100644 --- a/include/ki/pclass/StaticProperty.h +++ b/include/ki/pclass/StaticProperty.h @@ -45,7 +45,8 @@ namespace pclass ); } - static void set_object(StaticProperty &prop, PropertyClass *object) + static void set_object(StaticProperty &prop, + std::unique_ptr &object) { // ValueT does not derive from PropertyClass, and so, this property is not // storing an object. @@ -101,7 +102,8 @@ namespace pclass ); } - static void set_object(StaticProperty &prop, PropertyClass *object) + static void set_object(StaticProperty &prop, + std::unique_ptr &object) { // ValueT does not derive from PropertyClass, and so, this property is not // storing an object. @@ -158,7 +160,8 @@ namespace pclass return dynamic_cast(prop.m_value); } - static void set_object(StaticProperty &prop, PropertyClass *object) + static void set_object(StaticProperty &prop, + std::unique_ptr &object) { // Ensure that object inherits the type of the property if (object) @@ -166,7 +169,7 @@ namespace pclass // ValueT does derive from PropertyClass, and we have a pointer to an instance // of PropertyClass, so cast the pointer up to a ValueT. - prop.m_value = dynamic_cast(object); + prop.m_value = dynamic_cast(object.release()); } }; @@ -220,7 +223,8 @@ namespace pclass return dynamic_cast(&prop.m_value); } - static void set_object(StaticProperty &prop, PropertyClass *object) + static void set_object(StaticProperty &prop, + std::unique_ptr &object) { // Ensure that object is not nullptr if (!object) @@ -231,8 +235,7 @@ namespace pclass // ValueT does derive from PropertyClass, but we don't store a pointer, // so we need to copy the value in. - prop.m_value = *dynamic_cast(object); - delete object; + prop.m_value = *dynamic_cast(object.get()); } }; @@ -315,7 +318,8 @@ namespace pclass return value_object_helper::get_object(prop); } - static void set_object(StaticProperty &prop, PropertyClass *object) + static void set_object(StaticProperty &prop, + std::unique_ptr &object) { value_object_helper::set_object(prop, object); } @@ -385,7 +389,7 @@ namespace pclass return value_helper::get_object(*this); } - void set_object(PropertyClass *object) override + void set_object(std::unique_ptr &object) override { return value_helper::set_object(*this, object); } diff --git a/include/ki/pclass/TypeSystem.h b/include/ki/pclass/TypeSystem.h index a167ed1..c1f60f3 100644 --- a/include/ki/pclass/TypeSystem.h +++ b/include/ki/pclass/TypeSystem.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include "ki/pclass/HashCalculator.h" #include "ki/pclass/types/Type.h" #include "ki/pclass/types/PrimitiveType.h" @@ -17,8 +17,7 @@ namespace pclass class TypeSystem { public: - explicit TypeSystem(HashCalculator *hash_calculator); - ~TypeSystem(); + explicit TypeSystem(std::unique_ptr &hash_calculator); const HashCalculator &get_hash_calculator() const; @@ -32,7 +31,9 @@ namespace pclass PrimitiveType &define_primitive(const std::string &name) { auto *type = new PrimitiveType(name, *this); - define_type(type); + define_type(std::unique_ptr( + dynamic_cast(type) + )); return *type; } @@ -53,25 +54,30 @@ namespace pclass CppEnumType &define_enum(const std::string &name) { auto *type = new CppEnumType(name, *this); - define_type(type); + define_type(std::unique_ptr( + dynamic_cast(type) + )); return *type; } template - ClassT *instantiate(const std::string &name) const + std::unique_ptr instantiate(const std::string &name) const { const auto &type = get_type(name); - return dynamic_cast(type.instantiate()); + auto object = type.instantiate(); + return std::unique_ptr( + dynamic_cast(object.release()) + ); } protected: - void define_type(Type *type); + void define_type(std::unique_ptr type); private: - TypeList m_types; - TypeNameMap m_type_name_lookup; - TypeHashMap m_type_hash_lookup; - HashCalculator *m_hash_calculator; + std::vector> m_types; + std::unordered_map m_type_name_lookup; + std::unordered_map m_type_hash_lookup; + std::unique_ptr m_hash_calculator; template ClassType &define_class( @@ -83,7 +89,9 @@ namespace pclass base_class = &get_type("class PropertyClass"); auto *type = new ClassType(name, base_class, *this); - define_type(type); + define_type(std::unique_ptr( + dynamic_cast(type) + )); return *type; } }; diff --git a/include/ki/pclass/VectorProperty.h b/include/ki/pclass/VectorProperty.h index 588d9a3..14373f8 100644 --- a/include/ki/pclass/VectorProperty.h +++ b/include/ki/pclass/VectorProperty.h @@ -43,7 +43,8 @@ namespace pclass ); } - static void set_object(VectorProperty &prop, PropertyClass *object, const int index) + static void set_object(VectorProperty &prop, + std::unique_ptr &object, const int index) { // ValueT does not derive from PropertyClass, and so, this property is not // storing an object. @@ -90,7 +91,8 @@ namespace pclass ); } - static void set_object(VectorProperty &prop, PropertyClass *object, const int index) + static void set_object(VectorProperty &prop, + std::unique_ptr &object, const int index) { // ValueT does not derive from PropertyClass, and so, this property is not // storing an object. @@ -135,7 +137,8 @@ namespace pclass return dynamic_cast(prop.at(index)); } - static void set_object(VectorProperty &prop, PropertyClass *object, const int index) + static void set_object(VectorProperty &prop, + std::unique_ptr &object, const int index) { // Ensure index is within bounds if (index < 0 || index >= prop.size()) @@ -147,7 +150,7 @@ namespace pclass // ValueT does derive from PropertyClass, and we have a pointer to an instance // of PropertyClass, so cast the pointer up to a ValueT. - prop.at(index) = dynamic_cast(object); + prop.at(index) = dynamic_cast(object.release()); } }; @@ -193,7 +196,8 @@ namespace pclass return dynamic_cast(&prop.at(index)); } - static void set_object(VectorProperty &prop, PropertyClass *object, const int index) + static void set_object(VectorProperty &prop, + std::unique_ptr &object, const int index) { // Ensure index is within bounds if (index < 0 || index >= prop.size()) @@ -208,8 +212,7 @@ namespace pclass // ValueT does derive from PropertyClass, but we don't store a pointer, // so we need to copy the value in. - prop.at(index) = *dynamic_cast(object); - delete object; + prop.at(index) = *dynamic_cast(object.get()); } }; @@ -291,22 +294,26 @@ namespace pclass return vector_value_object_helper::copy(prop, index); } - static const PropertyClass *get_object(const VectorProperty &prop, const int index) + static const PropertyClass *get_object(const VectorProperty &prop, + const int index) { return vector_value_object_helper::get_object(prop, index); } - static void set_object(VectorProperty &prop, PropertyClass *object, const int index) + static void set_object(VectorProperty &prop, + std::unique_ptr &object, const int index) { vector_value_object_helper::set_object(prop, object, index); } - static void write_value_to(const VectorProperty &prop, BitStream &stream, const int index) + static void write_value_to(const VectorProperty &prop, + BitStream &stream, const int index) { vector_value_rw_helper::write_value_to(prop, stream, index); } - static void read_value_from(VectorProperty &prop, BitStream &stream, const int index) + static void read_value_from(VectorProperty &prop, + BitStream &stream, const int index) { vector_value_rw_helper::read_value_from(prop, stream, index); } @@ -365,7 +372,7 @@ namespace pclass return vector_value_helper::get_object(*this, index); } - void set_object(PropertyClass *object, int index) override + void set_object(std::unique_ptr &object, int index) override { return vector_value_helper::set_object(*this, object, index); } diff --git a/include/ki/pclass/types/ClassType.h b/include/ki/pclass/types/ClassType.h index c99b056..ce78676 100644 --- a/include/ki/pclass/types/ClassType.h +++ b/include/ki/pclass/types/ClassType.h @@ -1,9 +1,10 @@ #pragma once +#include #include #include +#include "ki/pclass/Property.h" #include "ki/pclass/types/Type.h" #include "ki/pclass/PropertyClass.h" -#include "ki/pclass/Property.h" namespace ki { @@ -43,9 +44,12 @@ namespace pclass : IClassType(name, base_class, type_system) {} - PropertyClass *instantiate() const override + std::unique_ptr instantiate() const override { - return new ClassT(*this, get_type_system()); + auto *instance = new ClassT(*this, get_type_system()); + return std::unique_ptr( + dynamic_cast(instance) + ); } void write_to(BitStream &stream, Value value) const override diff --git a/include/ki/pclass/types/EnumType.h b/include/ki/pclass/types/EnumType.h index 1c06c1b..c29e424 100644 --- a/include/ki/pclass/types/EnumType.h +++ b/include/ki/pclass/types/EnumType.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "ki/pclass/types/Type.h" #include "ki/pclass/types/PrimitiveType.h" @@ -47,8 +48,8 @@ namespace pclass private: std::vector m_elements; - std::map m_element_name_lookup; - std::map m_element_value_lookup; + std::unordered_map m_element_name_lookup; + std::unordered_map m_element_value_lookup; }; /** diff --git a/include/ki/pclass/types/FloatingPointPrimitiveType.h b/include/ki/pclass/types/FloatingPointPrimitiveType.h index 018d938..defc58a 100644 --- a/include/ki/pclass/types/FloatingPointPrimitiveType.h +++ b/include/ki/pclass/types/FloatingPointPrimitiveType.h @@ -31,9 +31,9 @@ namespace detail private: /** - * An unsigned integer type with the same size as the floating point type - * ValueT. - */ + * An unsigned integer type with the same size as the floating point type + * ValueT. + */ using uint_type = typename bits::value>::uint_type; }; } diff --git a/include/ki/pclass/types/Type.h b/include/ki/pclass/types/Type.h index be9a232..d9a76f2 100644 --- a/include/ki/pclass/types/Type.h +++ b/include/ki/pclass/types/Type.h @@ -1,7 +1,7 @@ #pragma once +#include #include #include -#include #include "ki/pclass/HashCalculator.h" #include "ki/pclass/Value.h" #include "ki/util/BitStream.h" @@ -47,7 +47,7 @@ namespace pclass kind get_kind() const; const TypeSystem &get_type_system() const; - virtual PropertyClass *instantiate() const; + virtual std::unique_ptr instantiate() const; virtual void write_to(BitStream &stream, Value value) const; virtual Value read_from(BitStream &stream) const; @@ -60,10 +60,6 @@ namespace pclass const TypeSystem &m_type_system; }; - typedef std::vector TypeList; - typedef std::map TypeNameMap; - typedef std::map TypeHashMap; - /** * @param[in] expected The Type that is expected to match with the actual Type. * @param[in] actual The Type that is being checked for a match with the expected Type. diff --git a/include/ki/serialization/SerializerBinary.h b/include/ki/serialization/SerializerBinary.h index 2c02503..d6ca401 100644 --- a/include/ki/serialization/SerializerBinary.h +++ b/include/ki/serialization/SerializerBinary.h @@ -45,16 +45,58 @@ namespace serialization bool is_file, flags flags); virtual ~SerializerBinary() {} + /** + * @param object + * @param stream + */ void save(const pclass::PropertyClass *object, BitStream &stream); - void load(pclass::PropertyClass *&dest, BitStream &stream, std::size_t size); + + /** + * @param dest + * @param stream + * @param size + */ + void load(std::unique_ptr &dest, + BitStream &stream, std::size_t size); protected: + /** + * @param object + * @param stream + */ virtual void presave_object(const pclass::PropertyClass *object, BitStream &stream) const; + + /** + * @param object + * @param stream + */ void save_object(const pclass::PropertyClass *object, BitStream &stream) const; + + /** + * @param prop + * @param stream + */ void save_property(const pclass::IProperty &prop, BitStream &stream) const; - virtual void preload_object(pclass::PropertyClass *&dest, BitStream &stream) const; - void load_object(pclass::PropertyClass *&dest, BitStream &stream) const; + /** + * Read an object header, and instantiate the necessary PropertyClass. + * @param dest + * @param stream + */ + virtual void preload_object( + std::unique_ptr &dest, BitStream &stream) const; + + /** + * @param dest + * @param stream + */ + void load_object( + std::unique_ptr &dest, BitStream &stream) const; + + /** + * @param prop + * @param stream + */ void load_property(pclass::IProperty &prop, BitStream &stream) const; private: diff --git a/include/ki/util/BitStream.h b/include/ki/util/BitStream.h index 23041ef..e31dc08 100644 --- a/include/ki/util/BitStream.h +++ b/include/ki/util/BitStream.h @@ -53,7 +53,7 @@ namespace ki void set_bit(int bit); }; - virtual ~IBitBuffer() {}; + virtual ~IBitBuffer() {} /** * @returns @@ -77,7 +77,9 @@ namespace ki * @param[in] bitsize The size of the segment in bits. * @returns A new segment of this buffer. */ - virtual BitBufferSegment *segment(buffer_pos from, std::size_t bitsize); + virtual std::unique_ptr segment( + buffer_pos from, std::size_t bitsize + ); /** * Reads a value from the buffer. @@ -214,8 +216,10 @@ namespace ki std::size_t size() const override; void resize(std::size_t new_size) override; - uint8_t* data() const override; - BitBufferSegment *segment(buffer_pos from, std::size_t bitsize) override; + uint8_t *data() const override; + std::unique_ptr segment( + buffer_pos from, std::size_t bitsize + ) override; /** * @copydoc IBitBuffer::read(buffer_pos, uint8_t) diff --git a/include/ki/util/unique.h b/include/ki/util/unique.h new file mode 100644 index 0000000..6052b74 --- /dev/null +++ b/include/ki/util/unique.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +#if __cplusplus <= 201103L +namespace ki +{ + template + std::unique_ptr make_unique(Args&&... args) + { + return std::unique_ptr( + new T(std::forward(args)...) + ); + } +} +#endif diff --git a/src/pclass/Property.cpp b/src/pclass/Property.cpp index 9365737..f3877b3 100644 --- a/src/pclass/Property.cpp +++ b/src/pclass/Property.cpp @@ -98,7 +98,7 @@ namespace pclass throw runtime_error("Called get_object() on a dynamic property. Use get_object(index) instead."); } - void IDynamicProperty::set_object(PropertyClass *object) + void IDynamicProperty::set_object(std::unique_ptr &object) { // The caller must specify an index throw runtime_error("Called set_object() on a dynamic property. Use set_object(index) instead."); diff --git a/src/pclass/Type.cpp b/src/pclass/Type.cpp index 4f210b0..da39192 100644 --- a/src/pclass/Type.cpp +++ b/src/pclass/Type.cpp @@ -53,7 +53,7 @@ namespace pclass throw runtime_error(oss.str()); } - PropertyClass *Type::instantiate() const + std::unique_ptr Type::instantiate() const { std::ostringstream oss; oss << "Type '" << m_name << "' does not implement Type::instantiate."; diff --git a/src/pclass/TypeSystem.cpp b/src/pclass/TypeSystem.cpp index ad6e521..25fa154 100644 --- a/src/pclass/TypeSystem.cpp +++ b/src/pclass/TypeSystem.cpp @@ -32,9 +32,9 @@ namespace pclass template <> void define_bit_integer_primitive<0>(TypeSystem &type_system) {} - TypeSystem::TypeSystem(HashCalculator *hash_calculator) + TypeSystem::TypeSystem(std::unique_ptr &hash_calculator) { - m_hash_calculator = hash_calculator; + m_hash_calculator = std::move(hash_calculator); // Pre-define C++ primitive types // Define integer types @@ -74,20 +74,6 @@ namespace pclass define_class("class PropertyClass"); } - TypeSystem::~TypeSystem() - { - // Delete all type declarations - for (auto it = m_types.begin(); it != m_types.end(); ++it) - delete *it; - - // Clear lookups - m_type_name_lookup.clear(); - m_type_hash_lookup.clear(); - - // Delete the hash calculator - delete m_hash_calculator; - } - const HashCalculator &TypeSystem::get_hash_calculator() const { // Make sure the hash calculator isn't null @@ -132,14 +118,11 @@ namespace pclass return *it->second; } - void TypeSystem::define_type(Type *type) + void TypeSystem::define_type(std::unique_ptr type) { // Does a type with this name already exist? if (m_type_name_lookup.find(type->get_name()) != m_type_name_lookup.end()) { - // This pointer will become lost since it isn't being added to the lookups. - delete type; - // Throw an error std::ostringstream oss; oss << "Type '" << type->get_name() << "' is already defined."; @@ -149,9 +132,6 @@ namespace pclass // Does a type with this hash already exist? if (m_type_name_lookup.find(type->get_name()) != m_type_name_lookup.end()) { - // This pointer will become lost since it isn't being added to the lookups. - delete type; - // Throw an error auto &other_type = get_type(type->get_hash()); std::ostringstream oss; @@ -161,9 +141,9 @@ namespace pclass } // This type is safe to add to our lookups - m_types.push_back(type); - m_type_name_lookup[type->get_name()] = type; - m_type_hash_lookup[type->get_hash()] = type; + m_type_name_lookup[type->get_name()] = type.get(); + m_type_hash_lookup[type->get_hash()] = type.get(); + m_types.push_back(std::move(type)); } } } diff --git a/src/serialization/SerializerBinary.cpp b/src/serialization/SerializerBinary.cpp index a01181d..5a0be20 100644 --- a/src/serialization/SerializerBinary.cpp +++ b/src/serialization/SerializerBinary.cpp @@ -1,6 +1,7 @@ #include "ki/serialization/SerializerBinary.h" #include #include +#include "ki/util/unique.h" namespace ki { @@ -235,11 +236,15 @@ namespace serialization } } - void SerializerBinary::load(pclass::PropertyClass *&dest, + void SerializerBinary::load( + std::unique_ptr &dest, BitStream &stream, const std::size_t size) { // Create a new stream that reads a segment of the stream given to us - IBitBuffer *buffer = stream.buffer().segment(stream.tell(), size * 8); + auto segment_buffer = stream.buffer().segment(stream.tell(), size * 8); + auto buffer = std::unique_ptr( + dynamic_cast(segment_buffer.release()) + ); auto segment_stream = BitStream(*buffer); stream.seek(stream.tell() + size * 8, false); @@ -267,21 +272,23 @@ namespace serialization segment_stream.read_copy(compressed.data(), data_available_bytes * 8); // Uncompress the compressed buffer - auto *uncompressed = new BitBuffer(uncompressed_size); + auto uncompressed = ki::make_unique(uncompressed_size); uLong dest_len = uncompressed_size; uncompress(uncompressed->data(), &dest_len, compressed.data(), data_available_bytes); // Delete the old buffer and use the new uncompressed buffer - delete buffer; - buffer = uncompressed; + buffer = std::unique_ptr( + dynamic_cast(uncompressed.release()) + ); } else { // Use a segment of the current buffer as the new buffer - auto *segment_buffer = buffer->segment(segment_stream.tell(), data_available_bytes); - delete buffer; - buffer = segment_buffer; + segment_buffer = buffer->segment(segment_stream.tell(), data_available_bytes); + buffer = std::unique_ptr( + dynamic_cast(segment_buffer.release()) + ); } // Create a new stream to read from the new buffer @@ -289,21 +296,11 @@ namespace serialization } // Load the root object - try - { - load_object(dest, segment_stream); - } - catch (runtime_error &e) - { - delete buffer; - throw e; - } - - // Free resources - delete buffer; + load_object(dest, segment_stream); } - void SerializerBinary::preload_object(pclass::PropertyClass *&dest, BitStream &stream) const + void SerializerBinary::preload_object( + std::unique_ptr &dest, BitStream &stream) const { const auto type_hash = stream.read(); if (type_hash != 0) @@ -317,7 +314,8 @@ namespace serialization dest = nullptr; } - void SerializerBinary::load_object(pclass::PropertyClass *&dest, BitStream &stream) const + void SerializerBinary::load_object( + std::unique_ptr &dest, BitStream &stream) const { // Read the object header preload_object(dest, stream); @@ -333,11 +331,11 @@ namespace serialization // ensure that data is only read from inside this region. const auto object_size = stream.read() - bitsizeof::value; - auto *object_buffer = stream.buffer().segment( + auto object_buffer = stream.buffer().segment( stream.tell(), object_size ); - stream.seek(stream.tell() + object_size, false); auto object_stream = BitStream(*object_buffer); + stream.seek(stream.tell() + object_size, false); // Instead of loading properties sequentially, the file format specifies // the hash of a property before writing its value, so we just need to @@ -349,7 +347,7 @@ namespace serialization // ensure that data is only read from inside this region. const auto property_size = object_stream.read() - bitsizeof::value; - auto *property_buffer = object_buffer->segment( + const auto property_buffer = object_buffer->segment( object_stream.tell(), property_size ); auto property_stream = BitStream(*property_buffer); @@ -360,9 +358,7 @@ namespace serialization const auto property_hash = property_stream.read(); auto &prop = properties.get_property(property_hash); load_property(prop, property_stream); - delete property_buffer; } - delete object_buffer; } else { @@ -402,7 +398,7 @@ namespace serialization if (property_type.get_kind() == pclass::Type::kind::CLASS) { // Read the object as a nested object - pclass::PropertyClass *object = nullptr; + std::unique_ptr object = nullptr; load_object(object, stream); dynamic_property.set_object(object, i); } @@ -421,7 +417,7 @@ namespace serialization if (property_type.get_kind() == pclass::Type::kind::CLASS) { // Read the object as a nested object - pclass::PropertyClass *object = nullptr; + std::unique_ptr object = nullptr; load_object(object, stream); prop.set_object(object); } diff --git a/src/util/BitStream.cpp b/src/util/BitStream.cpp index bdec477..9f8f78e 100644 --- a/src/util/BitStream.cpp +++ b/src/util/BitStream.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "ki/util/unique.h" namespace ki { @@ -141,10 +142,10 @@ namespace ki return copy; } - BitBufferSegment *IBitBuffer::segment( + std::unique_ptr IBitBuffer::segment( const buffer_pos from, const std::size_t bitsize) { - return new BitBufferSegment(*this, from, bitsize); + return ki::make_unique(*this, from, bitsize); } void IBitBuffer::write_copy(uint8_t *src, @@ -329,10 +330,12 @@ namespace ki return &m_buffer->data()[m_from.get_byte()]; } - BitBufferSegment *BitBufferSegment::segment( + std::unique_ptr BitBufferSegment::segment( const buffer_pos from, const std::size_t bitsize) { - return new BitBufferSegment(*m_buffer, m_from + from, bitsize); + return ki::make_unique( + *m_buffer, m_from + from, bitsize + ); } uint64_t BitBufferSegment::read( diff --git a/test/src/unit-bitstream.cpp b/test/src/unit-bitstream.cpp index 4f56500..40ff7fe 100644 --- a/test/src/unit-bitstream.cpp +++ b/test/src/unit-bitstream.cpp @@ -137,21 +137,19 @@ TEST_CASE("BitBuffer Functionality", "[bit-stream]") SECTION("Create valid segment") { - auto *segment = bit_buffer.segment( + auto segment = bit_buffer.segment( BitBuffer::buffer_pos(0, 0), 8 ); REQUIRE(segment->size() == 1); - delete segment; } SECTION("Create invalid segment (invalid position)") { try { - auto *segment = bit_buffer.segment( + auto segment = bit_buffer.segment( BitBuffer::buffer_pos(1, 0), 8 ); - delete segment; FAIL(); } catch (runtime_error &e) @@ -164,10 +162,9 @@ TEST_CASE("BitBuffer Functionality", "[bit-stream]") { try { - auto *segment = bit_buffer.segment( + auto segment = bit_buffer.segment( BitBuffer::buffer_pos(0, 0), 16 ); - delete segment; FAIL(); } catch (runtime_error &e) diff --git a/test/src/unit-serialization.cpp b/test/src/unit-serialization.cpp index 738a409..3e41649 100644 --- a/test/src/unit-serialization.cpp +++ b/test/src/unit-serialization.cpp @@ -8,6 +8,7 @@ #include #include #include +#include "ki/util/unique.h" using namespace ki; @@ -256,8 +257,9 @@ public: }; // Setup a global TypeSystem instance -auto *g_hash_calculator = new pclass::WizardHashCalculator(); -pclass::TypeSystem *g_type_system = new pclass::TypeSystem(g_hash_calculator); +std::unique_ptr g_hash_calculator + = ki::make_unique(); +auto g_type_system = ki::make_unique(g_hash_calculator); bool g_types_defined = false; /** @@ -337,13 +339,13 @@ void configure_test_object(TestObject &object) // Configure nested objects object.value_object.get().extra_value = EXPECTED_value_object_extra_value; - object.not_null_object = g_type_system->instantiate("class NestedTestObject"); + object.not_null_object = g_type_system->instantiate("class NestedTestObject").release(); object.null_object = nullptr; object.objects.push_back( - g_type_system->instantiate("class NestedTestObjectA") + g_type_system->instantiate("class NestedTestObjectA").release() ); object.objects.push_back( - g_type_system->instantiate("class NestedTestObjectB") + g_type_system->instantiate("class NestedTestObjectB").release() ); } @@ -395,7 +397,7 @@ void validate_test_object(TestObject &object) * Conduct save/load tests with a SerializerBinary instance. */ void test_serializer( - TestObject *&test_object, + std::unique_ptr &test_object, serialization::SerializerBinary &serializer, const std::string &file_suffix) { @@ -425,12 +427,11 @@ void test_serializer( // Create a test object, configure it, and write it to our stream test_object = g_type_system->instantiate("class TestObject"); configure_test_object(*test_object); - serializer.save(test_object, stream); + serializer.save(test_object.get(), stream); const auto end_pos = stream.tell(); // Delete the test object here so that it is not // unnecessarily validated by the caller - delete test_object; test_object = nullptr; // Validate the contents of the stream @@ -452,12 +453,14 @@ void test_serializer( stream.seek(start_pos); // Load an object from the bit stream's contents - pclass::PropertyClass *object = nullptr; + std::unique_ptr object = nullptr; serializer.load(object, stream, sample_size); // Set test_object so that it is validated by the caller REQUIRE(object != nullptr); - test_object = dynamic_cast(object); + test_object = std::unique_ptr( + dynamic_cast(object.release()) + ); REQUIRE(test_object != nullptr); } @@ -467,7 +470,7 @@ void test_serializer( TEST_CASE("Serialization tests", "[serialization]") { - TestObject *test_object = nullptr; + std::unique_ptr test_object = nullptr; define_types(); SECTION("SerializerBinary") @@ -475,7 +478,7 @@ TEST_CASE("Serialization tests", "[serialization]") SECTION("Regular format without compression") { serialization::SerializerBinary serializer( - *g_type_system, false, + *g_type_system.get(), false, serialization::SerializerBinary::flags::NONE ); test_serializer(test_object, serializer, "_regular"); @@ -483,7 +486,7 @@ TEST_CASE("Serialization tests", "[serialization]") SECTION("File format without compression") { serialization::SerializerBinary serializer( - *g_type_system, true, + *g_type_system.get(), true, serialization::SerializerBinary::flags::WRITE_SERIALIZER_FLAGS ); test_serializer(test_object, serializer, "_file"); @@ -491,7 +494,7 @@ TEST_CASE("Serialization tests", "[serialization]") SECTION("Regular format with compression") { serialization::SerializerBinary serializer( - *g_type_system, false, + *g_type_system.get(), false, serialization::SerializerBinary::flags::COMPRESSED ); test_serializer(test_object, serializer, "_regular_compressed"); @@ -499,7 +502,7 @@ TEST_CASE("Serialization tests", "[serialization]") SECTION("File format with compression") { serialization::SerializerBinary serializer( - *g_type_system, true, + *g_type_system.get(), true, serialization::SerializerBinary::flags::WRITE_SERIALIZER_FLAGS | serialization::SerializerBinary::flags::COMPRESSED ); @@ -512,7 +515,6 @@ TEST_CASE("Serialization tests", "[serialization]") if (test_object) { validate_test_object(*test_object); - delete test_object; test_object = nullptr; } }