diff --git a/CMakeLists.txt b/CMakeLists.txt index f7d36a3..0287b50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,10 +8,14 @@ set_target_properties(${PROJECT_NAME} CXX_STANDARD 11 ) target_include_directories(${PROJECT_NAME} - PUBLIC + PRIVATE + ${PROJECT_SOURCE_DIR}/include + INTERFACE ${PROJECT_SOURCE_DIR}/include ) +add_subdirectory("src/dml") + option(KI_BUILD_EXAMPLES "Determines whether to build examples." ON) if (KI_BUILD_EXAMPLES) add_subdirectory("examples") diff --git a/include/ki/dml/Field.h b/include/ki/dml/Field.h new file mode 100644 index 0000000..3cc028d --- /dev/null +++ b/include/ki/dml/Field.h @@ -0,0 +1,45 @@ +#pragma once +#include "FieldBase.h" +#include "types.h" + +namespace ki +{ +namespace dml +{ + template + class Field : public FieldBase + { + friend Record; + public: + ValueT get_value() const; + void set_value(ValueT value); + + Field *clone(const Record &record) const; + + void write_to(std::ostream &ostream) const; + void read_from(std::istream &istream); + size_t get_size() const; + protected: + Field(std::string name, const Record &record) + : FieldBase(name, record) + { + m_type_hash = typeid(ValueT).hash_code(); + m_value = ValueT(); + } + private: + ValueT m_value; + }; + + typedef Field BytField; + typedef Field UBytField; + typedef Field ShrtField; + typedef Field UShrtField; + typedef Field IntField; + typedef Field UIntField; + typedef Field StrField; + typedef Field WStrField; + typedef Field FltField; + typedef Field DblField; + typedef Field GidField; +} +} diff --git a/include/ki/dml/FieldBase.h b/include/ki/dml/FieldBase.h new file mode 100644 index 0000000..14e9479 --- /dev/null +++ b/include/ki/dml/FieldBase.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include +#include "../util/Serializable.h" + +namespace ki +{ +namespace dml +{ + class Record; + + class FieldBase : public util::Serializable + { + friend Record; + public: + const Record &get_record() const; + std::string get_name() const; + bool is_transferable() const; + + template + bool is_type() const + { + return (typeid(ValueT).hash_code() == m_type_hash); + } + protected: + 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; + typedef std::map FieldNameMap; +} +} diff --git a/include/ki/dml/Record.h b/include/ki/dml/Record.h new file mode 100644 index 0000000..fd34d2b --- /dev/null +++ b/include/ki/dml/Record.h @@ -0,0 +1,58 @@ +#pragma once +#include "FieldBase.h" +#include "Field.h" + +namespace ki +{ +namespace dml +{ + class Record : public util::Serializable + { + public: + Record(); + Record(const Record &record); + + bool has_field(std::string name) const; + + template + bool has_field(std::string name) const + { + if (!has_field(name)) + return false; + return m_field_map[name]->is_type(); + } + + template + Field &get_field(std::string name) const + { + if (has_field(name)) + return dynamic_cast *>(m_fields[name]); + return nullptr; + } + + template + Field &add_field(std::string name, bool transferable = true) + { + 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 field; + } + + size_t get_field_count() const; + + FieldList::iterator fields_begin() const; + FieldList::iterator fields_end() const; + + void write_to(std::ostream &ostream) const; + void read_from(std::istream &istream); + size_t get_size() const; + private: + FieldList m_fields; + FieldNameMap m_field_map; + }; +} +} diff --git a/include/ki/dml/types.h b/include/ki/dml/types.h new file mode 100644 index 0000000..de40b1e --- /dev/null +++ b/include/ki/dml/types.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include + +namespace ki +{ +namespace dml +{ + typedef int8_t BYT; + typedef uint8_t UBYT; + typedef int16_t SHRT; + typedef uint16_t USHRT; + typedef int32_t INT; + typedef uint32_t UINT; + typedef std::string STR; + typedef std::wstring WSTR; + typedef float FLT; + typedef double DBL; + typedef uint64_t GID; +} +} diff --git a/include/ki/util/Serializable.h b/include/ki/util/Serializable.h new file mode 100644 index 0000000..0fe5bd2 --- /dev/null +++ b/include/ki/util/Serializable.h @@ -0,0 +1,16 @@ +#pragma once +#include + +namespace ki +{ +namespace util +{ + class Serializable + { + public: + virtual void write_to(std::ostream &ostream) const = 0; + virtual void read_from(std::istream &istream) = 0; + virtual size_t get_size() const = 0; + }; +} +} diff --git a/src/dml/CMakeLists.txt b/src/dml/CMakeLists.txt new file mode 100644 index 0000000..7a9dd80 --- /dev/null +++ b/src/dml/CMakeLists.txt @@ -0,0 +1,16 @@ +target_sources(${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCE_DIR}/src/dml/FieldBase.cpp + ${PROJECT_SOURCE_DIR}/src/dml/Record.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/BytField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/UBytField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/ShrtField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/UShrtField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/IntField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/UIntField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/StrField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/WStrField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/FltField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/DblField.cpp + ${PROJECT_SOURCE_DIR}/src/dml/types/GidField.cpp +) \ No newline at end of file diff --git a/src/dml/FieldBase.cpp b/src/dml/FieldBase.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/Record.cpp b/src/dml/Record.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/BytField.cpp b/src/dml/types/BytField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/DblField.cpp b/src/dml/types/DblField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/FltField.cpp b/src/dml/types/FltField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/GidField.cpp b/src/dml/types/GidField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/IntField.cpp b/src/dml/types/IntField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/ShrtField.cpp b/src/dml/types/ShrtField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/StrField.cpp b/src/dml/types/StrField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/UBytField.cpp b/src/dml/types/UBytField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/UIntField.cpp b/src/dml/types/UIntField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/UShrtField.cpp b/src/dml/types/UShrtField.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dml/types/WStrField.cpp b/src/dml/types/WStrField.cpp new file mode 100644 index 0000000..e69de29