diff --git a/include/ki/dml/Field.h b/include/ki/dml/Field.h index 3cc028d..31e15c9 100644 --- a/include/ki/dml/Field.h +++ b/include/ki/dml/Field.h @@ -7,18 +7,25 @@ namespace ki namespace dml { template - class Field : public FieldBase + class Field final : public FieldBase { friend Record; public: - ValueT get_value() const; - void set_value(ValueT value); + virtual ~Field() = default; - Field *clone(const Record &record) const; + ValueT get_value() const + { + return m_value; + } - void write_to(std::ostream &ostream) const; - void read_from(std::istream &istream); - size_t get_size() const; + void set_value(ValueT value) + { + m_value = value; + } + + void write_to(std::ostream &ostream) const final; + void read_from(std::istream &istream) final; + size_t get_size() const final; protected: Field(std::string name, const Record &record) : FieldBase(name, record) @@ -28,6 +35,14 @@ namespace dml } private: ValueT m_value; + + Field *clone(const Record &record) const final + { + auto *clone = new Field(m_name, record); + clone->m_transferable = true; + clone->m_value = m_value; + return clone; + } }; typedef Field BytField; diff --git a/include/ki/dml/FieldBase.h b/include/ki/dml/FieldBase.h index 14e9479..6969742 100644 --- a/include/ki/dml/FieldBase.h +++ b/include/ki/dml/FieldBase.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "../util/Serializable.h" namespace ki @@ -14,6 +15,8 @@ namespace dml { friend Record; public: + virtual ~FieldBase() = default; + const Record &get_record() const; std::string get_name() const; bool is_transferable() const; @@ -24,18 +27,15 @@ namespace dml return (typeid(ValueT).hash_code() == m_type_hash); } protected: + std::string m_name; + bool m_transferable; size_t m_type_hash; FieldBase(std::string name, const Record& record); - void set_name(std::string name); - void set_transferable(bool transferable); - virtual FieldBase *clone(const Record &record) const = 0; private: const Record &m_record; - std::string m_name; - bool m_transferable; }; typedef std::vector FieldList; diff --git a/include/ki/dml/Record.h b/include/ki/dml/Record.h index fd34d2b..4cfec78 100644 --- a/include/ki/dml/Record.h +++ b/include/ki/dml/Record.h @@ -6,11 +6,12 @@ namespace ki { namespace dml { - class Record : public util::Serializable + class Record final : public util::Serializable { public: Record(); Record(const Record &record); + virtual ~Record(); bool has_field(std::string name) const; @@ -19,33 +20,35 @@ namespace dml { if (!has_field(name)) return false; - return m_field_map[name]->is_type(); + return m_field_map.at(name)->is_type(); } template - Field &get_field(std::string name) const + Field *get_field(std::string name) const { if (has_field(name)) - return dynamic_cast *>(m_fields[name]); + return dynamic_cast *>(m_field_map.at(name)); return nullptr; } template - Field &add_field(std::string name, bool transferable = true) + Field *add_field(std::string name, bool transferable = true) { + // Does this field already exist? if (has_field(name)) - return nullptr; - Field *field = new Field(name, *this); - auto *base = static_cast(field); - m_fields.push_back(base); - m_field_map.insert({ base->get_name(), base }); + return get_field(name); + + // Create the field + auto *field = new Field(name, *this); + field->m_transferable = transferable; + add_field(field); return field; } size_t get_field_count() const; - FieldList::iterator fields_begin() const; - FieldList::iterator fields_end() const; + FieldList::const_iterator fields_begin() const; + FieldList::const_iterator fields_end() const; void write_to(std::ostream &ostream) const; void read_from(std::istream &istream); @@ -53,6 +56,8 @@ namespace dml private: FieldList m_fields; FieldNameMap m_field_map; + + void add_field(FieldBase *field); }; } } diff --git a/src/dml/FieldBase.cpp b/src/dml/FieldBase.cpp index e69de29..2593bdc 100644 --- a/src/dml/FieldBase.cpp +++ b/src/dml/FieldBase.cpp @@ -0,0 +1,30 @@ +#include "ki/dml/FieldBase.h" + +namespace ki +{ +namespace dml +{ + FieldBase::FieldBase(std::string name, const Record& record) + : m_record(record) + { + m_name = name; + m_transferable = true; + m_type_hash = 0; + } + + const Record &FieldBase::get_record() const + { + return m_record; + } + + std::string FieldBase::get_name() const + { + return m_name; + } + + bool FieldBase::is_transferable() const + { + return m_transferable; + } +} +} diff --git a/src/dml/Record.cpp b/src/dml/Record.cpp index e69de29..a5a9771 100644 --- a/src/dml/Record.cpp +++ b/src/dml/Record.cpp @@ -0,0 +1,73 @@ +#include "ki/dml/Record.h" + +namespace ki +{ +namespace dml +{ + Record::Record() + { + m_fields = FieldList(); + m_field_map = FieldNameMap(); + } + + Record::~Record() + { + m_fields.clear(); + m_field_map.clear(); + for (auto it = m_fields.begin(); it != m_fields.end(); ++it) + delete *it; + } + + Record::Record(const Record& record) + { + for (auto it = record.fields_begin(); it != record.fields_end(); ++it) + add_field((*it)->clone(*this)); + } + + bool Record::has_field(std::string name) const + { + return m_field_map.count(name); + } + + size_t Record::get_field_count() const + { + return m_fields.size(); + } + + FieldList::const_iterator Record::fields_begin() const + { + return m_fields.begin(); + } + + FieldList::const_iterator Record::fields_end() const + { + return m_fields.end(); + } + + void Record::write_to(std::ostream &ostream) const + { + for (auto it = m_fields.begin(); it != m_fields.end(); ++it) + (*it)->write_to(ostream); + } + + void Record::read_from(std::istream &istream) + { + for (auto it = m_fields.begin(); it != m_fields.end(); ++it) + (*it)->read_from(istream); + } + + size_t Record::get_size() const + { + size_t size = 0; + for (auto it = m_fields.begin(); it != m_fields.end(); ++it) + size += (*it)->get_size(); + return size; + } + + void Record::add_field(FieldBase* field) + { + m_fields.push_back(field); + m_field_map.insert({ field->get_name(), field }); + } +} +}