#pragma once #include #include #include #include #include namespace td { class DataBuffer { private: typedef std::vector Data; Data m_Buffer; std::size_t m_ReadOffset; public: typedef Data::iterator iterator; typedef Data::const_iterator const_iterator; typedef Data::reference reference; typedef Data::const_reference const_reference; DataBuffer(); DataBuffer(const DataBuffer& other); DataBuffer(const DataBuffer& other, Data::difference_type offset); DataBuffer(DataBuffer&& other); DataBuffer(const std::string& str); DataBuffer& operator=(const DataBuffer& other); DataBuffer& operator=(DataBuffer&& other); template void Append(T data) { std::size_t size = sizeof(data); std::size_t end_pos = m_Buffer.size(); m_Buffer.resize(m_Buffer.size() + size); memcpy(&m_Buffer[end_pos], &data, size); } template DataBuffer& operator<<(T data) { // Switch to big endian //std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T)); Append(data); return *this; } DataBuffer& operator<<(std::string str) { m_Buffer.insert(m_Buffer.end(), str.begin(), str.end()); return *this; } DataBuffer& operator<<(DataBuffer& data) { m_Buffer.insert(m_Buffer.end(), data.begin(), data.end()); return *this; } DataBuffer& operator<<(const DataBuffer& data) { m_Buffer.insert(m_Buffer.end(), data.begin(), data.end()); return *this; } template DataBuffer& operator>>(T& data) { assert(m_ReadOffset + sizeof(T) <= GetSize()); data = *(reinterpret_cast(&m_Buffer[m_ReadOffset])); //std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T)); m_ReadOffset += sizeof(T); return *this; } DataBuffer& operator>>(DataBuffer& data) { data.Resize(GetSize() - m_ReadOffset); std::copy(m_Buffer.begin() + static_cast(m_ReadOffset), m_Buffer.end(), data.begin()); m_ReadOffset = m_Buffer.size(); return *this; } DataBuffer& operator>>(std::string& str) { std::size_t stringSize = strlen(reinterpret_cast(m_Buffer.data()) + m_ReadOffset) + 1; // including null character str.resize(stringSize); std::copy(m_Buffer.begin() + static_cast(m_ReadOffset), m_Buffer.begin() + static_cast(m_ReadOffset + stringSize), str.begin()); m_ReadOffset += stringSize; return *this; } void WriteSome(const char* buffer, std::size_t amount) { std::size_t end_pos = m_Buffer.size(); m_Buffer.resize(m_Buffer.size() + amount); memcpy(&m_Buffer[end_pos], buffer, amount); } void WriteSome(const std::uint8_t* buffer, std::size_t amount) { std::size_t end_pos = m_Buffer.size(); m_Buffer.resize(m_Buffer.size() + amount); memcpy(&m_Buffer[end_pos], buffer, amount); } void ReadSome(char* buffer, std::size_t amount) { assert(m_ReadOffset + amount <= GetSize()); std::copy_n(m_Buffer.begin() + static_cast(m_ReadOffset), amount, buffer); m_ReadOffset += amount; } void ReadSome(std::uint8_t* buffer, std::size_t amount) { assert(m_ReadOffset + amount <= GetSize()); std::copy_n(m_Buffer.begin() + static_cast(m_ReadOffset), amount, buffer); m_ReadOffset += amount; } void ReadSome(DataBuffer& buffer, std::size_t amount) { assert(m_ReadOffset + amount <= GetSize()); buffer.Resize(amount); std::copy_n(m_Buffer.begin() + static_cast(m_ReadOffset), amount, buffer.begin()); m_ReadOffset += amount; } void ReadSome(std::string& buffer, std::size_t amount) { assert(m_ReadOffset + amount <= GetSize()); buffer.resize(amount); std::copy_n(m_Buffer.begin() + static_cast(m_ReadOffset), amount, buffer.begin()); m_ReadOffset += amount; } void Resize(std::size_t size) { m_Buffer.resize(size); } void Reserve(std::size_t amount) { m_Buffer.reserve(amount); } void erase(iterator it) { m_Buffer.erase(it); } void Clear() { m_Buffer.clear(); m_ReadOffset = 0; } bool IsFinished() const { return m_ReadOffset >= m_Buffer.size(); } std::uint8_t* data() { return m_Buffer.data(); } const std::uint8_t* data() const { return m_Buffer.data(); } std::size_t GetReadOffset() const { return m_ReadOffset; } void SetReadOffset(std::size_t pos); std::string ToString() const; std::size_t GetSize() const; bool IsEmpty() const; std::size_t GetRemaining() const; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; reference operator[](Data::size_type i) { return m_Buffer[i]; } const_reference operator[](Data::size_type i) const { return m_Buffer[i]; } bool ReadFile(const std::string& fileName); bool WriteFile(const std::string& fileName); }; std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer); } // ns td