#ifndef MCLIB_COMMON_DATA_BUFFER_H_ #define MCLIB_COMMON_DATA_BUFFER_H_ #include #include #include #include #include namespace td{ class DataBuffer{ private: typedef std::vector Data; Data m_Buffer; std::size_t m_ReadOffset = 0; 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, std::size_t 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 = *(T*)&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() + m_ReadOffset, m_Buffer.end(), data.begin()); m_ReadOffset = m_Buffer.size(); return *this; } DataBuffer& operator>>(std::string& str){ std::size_t stringSize = strlen((const char*) m_Buffer.data() + m_ReadOffset) + 1; // including null character str.resize(stringSize); std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.begin() + m_ReadOffset + stringSize, str.begin()); m_ReadOffset += stringSize; return *this; } void ReadSome(char* buffer, std::size_t amount){ assert(m_ReadOffset + amount <= GetSize()); std::copy_n(m_Buffer.begin() + 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() + 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() + 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() + 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 #endif