diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 130e30f..5cae8e7 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,5 +1,6 @@ file(GLOB COMMON_SOURCES "*.cpp" + "datastore/*.cpp" "objectalloc/*.cpp" "ref/*.cpp" "string/*.cpp" diff --git a/common/DataStore.hpp b/common/DataStore.hpp new file mode 100644 index 0000000..b0b5c1f --- /dev/null +++ b/common/DataStore.hpp @@ -0,0 +1,6 @@ +#ifndef COMMON_DATA_STORE_HPP +#define COMMON_DATA_STORE_HPP + +#include "common/datastore/CDataStore.hpp" + +#endif diff --git a/common/datastore/CDataStore.cpp b/common/datastore/CDataStore.cpp new file mode 100644 index 0000000..2e45012 --- /dev/null +++ b/common/datastore/CDataStore.cpp @@ -0,0 +1,193 @@ +#include "common/datastore/CDataStore.hpp" +#include +#include +#include +#include + +void CDataStore::DetachBuffer(void** data, uint32_t* size, uint32_t* alloc) { + // TODO +} + +int32_t CDataStore::FetchWrite(uint32_t pos, uint32_t bytes, const char* fileName, int32_t lineNumber) { + if (pos >= this->m_base && pos + bytes <= this->m_base + this->m_alloc) { + return 1; + } + + if (this->InternalFetchWrite(pos, bytes, this->m_data, this->m_base, this->m_alloc, fileName, lineNumber)) { + return 1; + } + + return 0; +} + +void CDataStore::Finalize() { + STORM_ASSERT(!this->IsFinal()); + + this->m_read = 0; +} + +void CDataStore::GetBufferParams(const void** data, uint32_t* size, uint32_t* alloc) const { + if (data) { + *data = this->m_data; + } + + if (size) { + *size = this->m_size; + } + + if (alloc) { + *alloc = this->m_alloc; + } +} + +CDataStore& CDataStore::GetDataInSitu(void*& val, uint32_t bytes) { + STORM_ASSERT(this->IsFinal()); + + // TODO FetchRead + + auto ofs = this->m_read - this->m_base; + val = &this->m_data[ofs]; + + this->m_read += bytes; + + return *this; +} + +uint32_t CDataStore::GetHeaderSpace() { + return 0; +} + +void CDataStore::InternalDestroy(uint8_t*& data, uint32_t& base, uint32_t& alloc) { + if (alloc && data) { + SMemFree(data, __FILE__, __LINE__, 0); + } + + data = nullptr; + base = 0; + alloc = 0; +} + +int32_t CDataStore::InternalFetchRead(uint32_t pos, uint32_t bytes, uint8_t*& data, uint32_t& base, uint32_t& alloc) { + return 0; +} + +int32_t CDataStore::InternalFetchWrite(uint32_t pos, uint32_t bytes, uint8_t*& data, uint32_t& base, uint32_t& alloc, const char* fileName, int32_t lineNumber) { + alloc = (pos + bytes + 0xFF) & 0xFFFFFF00; + + data = static_cast(SMemReAlloc( + data, + alloc, + fileName == nullptr ? __FILE__ : fileName, + fileName == nullptr ? __LINE__ : lineNumber, + 0x0)); + + return 1; +} + +int32_t CDataStore::IsFinal() { + return this->m_read != -1; +} + +int32_t CDataStore::IsRead() const { + return this->m_size == this->m_read; +} + +CDataStore& CDataStore::Put(uint8_t val) { + STORM_ASSERT(!this->IsFinal()); + + this->FetchWrite(this->m_size, sizeof(val), nullptr, 0); + + auto ofs = this->m_size - this->m_base; + auto ptr = &this->m_data[ofs]; + *reinterpret_cast(ptr) = val; + + this->m_size += sizeof(val); + + return *this; +} + +CDataStore& CDataStore::Put(uint16_t val) { + STORM_ASSERT(!this->IsFinal()); + + this->FetchWrite(this->m_size, sizeof(val), nullptr, 0); + + auto ofs = this->m_size - this->m_base; + auto ptr = &this->m_data[ofs]; + *reinterpret_cast(ptr) = val; + + this->m_size += sizeof(val); + + return *this; +} + +CDataStore& CDataStore::Put(uint32_t val) { + STORM_ASSERT(!this->IsFinal()); + + this->FetchWrite(this->m_size, sizeof(val), nullptr, 0); + + auto ofs = this->m_size - this->m_base; + auto ptr = &this->m_data[ofs]; + *reinterpret_cast(ptr) = val; + + this->m_size += sizeof(val); + + return *this; +} + +CDataStore& CDataStore::PutArray(const uint8_t* val, uint32_t count) { + STORM_ASSERT(!this->IsFinal()); + STORM_ASSERT(val || !count); + + if (val) { + auto src = val; + auto bytes = count; + + this->FetchWrite(this->m_size, bytes, nullptr, 0); + + while (count) { + bytes = std::max(1u, std::min(bytes, this->m_alloc)); + + this->FetchWrite(this->m_size, bytes, nullptr, 0); + + auto ofs = this->m_size - this->m_base; + auto ptr = &this->m_data[ofs]; + + if (ptr != src) { + memcpy(ptr, src, bytes); + } + + src += bytes; + this->m_size += bytes; + count -= bytes; + } + } + + return *this; +} + +CDataStore& CDataStore::PutData(const void* val, uint32_t bytes) { + return this->PutArray(static_cast(val), bytes); +} + +void CDataStore::Reset() { + if (this->m_alloc == -1) { + this->m_data = nullptr; + this->m_alloc = 0; + } + + this->m_size = 0; + this->m_read = -1; +} + +CDataStore& CDataStore::Set(uint32_t pos, uint16_t val) { + STORM_ASSERT(!this->IsFinal()); + STORM_ASSERT(pos + sizeof(val) <= this->m_size); + + this->FetchWrite(pos, sizeof(val), nullptr, 0); + + auto ofs = pos - this->m_base; + auto ptr = &this->m_data[ofs]; + *reinterpret_cast(ptr) = val; + + return *this; +} diff --git a/common/datastore/CDataStore.hpp b/common/datastore/CDataStore.hpp new file mode 100644 index 0000000..a0ae3b3 --- /dev/null +++ b/common/datastore/CDataStore.hpp @@ -0,0 +1,41 @@ +#ifndef COMMON_DATASTORE_C_DATA_STORE_HPP +#define COMMON_DATASTORE_C_DATA_STORE_HPP + +#include + +class CDataStore { + public: + // Member variables + uint8_t* m_data = nullptr; + uint32_t m_base = 0; + uint32_t m_alloc = 0; + uint32_t m_size = 0; + uint32_t m_read = -1; + + // Virtual member functions + virtual void InternalInitialize(uint8_t*& data, uint32_t& base, uint32_t& alloc) {}; + virtual void InternalDestroy(uint8_t*& data, uint32_t& base, uint32_t& alloc); + virtual int32_t InternalFetchRead(uint32_t pos, uint32_t bytes, uint8_t*& data, uint32_t& base, uint32_t& alloc); + virtual int32_t InternalFetchWrite(uint32_t pos, uint32_t bytes, uint8_t*& data, uint32_t& base, uint32_t& alloc, const char* fileName, int32_t lineNumber); + // TODO + // virtual ~CDataStore(); + virtual int32_t IsRead() const; + virtual void Reset(); + virtual void Finalize(); + virtual void GetBufferParams(const void** data, uint32_t* size, uint32_t* alloc) const; + virtual void DetachBuffer(void** data, uint32_t* size, uint32_t* alloc); + virtual uint32_t GetHeaderSpace(); + + // Member functions + int32_t FetchWrite(uint32_t pos, uint32_t bytes, const char* fileName, int32_t lineNumber); + CDataStore& GetDataInSitu(void*& val, uint32_t bytes); + int32_t IsFinal(); + CDataStore& Put(uint8_t val); + CDataStore& Put(uint16_t val); + CDataStore& Put(uint32_t val); + CDataStore& PutArray(const uint8_t* val, uint32_t count); + CDataStore& PutData(const void* val, uint32_t bytes); + CDataStore& Set(uint32_t pos, uint16_t val); +}; + +#endif diff --git a/test/DataStore.cpp b/test/DataStore.cpp new file mode 100644 index 0000000..e33ec2c --- /dev/null +++ b/test/DataStore.cpp @@ -0,0 +1,9 @@ +#include "common/DataStore.hpp" +#include "test/Test.hpp" + +TEST_CASE("CDataStore::CDataStore", "[datastore]") { + SECTION("constructs new data store") { + CDataStore msg; + SUCCEED(); + } +}