From 273574d4dbdb442bc69e144fac556ff11613f0ca Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 22 Feb 2015 15:37:11 -0800 Subject: [PATCH] Added memory buffer plus tests to project, going to use it for item serialization --- common/CMakeLists.txt | 2 + common/memory_buffer.cpp | 171 +++++++++++++ common/memory_buffer.h | 131 ++++++++++ tests/CMakeLists.txt | 1 + tests/main.cpp | 2 + tests/memory_buffer_test.h | 510 +++++++++++++++++++++++++++++++++++++ 6 files changed, 817 insertions(+) create mode 100644 common/memory_buffer.cpp create mode 100644 common/memory_buffer.h create mode 100644 tests/memory_buffer_test.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 49828d082..243553bff 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -37,6 +37,7 @@ SET(common_sources item_container.cpp item_instance.cpp md5.cpp + memory_buffer.cpp memory_mapped_file.cpp misc.cpp misc_functions.cpp @@ -152,6 +153,7 @@ SET(common_headers loottable.h mail_oplist.h md5.h + memory_buffer.h memory_mapped_file.h misc.h misc_functions.h diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp new file mode 100644 index 000000000..cd10fe0c2 --- /dev/null +++ b/common/memory_buffer.cpp @@ -0,0 +1,171 @@ +#include "memory_buffer.h" + +EQEmu::MemoryBuffer::MemoryBuffer() { + buffer_ = nullptr; + size_ = 0; + capacity_ = 0; + read_pos_ = 0; + write_pos_ = 0; +} + +EQEmu::MemoryBuffer::MemoryBuffer(size_t sz) { + buffer_ = nullptr; + size_ = 0; + capacity_ = 0; + read_pos_ = 0; + write_pos_ = 0; + Resize(sz); +} + +EQEmu::MemoryBuffer::MemoryBuffer(const MemoryBuffer &other) { + if(other.capacity_) { + buffer_ = new uchar[other.capacity_]; + memcpy(buffer_, other.buffer_, other.capacity_); + } else { + buffer_ = nullptr; + } + + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; +} + +EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) { + buffer_ = other.buffer_; + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; + + other.buffer_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + other.read_pos_ = 0; + other.write_pos_ = 0; +} + +EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) { + if(other.capacity_) { + buffer_ = new uchar[other.capacity_]; + memcpy(buffer_, other.buffer_, other.capacity_); + } + else { + buffer_ = nullptr; + } + + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; + return *this; +} + +EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other) { + buffer_ = other.buffer_; + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; + + other.buffer_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + other.read_pos_ = 0; + other.write_pos_ = 0; + return *this; +} + +EQEmu::MemoryBuffer::~MemoryBuffer() { Clear(); } + +uchar& EQEmu::MemoryBuffer::operator[](size_t pos) { + return buffer_[pos]; +} + +const uchar& EQEmu::MemoryBuffer::operator[](size_t pos) const { + return buffer_[pos]; +} + +bool EQEmu::MemoryBuffer::Empty() { + return size_ == 0; +} + +bool EQEmu::MemoryBuffer::Empty() const { + return size_ == 0; +} + +size_t EQEmu::MemoryBuffer::Size() { + return size_; +} + +size_t EQEmu::MemoryBuffer::Size() const { + return size_; +} + +size_t EQEmu::MemoryBuffer::Capacity() { + return capacity_; +} + +size_t EQEmu::MemoryBuffer::Capacity() const { + return capacity_; +} + +void EQEmu::MemoryBuffer::Resize(size_t sz) { + if(!buffer_) { + size_t new_size = sz + 32; + buffer_ = new uchar[new_size]; + capacity_ = new_size; + size_ = sz; + memset(buffer_, 0, capacity_); + return; + } + + if(sz > capacity_) { + size_t new_size = sz + 32; + uchar *temp = new uchar[new_size]; + memcpy(temp, buffer_, new_size); + delete[] buffer_; + buffer_ = temp; + + capacity_ = new_size; + size_ = sz; + } + else { + size_ = sz; + } +} + +void EQEmu::MemoryBuffer::Clear() { + if(buffer_) { + delete[] buffer_; + buffer_ = nullptr; + } + + size_ = 0; + capacity_ = 0; +} + +void EQEmu::MemoryBuffer::Zero() { + if(buffer_) { + memset(buffer_, 0, capacity_); + } +} + +void EQEmu::MemoryBuffer::Write(const char *val, size_t len) { + size_t size_needed = write_pos_ + len; + Resize(size_needed); + + memcpy(&buffer_[write_pos_], val, len); + write_pos_ += len; +} + +void EQEmu::MemoryBuffer::Read(uchar *buf, size_t len) { + memcpy(buf, &buffer_[read_pos_], len); + read_pos_ += len; +} + +void EQEmu::MemoryBuffer::Read(char *str) { + size_t len = strlen((const char*)&buffer_[read_pos_]); + memcpy(str, &buffer_[read_pos_], len); + read_pos_ += len; +} diff --git a/common/memory_buffer.h b/common/memory_buffer.h new file mode 100644 index 000000000..beec6b809 --- /dev/null +++ b/common/memory_buffer.h @@ -0,0 +1,131 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef COMMON_MEMORY_BUFFER_H +#define COMMON_MEMORY_BUFFER_H + +#include "types.h" +#include +#include +#include + +namespace EQEmu +{ + class MemoryBuffer + { + public: + MemoryBuffer(); + MemoryBuffer(size_t sz); + MemoryBuffer(const MemoryBuffer &other); + MemoryBuffer(MemoryBuffer &&other); + MemoryBuffer& operator=(const MemoryBuffer &other); + MemoryBuffer& operator=(MemoryBuffer &&other); + ~MemoryBuffer(); + + uchar& operator[](size_t pos); + const uchar& operator[](size_t pos) const; + + template + operator T*() { + return reinterpret_cast(buffer_); + } + + template + operator T*() const { + return reinterpret_cast(buffer_); + } + + operator bool() { return buffer_ != nullptr; } + operator bool() const { return buffer_ != nullptr; } + + bool Empty(); + bool Empty() const; + size_t Size(); + size_t Size() const; + size_t Capacity(); + size_t Capacity() const; + + void Resize(size_t sz); + void Clear(); + void Zero(); + + template + void Write(T val) { + static_assert(std::is_pod::value, "MemoryBuffer::Write(T val) only works on pod and string types."); + Write((const char*)&val, sizeof(T)); + } + + template + T Read() { + static_assert(std::is_pod::value, "MemoryBuffer::Read() only works on pod and string types."); + T temp; + Read((uchar*)&temp, sizeof(T)); + return temp; + } + + template<> + void Write(std::string val) { + Write(val.c_str(), val.length()); + Write((uint8)0); + } + + template<> + void Write(const std::string &val) { + Write(val.c_str(), val.length()); + Write((uint8)0); + } + + template<> + void Write(const char *val) { + size_t len = strlen(val); + Write(val, len); + Write((uint8)0); + } + + template<> + std::string Read() { + std::string ret; + size_t len = strlen((const char*)&buffer_[read_pos_]); + ret.resize(len); + memcpy(&ret[0], &buffer_[read_pos_], len); + read_pos_ += len + 1; + return ret; + } + + void Write(const char *val, size_t len); + void Read(uchar *buf, size_t len); + void Read(char *str); + + inline size_t GetWritePosition() { return write_pos_; } + inline void SetWritePosition(size_t wp) { write_pos_ = wp; } + inline void WriteSkipBytes(size_t skip) { write_pos_ += skip; } + inline size_t GetReadPosition() { return read_pos_; } + inline void SetReadPosition(size_t wp) { read_pos_ = wp; } + inline void ReadSkipBytes(size_t skip) { read_pos_ += skip; } + + private: + uchar *buffer_; + size_t size_; + size_t capacity_; + size_t write_pos_; + size_t read_pos_; + }; + +} // EQEmu + +#endif \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8d0a733b7..5e10cddba 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,7 @@ SET(tests_headers hextoi_32_64_test.h inventory_test.h ipc_mutex_test.h + memory_buffer_test.h memory_mapped_file_test.h string_util_test.h skills_util_test.h diff --git a/tests/main.cpp b/tests/main.cpp index 165ab8d82..420280f30 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -30,6 +30,7 @@ #include "data_verification_test.h" #include "skills_util_test.h" #include "inventory_test.h" +#include "memory_buffer_test.h" int main() { try { @@ -46,6 +47,7 @@ int main() { tests.add(new DataVerificationTest()); tests.add(new SkillsUtilsTest()); tests.add(new InventoryTest()); + tests.add(new MemoryBufferTest()); tests.run(*output, false); } catch(...) { return -1; diff --git a/tests/memory_buffer_test.h b/tests/memory_buffer_test.h new file mode 100644 index 000000000..366795bab --- /dev/null +++ b/tests/memory_buffer_test.h @@ -0,0 +1,510 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __EQEMU_TESTS_MEMORY_BUFFER_H +#define __EQEMU_TESTS_MEMORY_BUFFER_H + +#include "cppunit/cpptest.h" +#include "../common/memory_buffer.h" + +class MemoryBufferTest : public Test::Suite { + typedef void(MemoryBufferTest::*TestFunction)(void); +public: + MemoryBufferTest() { + TEST_ADD(MemoryBufferTest::WriteTest); + TEST_ADD(MemoryBufferTest::ReadTest); + TEST_ADD(MemoryBufferTest::ConvertTest); + TEST_ADD(MemoryBufferTest::ResizeTest); + TEST_ADD(MemoryBufferTest::CopyTest); + TEST_ADD(MemoryBufferTest::AssignTest); + TEST_ADD(MemoryBufferTest::MoveTest); + TEST_ADD(MemoryBufferTest::ZeroTest); + TEST_ADD(MemoryBufferTest::ClearTest); + } + + ~MemoryBufferTest() { + } + +private: + void WriteTest() { + uint8 a = 0; + uint16 b = 5 ; + uint32 c = 10; + uint64 d = 15; + std::string s2 = "test2"; + + mb.Write(a); + mb.Write(b); + mb.Write(c); + mb.Write(d); + mb.Write("test1"); + mb.Write(s2); + + TEST_ASSERT(mb.Size() == 27); + + uchar *data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + } + + void ReadTest() { + uint8 a = mb.Read(); + uint16 b = mb.Read(); + uint32 c = mb.Read(); + uint64 d = mb.Read(); + std::string s1 = mb.Read(); + std::string s2 = mb.Read(); + + TEST_ASSERT(a == 0); + TEST_ASSERT(b == 5); + TEST_ASSERT(c == 10); + TEST_ASSERT(d == 15); + TEST_ASSERT(s1.compare("test1") == 0); + TEST_ASSERT(s2.compare("test2") == 0); + } + +#pragma pack(1) + struct ConvertStruct + { + uint8 a; + uint16 b; + uint32 c; + uint64 d; + char test1[6]; + char test2[6]; + }; +#pragma pack() + + void ConvertTest() + { + uchar *v1 = mb; + char *v2 = mb; + ConvertStruct *cs = (ConvertStruct*)mb; + + TEST_ASSERT(v1 != nullptr); + TEST_ASSERT(v1[0] == 0); + TEST_ASSERT(v1[1] == 5); + TEST_ASSERT(v1[2] == 0); + TEST_ASSERT(v1[3] == 10); + TEST_ASSERT(v1[4] == 0); + TEST_ASSERT(v1[5] == 0); + TEST_ASSERT(v1[6] == 0); + TEST_ASSERT(v1[7] == 15); + TEST_ASSERT(v1[8] == 0); + TEST_ASSERT(v1[9] == 0); + TEST_ASSERT(v1[10] == 0); + TEST_ASSERT(v1[11] == 0); + TEST_ASSERT(v1[12] == 0); + TEST_ASSERT(v1[13] == 0); + TEST_ASSERT(v1[14] == 0); + TEST_ASSERT(v1[15] == 't'); + TEST_ASSERT(v1[16] == 'e'); + TEST_ASSERT(v1[17] == 's'); + TEST_ASSERT(v1[18] == 't'); + TEST_ASSERT(v1[19] == '1'); + TEST_ASSERT(v1[20] == 0); + TEST_ASSERT(v1[21] == 't'); + TEST_ASSERT(v1[22] == 'e'); + TEST_ASSERT(v1[23] == 's'); + TEST_ASSERT(v1[24] == 't'); + TEST_ASSERT(v1[25] == '2'); + TEST_ASSERT(v1[26] == 0); + + TEST_ASSERT(v2 != nullptr); + TEST_ASSERT(v2[0] == 0); + TEST_ASSERT(v2[1] == 5); + TEST_ASSERT(v2[2] == 0); + TEST_ASSERT(v2[3] == 10); + TEST_ASSERT(v2[4] == 0); + TEST_ASSERT(v2[5] == 0); + TEST_ASSERT(v2[6] == 0); + TEST_ASSERT(v2[7] == 15); + TEST_ASSERT(v2[8] == 0); + TEST_ASSERT(v2[9] == 0); + TEST_ASSERT(v2[10] == 0); + TEST_ASSERT(v2[11] == 0); + TEST_ASSERT(v2[12] == 0); + TEST_ASSERT(v2[13] == 0); + TEST_ASSERT(v2[14] == 0); + TEST_ASSERT(v2[15] == 't'); + TEST_ASSERT(v2[16] == 'e'); + TEST_ASSERT(v2[17] == 's'); + TEST_ASSERT(v2[18] == 't'); + TEST_ASSERT(v2[19] == '1'); + TEST_ASSERT(v2[20] == 0); + TEST_ASSERT(v2[21] == 't'); + TEST_ASSERT(v2[22] == 'e'); + TEST_ASSERT(v2[23] == 's'); + TEST_ASSERT(v2[24] == 't'); + TEST_ASSERT(v2[25] == '2'); + TEST_ASSERT(v2[26] == 0); + + TEST_ASSERT(cs != nullptr); + TEST_ASSERT(cs->a == 0); + TEST_ASSERT(cs->b == 5); + TEST_ASSERT(cs->c == 10); + TEST_ASSERT(cs->d == 15); + TEST_ASSERT(strcmp(cs->test1, "test1") == 0); + TEST_ASSERT(strcmp(cs->test2, "test2") == 0); + } + + void ResizeTest() + { + mb.Resize(21); + TEST_ASSERT(mb.Size() == 21); + + mb.Resize(27); + uchar *data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + + mb.Resize(40); + data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Capacity() >= 40); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + } + + void CopyTest() + { + EQEmu::MemoryBuffer mb2(mb); + + uchar *data = (uchar*)mb2; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + + data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + TEST_ASSERT((void*)mb != (void*)mb2); + } + + void AssignTest() + { + EQEmu::MemoryBuffer mb2 = mb; + + uchar *data = (uchar*)mb2; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + + data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + TEST_ASSERT((void*)mb != (void*)mb2); + } + + void MoveTest() + { + EQEmu::MemoryBuffer mb2 = std::move(mb); + uchar *data = (uchar*)mb; + uchar *data2 = (uchar*)mb2; + TEST_ASSERT(data == nullptr); + TEST_ASSERT(data2 != nullptr); + TEST_ASSERT(mb.Size() == 0); + TEST_ASSERT(mb2.Size() == 40); + TEST_ASSERT(data2[0] == 0); + TEST_ASSERT(data2[1] == 5); + TEST_ASSERT(data2[2] == 0); + TEST_ASSERT(data2[3] == 10); + TEST_ASSERT(data2[4] == 0); + TEST_ASSERT(data2[5] == 0); + TEST_ASSERT(data2[6] == 0); + TEST_ASSERT(data2[7] == 15); + TEST_ASSERT(data2[8] == 0); + TEST_ASSERT(data2[9] == 0); + TEST_ASSERT(data2[10] == 0); + TEST_ASSERT(data2[11] == 0); + TEST_ASSERT(data2[12] == 0); + TEST_ASSERT(data2[13] == 0); + TEST_ASSERT(data2[14] == 0); + TEST_ASSERT(data2[15] == 't'); + TEST_ASSERT(data2[16] == 'e'); + TEST_ASSERT(data2[17] == 's'); + TEST_ASSERT(data2[18] == 't'); + TEST_ASSERT(data2[19] == '1'); + TEST_ASSERT(data2[20] == 0); + TEST_ASSERT(data2[21] == 't'); + TEST_ASSERT(data2[22] == 'e'); + TEST_ASSERT(data2[23] == 's'); + TEST_ASSERT(data2[24] == 't'); + TEST_ASSERT(data2[25] == '2'); + TEST_ASSERT(data2[26] == 0); + + mb = std::move(mb2); + + data = (uchar*)mb; + data2 = (uchar*)mb2; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(data2 == nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(mb2.Size() == 0); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + } + + void ZeroTest() + { + mb.Zero(); + uchar *data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 0); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 0); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 0); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 0); + TEST_ASSERT(data[16] == 0); + TEST_ASSERT(data[17] == 0); + TEST_ASSERT(data[18] == 0); + TEST_ASSERT(data[19] == 0); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 0); + TEST_ASSERT(data[22] == 0); + TEST_ASSERT(data[23] == 0); + TEST_ASSERT(data[24] == 0); + TEST_ASSERT(data[25] == 0); + TEST_ASSERT(data[26] == 0); + TEST_ASSERT(data[27] == 0); + TEST_ASSERT(data[28] == 0); + TEST_ASSERT(data[29] == 0); + TEST_ASSERT(data[30] == 0); + TEST_ASSERT(data[31] == 0); + TEST_ASSERT(data[32] == 0); + TEST_ASSERT(data[33] == 0); + TEST_ASSERT(data[34] == 0); + TEST_ASSERT(data[35] == 0); + TEST_ASSERT(data[36] == 0); + TEST_ASSERT(data[37] == 0); + TEST_ASSERT(data[38] == 0); + TEST_ASSERT(data[39] == 0); + } + + void ClearTest() + { + mb.Clear(); + TEST_ASSERT(!mb); + uchar *data = (uchar*)mb; + TEST_ASSERT(data == nullptr); + } + + EQEmu::MemoryBuffer mb; +}; + +#endif