diff --git a/CMakeLists.txt b/CMakeLists.txt index f069b95..e0803db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,13 +167,20 @@ set(EHS_SOURCES include/ehs/io/Usb_LNX.h src/io/Usb_LNX.cpp include/ehs/db/DbType.h - src/db/DbType.cpp include/ehs/db/DbTable.h include/ehs/db/DbObject.h include/ehs/db/DbVar.h src/db/DbVar.cpp include/ehs/db/Database.h src/db/DbObject.cpp + src/db/Database.cpp + src/db/Database.cpp + src/db/DbTable.cpp + include/ehs/io/BaseDirectory.h + src/io/BaseDirectory.cpp + include/ehs/io/Directory_LNX.h + src/io/Directory_LNX.cpp + include/ehs/io/Directory.h ) if (IS_OS_WINDOWS) diff --git a/include/ehs/Serializer.h b/include/ehs/Serializer.h index 8b08255..85305ba 100644 --- a/include/ehs/Serializer.h +++ b/include/ehs/Serializer.h @@ -1044,7 +1044,10 @@ namespace ehs void ReadArray(T* const value, O* const size) { if (!*size) - *size = (O)Read(); + { + *size = (O)Read(); + return; + } for (N i = 0; i < *size; ++i) value[i] = Read(); diff --git a/include/ehs/db/Database.h b/include/ehs/db/Database.h index 3e1958c..dd60199 100644 --- a/include/ehs/db/Database.h +++ b/include/ehs/db/Database.h @@ -10,27 +10,44 @@ namespace ehs private: UInt_64 hashId; Str_8 id; + Version version; Array tables; public: Database(); + Database(Str_8 id, const Version& version); + Database(const Str_8& filePath); + Database(Database&& db) noexcept; + + Database(const Database& db); + + Database& operator=(Database&& db) noexcept; + + Database& operator=(const Database& db); + UInt_64 GetHashId() const; + void SetId(Str_8 newId); + Str_8 GetId() const; + void SetVersion(const Version& newVersion); + + Version GetVersion() const; + bool HasTable(UInt_64 hashId) const; - bool HasTable(Str_8& id) const; + bool HasTable(const Str_8& id) const; - bool CreateTable(Str_8 id); + DbTable* CreateTable(Str_8 id); DbTable* GetTable(UInt_64 hashId) const; - DbTable* GetTable(Str_8& id) const; + DbTable* GetTable(const Str_8& id) const; - void Save(); + void Save(const Str_8& directory) const; }; } \ No newline at end of file diff --git a/include/ehs/db/DbObject.h b/include/ehs/db/DbObject.h index 5d0c84a..2a52825 100644 --- a/include/ehs/db/DbObject.h +++ b/include/ehs/db/DbObject.h @@ -11,15 +11,17 @@ namespace ehs { private: friend class DbTable; + friend class DbVar; UInt_64 id; - Array vars; - bool loaded; DbTable* parent; + Array vars; public: DbObject(); + DbObject(UInt_64 id); + DbObject(DbObject&& obj) noexcept; DbObject(const DbObject& obj); @@ -28,13 +30,13 @@ namespace ehs DbObject& operator=(const DbObject& obj); - UInt_64 GetId(); + UInt_64 GetId() const; - bool HasVariable(UInt_64 hashId); + bool HasVariable(UInt_64 hashId) const; DbVar* GetVariable(UInt_64 hashId) const; - void Save(); + void Save() const; void Load(); @@ -42,6 +44,7 @@ namespace ehs void Free(); - DbTable* GetParent() const; + private: + void CreateVariable(DbVarTmpl* master); }; } \ No newline at end of file diff --git a/include/ehs/db/DbTable.h b/include/ehs/db/DbTable.h index e5696af..5a436f2 100644 --- a/include/ehs/db/DbTable.h +++ b/include/ehs/db/DbTable.h @@ -4,33 +4,55 @@ #include "ehs/Array.h" #include "DbVarTmpl.h" #include "DbObject.h" +#include "ehs/Serializer.h" namespace ehs { class DbTable { private: + friend class Database; + friend class DbVar; + UInt_64 hashId; Str_8 id; - Version version; Array varTmpls; Array objects; public: DbTable(); - DbTable(); + DbTable(Str_8 id); + + DbTable(DbTable&& table) noexcept; + + DbTable(const DbTable& table); + + DbTable& operator=(DbTable&& table) noexcept; + + DbTable& operator=(const DbTable& table); UInt_64 GetHashId() const; + void SetId(Str_8 newId); + Str_8 GetId() const; - Version GetVersion() const; + bool HasVariable(UInt_64 hashId) const; - bool CreateVariable(Str_8 id, DbType type); + bool HasVariable(const Str_8& id) const; - bool CreateVariable(Str_8 id, DbType type, UInt_64 size); + bool CreateVariable(Str_8 id, DbType type, const Byte* defaultValue); - void Save(); + bool CreateVariable(Str_8 id, DbType type, UInt_64 size, const Byte* defaultValue); + + DbObject *CreateObject(); + + private: + DbVarTmpl* GetVariableTemplate(UInt_64 hashId) const; + + void Serialize(Serializer& data) const; + + void Deserialize(Serializer& data); }; } diff --git a/include/ehs/db/DbType.h b/include/ehs/db/DbType.h index 76096cd..e871b8c 100644 --- a/include/ehs/db/DbType.h +++ b/include/ehs/db/DbType.h @@ -22,5 +22,40 @@ namespace ehs CHAR_8 }; - constexpr UInt_8 DbTypeToSize(DbType type); + constexpr UInt_8 DbTypeToSize(const DbType type) + { + switch (type) + { + case DbType::SINT_64: + return 8; + case DbType::UINT_64: + return 8; + case DbType::SINT_32: + return 4; + case DbType::UINT_32: + return 4; + case DbType::SINT_16: + return 2; + case DbType::UINT_16: + return 2; + case DbType::SINT_8: + return 1; + case DbType::UINT_8: + return 1; + case DbType::FLOAT: + return 4; + case DbType::DOUBLE: + return 8; + case DbType::BOOLEAN: + return 1; + case DbType::CHAR_32: + return 4; + case DbType::CHAR_16: + return 2; + case DbType::CHAR_8: + return 1; + default: + return 0; + } + } } diff --git a/include/ehs/db/DbVar.h b/include/ehs/db/DbVar.h index eb0e57d..5d3b8ae 100644 --- a/include/ehs/db/DbVar.h +++ b/include/ehs/db/DbVar.h @@ -1,37 +1,56 @@ #pragma once #include "ehs/Types.h" +#include "DbType.h" +#include "ehs/Serializer.h" namespace ehs { + class DbVarTmpl; + class DbObject; + class DbVar { private: + friend class DbObject; + friend class DbVarTmpl; + UInt_64 hashId; + DbObject *parent; + DbVarTmpl *master; UInt_64 size; - Byte* data; + Byte *data; public: ~DbVar(); DbVar(); - DbVar(UInt_64 hashId, UInt_64 size, Byte* data); + DbVar(UInt_64 hashId, DbVarTmpl *master, UInt_64 size, const Byte *data); - DbVar(DbVar&& var) noexcept; + DbVar(DbVar &&var) noexcept; - DbVar(const DbVar& var); + DbVar(const DbVar &var); - DbVar& operator=(DbVar&& var) noexcept; + DbVar &operator=(DbVar &&var) noexcept; - DbVar& operator=(const DbVar& var); + DbVar &operator=(const DbVar &var); - explicit operator Byte*() const; + explicit operator Byte *() const; UInt_64 GetHashId() const; UInt_64 GetSize() const; + void SetData(UInt_64 newSize, const Byte* newData); + + void SetData(const Byte* newData); + Byte* GetData() const; + + private: + void Serialize(Serializer &data) const; + + void Deserialize(Serializer &data); }; -} \ No newline at end of file +} diff --git a/include/ehs/db/DbVarTmpl.h b/include/ehs/db/DbVarTmpl.h index ab92b0a..282b0bf 100644 --- a/include/ehs/db/DbVarTmpl.h +++ b/include/ehs/db/DbVarTmpl.h @@ -2,23 +2,35 @@ #include "DbType.h" #include "ehs/EHS.h" -#include "ehs/BaseObj.h" +#include "ehs/Serializer.h" #include "ehs/Str.h" namespace ehs { - class DbVarTmpl : public BaseObj + class DbVar; + + class DbVarTmpl { private: + friend class DbTable; + friend class DbVar; + UInt_64 hashId; Str_8 id; DbType type; bool array; + UInt_64 size; + Byte* def; + Array slaves; public: + ~DbVarTmpl(); + DbVarTmpl(); - DbVarTmpl(Str_8 id, DbType type, bool array); + DbVarTmpl(Str_8 id, DbType type, UInt_64 size, const Byte* def); + + DbVarTmpl(Str_8 id, DbType type, const Byte* def); DbVarTmpl(DbVarTmpl&& varTmpl) noexcept; @@ -41,5 +53,16 @@ namespace ehs void SetIsArray(bool value); bool IsArray() const; + + UInt_64 GetSize() const; + + Byte* GetDefault() const; + + private: + void UpdateSlave(const DbVar *oldSlave, DbVar *newSlave) const; + + void Serialize(Serializer &data) const; + + void Deserialize(Serializer &data); }; } diff --git a/include/ehs/io/BaseDirectory.h b/include/ehs/io/BaseDirectory.h new file mode 100644 index 0000000..bd8f1ea --- /dev/null +++ b/include/ehs/io/BaseDirectory.h @@ -0,0 +1,13 @@ +#pragma once + +#include "ehs/Array.h" +#include "ehs/Str.h" + +namespace ehs +{ + class BaseDirectory + { + public: + static Array GetAllFiles(const Str_8& dir); + }; +} \ No newline at end of file diff --git a/include/ehs/io/Directory.h b/include/ehs/io/Directory.h new file mode 100644 index 0000000..9d48339 --- /dev/null +++ b/include/ehs/io/Directory.h @@ -0,0 +1,9 @@ +#pragma once + +#include "ehs/system/OS.h" + +#if defined(EHS_OS_WINDOWS) +#include "Directory_W32.h" +#elif defined(EHS_OS_LINUX) +#include "Directory_LNX.h" +#endif \ No newline at end of file diff --git a/include/ehs/io/Directory_LNX.h b/include/ehs/io/Directory_LNX.h new file mode 100644 index 0000000..a70caec --- /dev/null +++ b/include/ehs/io/Directory_LNX.h @@ -0,0 +1,12 @@ +#pragma once + +#include "BaseDirectory.h" + +namespace ehs +{ + class Directory : public BaseDirectory + { + public: + static Array GetAllFiles(const Str_8& dir); + }; +} \ No newline at end of file diff --git a/include/ehs/io/File.h b/include/ehs/io/File.h index d957f51..ba794a3 100644 --- a/include/ehs/io/File.h +++ b/include/ehs/io/File.h @@ -1,6 +1,6 @@ #pragma once -#include "ehs/EHS.h" +#include "ehs/system/OS.h" #if defined(EHS_OS_WINDOWS) #include "File_W32.h" diff --git a/src/db/Database.cpp b/src/db/Database.cpp new file mode 100644 index 0000000..722de2b --- /dev/null +++ b/src/db/Database.cpp @@ -0,0 +1,148 @@ +#include "ehs/db/Database.h" +#include "ehs/io/File.h" + +namespace ehs +{ + Database::Database() + : hashId(0) + { + } + + Database::Database(Str_8 id, const Version& version) + : hashId(id.Hash_64()), id((Str_8&&)id), version(version) + { + } + + Database::Database(const Str_8& filePath) + { + File file(filePath, Mode::READ, Disposition::OPEN); + id = file.GetName(); + hashId = id.Hash_64(); + Serializer data = file.ReadSerializer_64(Endianness::LE, file.Size()); + file.Release(); + + version = data.ReadVersion(); + tables.Resize(data.Read()); + + for (UInt_64 i = 0; i < tables.Size(); ++i) + tables[i].Deserialize(data); + } + + Database::Database(Database&& db) noexcept + : hashId(db.hashId), id((Str_8&&)db.id), version(db.version), tables((Array&&)db.tables) + { + db.hashId = 0; + db.version = {0, 0, 0}; + } + + Database::Database(const Database& db) + : hashId(db.hashId), id(db.id), version(db.version), tables(db.tables) + { + } + + Database& Database::operator=(Database&& db) noexcept + { + if (this == &db) + return *this; + + hashId = db.hashId; + id = (Str_8&&)db.id; + version = db.version; + tables = (Array&&)db.tables; + + db.hashId = 0; + db.version = {0, 0, 0}; + + return *this; + } + + Database& Database::operator=(const Database& db) + { + if (this == &db) + return *this; + + hashId = db.hashId; + id = db.id; + version = db.version; + tables = db.tables; + + return *this; + } + + UInt_64 Database::GetHashId() const + { + return hashId; + } + + void Database::SetId(Str_8 newId) + { + hashId = newId.Hash_64(); + id = (Str_8&&)newId; + } + + Str_8 Database::GetId() const + { + return id; + } + + void Database::SetVersion(const Version& newVersion) + { + version = newVersion; + } + + Version Database::GetVersion() const + { + return version; + } + + bool Database::HasTable(UInt_64 hashId) const + { + for (UInt_64 i = 0; i < tables.Size(); ++i) + if (tables[i].GetHashId() == hashId) + return true; + + return false; + } + + bool Database::HasTable(const Str_8& id) const + { + return HasTable(id.Hash_64()); + } + + DbTable* Database::CreateTable(Str_8 id) + { + if (HasTable(id)) + return nullptr; + + tables.Push(DbTable((Str_8&&)id)); + + return &tables[tables.End()]; + } + + DbTable* Database::GetTable(UInt_64 hashId) const + { + for (UInt_64 i = 0; i < tables.Size(); ++i) + if (tables[i].GetHashId() == hashId) + return &tables[i]; + + return nullptr; + } + + DbTable* Database::GetTable(const Str_8& id) const + { + return GetTable(id.Hash_64()); + } + + void Database::Save(const Str_8& directory) const + { + Serializer data(Endianness::LE); + data.WriteVersion(version); + data.Write(tables.Size()); + + for (UInt_64 i = 0; i < tables.Size(); ++i) + tables[i].Serialize(data); + + File file(directory + "/" + id + ".ehd", Mode::WRITE, Disposition::CREATE_PERSISTENT); + file.WriteSerializer_64(data); + } +} diff --git a/src/db/DbObject.cpp b/src/db/DbObject.cpp index f923bba..1e3de63 100644 --- a/src/db/DbObject.cpp +++ b/src/db/DbObject.cpp @@ -1,22 +1,29 @@ #include "ehs/db/DbObject.h" +#include "ehs/db/DbTable.h" +#include "ehs/Serializer.h" +#include "ehs/io/File.h" namespace ehs { DbObject::DbObject() - : id(0), loaded(false), parent(nullptr) + : id(0), parent(nullptr) + { + } + + DbObject::DbObject(const UInt_64 id) + : id(id), parent(nullptr) { } DbObject::DbObject(DbObject&& obj) noexcept - : id(obj.id), vars((Array&&)obj.vars), loaded(obj.loaded), parent(obj.parent) + : id(obj.id), parent(obj.parent), vars((Array&&)obj.vars) { obj.id = 0; - obj.loaded = false; obj.parent = nullptr; } DbObject::DbObject(const DbObject& obj) - : id(obj.id), vars(obj.vars), loaded(obj.loaded), parent(obj.parent) + : id(obj.id), parent(obj.parent), vars(obj.vars) { } @@ -26,12 +33,13 @@ namespace ehs return *this; id = obj.id; - vars = (Array&&)obj.vars; - loaded = obj.loaded; parent = obj.parent; + vars = (Array&&)obj.vars; + + for (UInt_64 i = 0; i < vars.Size(); ++i) + vars[i].parent = this; obj.id = 0; - obj.loaded = false; obj.parent = nullptr; return *this; @@ -43,19 +51,21 @@ namespace ehs return *this; id = obj.id; - vars = obj.vars; - loaded = obj.loaded; parent = obj.parent; + vars = obj.vars; + + for (UInt_64 i = 0; i < vars.Size(); ++i) + vars[i].parent = this; return *this; } - UInt_64 DbObject::GetId() + UInt_64 DbObject::GetId() const { return id; } - bool DbObject::HasVariable(UInt_64 hashId) + bool DbObject::HasVariable(const UInt_64 hashId) const { for (UInt_64 i = 0; i < vars.Size(); ++i) if (vars[i].GetHashId() == hashId) @@ -64,7 +74,7 @@ namespace ehs return false; } - DbVar* DbObject::GetVariable(UInt_64 hashId) const + DbVar* DbObject::GetVariable(const UInt_64 hashId) const { for (UInt_64 i = 0; i < vars.Size(); ++i) if (vars[i].GetHashId() == hashId) @@ -73,17 +83,40 @@ namespace ehs return nullptr; } - void DbObject::Save() + void DbObject::Save() const { + if (!IsLoaded()) + return; + + Serializer data(Endianness::LE); + + data.Write(vars.Size()); + + for (UInt_64 i = 0; i < vars.Size(); ++i) + vars[i].Serialize(data); + + File file(parent->GetId() + "/" + Str_8::FromNum(id), Mode::WRITE, Disposition::CREATE_PERSISTENT); + file.WriteSerializer_64(data); } void DbObject::Load() { + if (IsLoaded()) + return; + + File file(parent->GetId() + "/" + Str_8::FromNum(id), Mode::READ, Disposition::OPEN); + Serializer data = file.ReadSerializer_64(Endianness::LE, file.Size()); + file.Release(); + + vars.Resize(data.Read()); + + for (UInt_64 i = 0; i < vars.Size(); ++i) + vars[i].Deserialize(data); } bool DbObject::IsLoaded() const { - return loaded; + return vars.Size(); } void DbObject::Free() @@ -91,8 +124,9 @@ namespace ehs vars.Clear(); } - DbTable* DbObject::GetParent() const + void DbObject::CreateVariable(DbVarTmpl* master) { - return parent; + vars.Push(DbVar(master->GetHashId(), master, master->GetSize(), master->GetDefault())); + vars[vars.End()].parent = this; } } diff --git a/src/db/DbTable.cpp b/src/db/DbTable.cpp new file mode 100644 index 0000000..fbcf108 --- /dev/null +++ b/src/db/DbTable.cpp @@ -0,0 +1,178 @@ +#include "ehs/db/DbTable.h" +#include "ehs/io/Directory.h" +#include "ehs/io/File_UNX.h" + +namespace ehs +{ + DbTable::DbTable() + : hashId(0) + { + } + + DbTable::DbTable(Str_8 id) + : hashId(id.Hash_64()), id((Str_8&&)id) + { + } + + DbTable::DbTable(DbTable&& table) noexcept + : hashId(table.hashId), id((Str_8&&)table.id), varTmpls((Array&&)table.varTmpls), + objects((Array&&)table.objects) + { + table.hashId = 0; + } + + DbTable::DbTable(const DbTable& table) + : hashId(table.hashId), id(table.id), varTmpls(table.varTmpls), objects(table.objects) + { + } + + DbTable& DbTable::operator=(DbTable&& table) noexcept + { + if (this == &table) + return *this; + + hashId = table.hashId; + id = (Str_8&&)table.id; + varTmpls = (Array&&)table.varTmpls; + objects = (Array&&)table.objects; + + for (UInt_64 i = 0; i < objects.Size(); ++i) + objects[i].parent = this; + + table.hashId = 0; + + return *this; + } + + DbTable& DbTable::operator=(const DbTable& table) + { + if (this == &table) + return *this; + + hashId = table.hashId; + id = table.id; + varTmpls = table.varTmpls; + objects = table.objects; + + for (UInt_64 i = 0; i < objects.Size(); ++i) + objects[i].parent = this; + + return *this; + } + + UInt_64 DbTable::GetHashId() const + { + return hashId; + } + + void DbTable::SetId(Str_8 newId) + { + hashId = newId.Hash_64(); + id = (Str_8&&)newId; + } + + Str_8 DbTable::GetId() const + { + return id; + } + + bool DbTable::HasVariable(const UInt_64 hashId) const + { + for (UInt_64 i = 0; i < varTmpls.Size(); ++i) + if (varTmpls[i].GetHashId() == hashId) + return true; + + return false; + } + + bool DbTable::HasVariable(const Str_8& id) const + { + return HasVariable(id.Hash_64()); + } + + bool DbTable::CreateVariable(Str_8 id, DbType type, const Byte* const defaultValue) + { + if (HasVariable(id)) + return false; + + varTmpls.Push(DbVarTmpl((Str_8&&)id, type, defaultValue)); + + DbVarTmpl* var = &varTmpls[varTmpls.End()]; + + for (UInt_64 i = 0; i < objects.Size(); ++i) + objects[i].CreateVariable(var); + + return true; + } + + bool DbTable::CreateVariable(Str_8 id, const DbType type, const UInt_64 size, const Byte* const defaultValue) + { + if (HasVariable(id)) + return false; + + varTmpls.Push(DbVarTmpl((Str_8&&)id, type, size, defaultValue)); + + DbVarTmpl* var = &varTmpls[varTmpls.End()]; + + for (UInt_64 i = 0; i < objects.Size(); ++i) + objects[i].CreateVariable(var); + + return true; + } + + DbObject* DbTable::CreateObject() + { + objects.Push(DbObject(objects.Size())); + + DbObject* obj = &objects[objects.End()]; + + obj->parent = this; + + for (UInt_64 i = 0; i < varTmpls.Size(); ++i) + obj->CreateVariable(&varTmpls[i]); + + return obj; + } + + DbVarTmpl* DbTable::GetVariableTemplate(UInt_64 hashId) const + { + for (UInt_64 i = 0; i < varTmpls.Size(); ++i) + if (varTmpls[i].GetHashId() == hashId) + return &varTmpls[i]; + + return nullptr; + } + + void DbTable::Serialize(Serializer& data) const + { + data.WriteStr(id); + data.Write(varTmpls.Size()); + + for (UInt_64 i = 0; i < varTmpls.Size(); ++i) + varTmpls[i].Serialize(data); + + for (UInt_64 i = 0; i < objects.Size(); ++i) + objects[i].Save(); + } + + void DbTable::Deserialize(Serializer& data) + { + id = data.ReadStr(); + hashId = id.Hash_64(); + + varTmpls.Resize(data.Read()); + + for (UInt_64 i = 0; i < varTmpls.Size(); ++i) + varTmpls[i].Deserialize(data); + + Array files = Directory::GetAllFiles(id); + for (UInt_64 i = 0; i < files.Size(); ++i) + { + if (File::ParseExt_8(files[i]) != "eho") + continue; + + objects.Push(DbObject(File::ParseName_8(files[i]).ToDecimal())); + objects[objects.End()].parent = this; + } + } +} diff --git a/src/db/DbType.cpp b/src/db/DbType.cpp deleted file mode 100644 index 5f83f28..0000000 --- a/src/db/DbType.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "ehs/db/DbType.h" - -namespace ehs -{ - constexpr UInt_8 DbTypeToSize(const DbType type) - { - switch (type) - { - case DbType::SINT_64: - return 8; - case DbType::UINT_64: - return 8; - case DbType::SINT_32: - return 4; - case DbType::UINT_32: - return 4; - case DbType::SINT_16: - return 2; - case DbType::UINT_16: - return 2; - case DbType::SINT_8: - return 1; - case DbType::UINT_8: - return 1; - case DbType::FLOAT: - return 4; - case DbType::DOUBLE: - return 8; - case DbType::BOOLEAN: - return 1; - case DbType::CHAR_32: - return 4; - case DbType::CHAR_16: - return 2; - case DbType::CHAR_8: - return 1; - } - } -} \ No newline at end of file diff --git a/src/db/DbVar.cpp b/src/db/DbVar.cpp index 2ce0930..30a5d38 100644 --- a/src/db/DbVar.cpp +++ b/src/db/DbVar.cpp @@ -1,4 +1,8 @@ #include "ehs/db/DbVar.h" +#include "ehs/Util.h" +#include "ehs/db/DbObject.h" +#include "ehs/db/DbTable.h" +#include "ehs/db/DbVarTmpl.h" namespace ehs { @@ -8,29 +12,35 @@ namespace ehs } DbVar::DbVar() - : hashId(0), size(0), data(nullptr) + : hashId(0), parent(nullptr), master(nullptr), size(0), data(nullptr) { } - DbVar::DbVar(UInt_64 hashId, UInt_64 size, Byte* data) - : hashId(hashId), size(size), data(data) + DbVar::DbVar(const UInt_64 hashId, DbVarTmpl *master, const UInt_64 size, const Byte *const data) + : hashId(hashId), parent(nullptr), master(master), size(size), data(new Byte[DbTypeToSize(master->GetType()) * size]) { + master->slaves.Push(this); + Util::Copy(this->data, data, DbTypeToSize(master->GetType()) * size); } - DbVar::DbVar(DbVar&& var) noexcept - : hashId(var.hashId), size(var.size), data(var.data) + DbVar::DbVar(DbVar &&var) noexcept + : hashId(var.hashId), parent(var.parent), master(var.master), size(var.size), data(var.data) { + master->UpdateSlave(&var, this); + var.hashId = 0; + var.parent = nullptr; + var.master = nullptr; var.size = 0; var.data = nullptr; } - DbVar::DbVar(const DbVar& var) - : hashId(0), size(0), data(nullptr) + DbVar::DbVar(const DbVar &var) + : hashId(0), parent(nullptr), master(nullptr), size(0), data(nullptr) { } - DbVar& DbVar::operator=(DbVar&& var) noexcept + DbVar &DbVar::operator=(DbVar &&var) noexcept { if (this == &var) return *this; @@ -38,17 +48,22 @@ namespace ehs delete[] data; hashId = var.hashId; + parent = var.parent; + master = var.master; size = var.size; data = var.data; + master->UpdateSlave(&var, this); + var.hashId = 0; + var.master = nullptr; var.size = 0; var.data = nullptr; return *this; } - DbVar& DbVar::operator=(const DbVar& var) + DbVar &DbVar::operator=(const DbVar &var) { if (this == &var) return *this; @@ -56,13 +71,15 @@ namespace ehs delete[] data; hashId = 0; + parent = nullptr; + master = nullptr; size = 0; data = nullptr; return *this; } - DbVar::operator Byte*() const + DbVar::operator Byte *() const { return data; } @@ -77,8 +94,54 @@ namespace ehs return size; } + void DbVar::SetData(const UInt_64 newSize, const Byte* const newData) + { + if (!master->IsArray()) + return; + + size = newSize; + + const UInt_64 byteSize = DbTypeToSize(master->GetType()) * newSize; + + data = new Byte[byteSize]; + + Util::Copy(data, newData, byteSize); + } + + void DbVar::SetData(const Byte* newData) + { + size = 1; + + const UInt_64 byteSize = DbTypeToSize(master->GetType()); + + data = new Byte[byteSize]; + + Util::Copy(data, newData, byteSize); + } + Byte* DbVar::GetData() const { return data; } + + void DbVar::Serialize(Serializer &data) const + { + data.Write(hashId); + data.Write(size); + data.WriteArray(this->data, DbTypeToSize(master->GetType()) * size); + } + + void DbVar::Deserialize(Serializer &data) + { + hashId = data.Read(); + + master = parent->parent->GetVariableTemplate(hashId); + + size = data.Read(); + + UInt_64 byteSize = 0; + data.ReadArray(this->data, &byteSize); + this->data = new Byte[byteSize]; + data.ReadArray(this->data, &byteSize); + } } diff --git a/src/db/DbVarTmpl.cpp b/src/db/DbVarTmpl.cpp index df1c0c9..aee80c1 100644 --- a/src/db/DbVarTmpl.cpp +++ b/src/db/DbVarTmpl.cpp @@ -1,43 +1,71 @@ #include "ehs/db/DbVarTmpl.h" +#include "ehs/db/DbVar.h" namespace ehs { + DbVarTmpl::~DbVarTmpl() + { + delete[] def; + } + DbVarTmpl::DbVarTmpl() - : hashId(0), type(DbType::SINT_64), array(false) + : hashId(0), type(DbType::SINT_64), array(false), size(0), def(nullptr) { } - DbVarTmpl::DbVarTmpl(Str_8 id, DbType type, bool array) - : hashId(id.Hash_64()), id((Str_8&&)id), type(type), array(array) + DbVarTmpl::DbVarTmpl(Str_8 id, const DbType type, const UInt_64 size, const Byte* const def) + : hashId(id.Hash_64()), id((Str_8&&)id), type(type), array(true), size(size), + def(new Byte[DbTypeToSize(type) * size]) { + Util::Copy(this->def, def, DbTypeToSize(type) * size); } - DbVarTmpl::DbVarTmpl(DbVarTmpl&& varTmpl) noexcept - : hashId(varTmpl.hashId), id((Str_8&&)varTmpl.id), type(varTmpl.type), array(varTmpl.array) + DbVarTmpl::DbVarTmpl(Str_8 id, const DbType type, const Byte* const def) + : hashId(id.Hash_64()), id((Str_8&&)id), type(type), array(false), size(1), def(new Byte[DbTypeToSize(type)]) + { + Util::Copy(this->def, def, DbTypeToSize(type)); + } + + DbVarTmpl::DbVarTmpl(DbVarTmpl &&varTmpl) noexcept + : hashId(varTmpl.hashId), id((Str_8&&)varTmpl.id), type(varTmpl.type), array(varTmpl.array), size(varTmpl.size), + def(varTmpl.def) { varTmpl.hashId = 0; varTmpl.type = DbType::SINT_64; varTmpl.array = false; + varTmpl.size = 0; + varTmpl.def = nullptr; } - DbVarTmpl::DbVarTmpl(const DbVarTmpl& varTmpl) - : hashId(varTmpl.hashId), id(varTmpl.id), type(varTmpl.type), array(varTmpl.array) + DbVarTmpl::DbVarTmpl(const DbVarTmpl &varTmpl) + : hashId(varTmpl.hashId), id(varTmpl.id), type(varTmpl.type), array(varTmpl.array), size(varTmpl.size), + def(varTmpl.def) { } - DbVarTmpl& DbVarTmpl::operator=(DbVarTmpl&& varTmpl) noexcept + DbVarTmpl &DbVarTmpl::operator=(DbVarTmpl &&varTmpl) noexcept { if (this == &varTmpl) return *this; + delete[] def; + hashId = varTmpl.hashId; id = (Str_8&&)varTmpl.id; type = varTmpl.type; array = varTmpl.array; + size = varTmpl.size; + def = varTmpl.def; + slaves = (Array&&)varTmpl.slaves; + + for (UInt_64 i = 0; i < slaves.Size(); ++i) + slaves[i]->master = this; varTmpl.hashId = 0; varTmpl.type = DbType::SINT_64; varTmpl.array = false; + varTmpl.size = 0; + varTmpl.def = nullptr; return *this; } @@ -47,10 +75,20 @@ namespace ehs if (this == &varTmpl) return *this; + delete[] def; + hashId = varTmpl.hashId; id = varTmpl.id; type = varTmpl.type; array = varTmpl.array; + size = varTmpl.size; + slaves = varTmpl.slaves; + + const UInt_64 byteSize = DbTypeToSize(varTmpl.type) * varTmpl.size; + + def = new Byte[byteSize]; + + Util::Copy(def, varTmpl.def, byteSize); return *this; } @@ -71,7 +109,7 @@ namespace ehs return id; } - void DbVarTmpl::SetType(DbType newType) + void DbVarTmpl::SetType(const DbType newType) { type = newType; } @@ -81,7 +119,7 @@ namespace ehs return type; } - void DbVarTmpl::SetIsArray(bool value) + void DbVarTmpl::SetIsArray(const bool value) { array = value; } @@ -90,4 +128,44 @@ namespace ehs { return array; } + + UInt_64 DbVarTmpl::GetSize() const + { + return size; + } + + Byte* DbVarTmpl::GetDefault() const + { + return def; + } + + void DbVarTmpl::UpdateSlave(const DbVar* const oldSlave, DbVar* const newSlave) const + { + for (UInt_64 i = 0; i < slaves.Size(); ++i) + if (slaves[i] == oldSlave) + slaves[i] = newSlave; + } + + void DbVarTmpl::Serialize(Serializer &data) const + { + data.WriteStr(id); + data.Write(type); + data.Write(array); + data.Write(size); + data.WriteArray(def, DbTypeToSize(type) * size); + } + + void DbVarTmpl::Deserialize(Serializer &data) + { + id = data.ReadStr(); + hashId = id.Hash_64(); + type = data.Read(); + array = data.Read(); + size = data.Read(); + + UInt_64 byteSize = 0; + data.ReadArray(def, &byteSize); + def = new Byte[byteSize]; + data.ReadArray(def, &byteSize); + } } diff --git a/src/io/BaseDirectory.cpp b/src/io/BaseDirectory.cpp new file mode 100644 index 0000000..3cfac5c --- /dev/null +++ b/src/io/BaseDirectory.cpp @@ -0,0 +1,9 @@ +#include "ehs/io/BaseDirectory.h" + +namespace ehs +{ + Array BaseDirectory::GetAllFiles(const Str_8& dir) + { + return {}; + } +} diff --git a/src/io/Directory_LNX.cpp b/src/io/Directory_LNX.cpp new file mode 100644 index 0000000..e4d55a0 --- /dev/null +++ b/src/io/Directory_LNX.cpp @@ -0,0 +1,28 @@ +#include "ehs/io/Directory_LNX.h" +#include "ehs/Log.h" + +#include + +namespace ehs +{ + Array Directory::GetAllFiles(const Str_8& dir) + { + Array result; + + DIR* hdl = opendir(dir); + if (!dir) + { + EHS_LOG_INT("Error", 0, "Failed to open directory, \"" + dir + "\"."); + return result; + } + + dirent* entry; + while ((entry = readdir(hdl))) + if (entry->d_type == DT_REG) + result.Push(entry->d_name); + + closedir(hdl); + + return result; + } +}