diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 034cf415a..6e78e1016 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -41,6 +41,7 @@ SET(common_sources item_struct.cpp light_source.cpp md5.cpp + memory_buffer.cpp memory_mapped_file.cpp misc.cpp misc_functions.cpp @@ -165,6 +166,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/item.h b/common/item.h index 181c57d9c..7c3cd87bb 100644 --- a/common/item.h +++ b/common/item.h @@ -32,13 +32,11 @@ class EvolveInfo; // Stores information about an evolving item family #include "../common/item_struct.h" #include "../common/timer.h" #include "../common/bodytypes.h" -#include "../common/deity.h" // aren't we already in '/common'? - -#include "string_util.h" +#include "../common/deity.h" +#include "../common/memory_buffer.h" #include #include -//#include namespace ItemField diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp new file mode 100644 index 000000000..898851cb3 --- /dev/null +++ b/common/memory_buffer.cpp @@ -0,0 +1,277 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 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 +*/ + +#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) +{ + uchar *tbuf = other.buffer_; + size_t tsz = other.size_; + size_t tcapacity = other.capacity_; + size_t twrite_pos = other.write_pos_; + size_t tread_pos = other.read_pos_; + + other.buffer_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + other.read_pos_ = 0; + other.write_pos_ = 0; + + buffer_ = tbuf; + size_ = tsz; + capacity_ = tcapacity; + write_pos_ = twrite_pos; + read_pos_ = tread_pos; +} + +EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) +{ + if(this == &other) { + return *this; + } + + if(buffer_) { + delete[] buffer_; + } + + 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) +{ + uchar *tbuf = other.buffer_; + size_t tsz = other.size_; + size_t tcapacity = other.capacity_; + size_t twrite_pos = other.write_pos_; + size_t tread_pos = other.read_pos_; + + other.buffer_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + other.read_pos_ = 0; + other.write_pos_ = 0; + + buffer_ = tbuf; + size_ = tsz; + capacity_ = tcapacity; + write_pos_ = twrite_pos; + read_pos_ = tread_pos; + return *this; +} + +EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator+=(const MemoryBuffer &rhs) +{ + if(!rhs.buffer_) { + return *this; + } + + if(buffer_) { + size_t old_size = size_; + Resize(size_ + rhs.size_); + memcpy(&buffer_[old_size], rhs.buffer_, rhs.size_); + } else { + buffer_ = new uchar[rhs.capacity_]; + memcpy(buffer_, rhs.buffer_, rhs.capacity_); + size_ = rhs.size_; + capacity_ = rhs.capacity_; + } + + 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 + 64; + 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_, capacity_); + 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; + write_pos_ = 0; + read_pos_ = 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; +} + +void EQEmu::OutBuffer::overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count) +{ + auto last_pos = tellp(); + seekp(position); + write(_Str, _Count); + seekp(last_pos); +} + +uchar* EQEmu::OutBuffer::detach() +{ + size_t buffer_size = tellp(); + if (buffer_size == 0) + return nullptr; + + auto out_buffer = new uchar[buffer_size]; + memcpy(out_buffer, str().c_str(), buffer_size); + flush(); + + return out_buffer; +} diff --git a/common/memory_buffer.h b/common/memory_buffer.h new file mode 100644 index 000000000..880b860ae --- /dev/null +++ b/common/memory_buffer.h @@ -0,0 +1,134 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2016 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 +#define COMMON_MEMORY_BUFFER + +#include "types.h" + +#include +#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& operator+=(const MemoryBuffer &rhs); + friend MemoryBuffer operator+(MemoryBuffer lhs, const MemoryBuffer& rhs) { return lhs += rhs; } + ~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; + } + + void Write(const std::string &val) { + Write(val.c_str(), val.length()); + Write((uint8)0); + } + + void Write(const char *val) { + size_t len = strlen(val); + Write(val, len); + Write((uint8)0); + } + + std::string ReadString() { + 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 rp) { read_pos_ = rp; } + 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_; + }; + + class OutBuffer : public std::stringstream { + public: + inline size_t size() { return tellp(); } + void overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count); + uchar* detach(); + }; + +} /*EQEmu*/ + +#endif /*COMMON_MEMORY_BUFFER*/ diff --git a/common/string_util.cpp b/common/string_util.cpp index b5717c1b7..902d13335 100644 --- a/common/string_util.cpp +++ b/common/string_util.cpp @@ -415,46 +415,3 @@ void find_replace(std::string& string_subject, const std::string& search_string, index = string_subject.find_first_of(search_string); } } - - - -/* EQEMu: Everquest Server Emulator - - Copyright (C) 2001-2016 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 -*/ - - -void EQEmu::OutBuffer::overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count) -{ - auto last_pos = tellp(); - seekp(position); - write(_Str, _Count); - seekp(last_pos); -} - -uchar* EQEmu::OutBuffer::detach() -{ - size_t buffer_size = tellp(); - if (buffer_size == 0) - return nullptr; - - auto out_buffer = new uchar[buffer_size]; - memcpy(out_buffer, str().c_str(), buffer_size); - flush(); - - return out_buffer; -} diff --git a/common/string_util.h b/common/string_util.h index 5b373a41b..c69f01456 100644 --- a/common/string_util.h +++ b/common/string_util.h @@ -53,36 +53,4 @@ void MakeLowerString(const char *source, char *target); void RemoveApostrophes(std::string &s); void find_replace(std::string& string_subject, const std::string& search_string, const std::string& replace_string); - - -/* EQEMu: Everquest Server Emulator - - Copyright (C) 2001-2016 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 -*/ - - -namespace EQEmu -{ - class OutBuffer : public std::stringstream { - public: - inline size_t size() { return tellp(); } - void overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count); - uchar* detach(); - }; -} - #endif