#ifndef __PROCESSOR_BUFFER_HPP__ #define __PROCESSOR_BUFFER_HPP__ #include #include #include #include #ifdef PROCESSOR_BUFFER_USE_EXCEPTIONS #define RETURN_OR_EXCEPT(code) throw Buffer::Exception(code) #else #define RETURN_OR_EXCEPT(code) return code #endif class IBuffer { public: virtual ~IBuffer() = default; }; template class Buffer : public IBuffer { public: enum Result { Ok=0, Err_InvalidSize=1 }; class Exception : public std::exception { public: Exception(Result code) : std::exception() , m_code(code) { } const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW { static std::string r = "Return code = " + std::to_string(m_code); return r.c_str(); } Result m_code; }; Buffer(size_t capacity); ~Buffer(); size_t len(); size_t capacity(); void clear(); T* data_w(); T* data_r(); size_t write(const T* pData, size_t len); size_t read(T* pData, size_t len); Result consume(size_t len); Result produce(size_t len); void print(const char *prefix); private: size_t m_capacity; size_t m_len; size_t m_wi; size_t m_ri; size_t m_bid; T *m_data[2]; void make_contigious() { if (m_len == 0) { return; } size_t cont_len = std::min(m_capacity - m_ri, m_len); if (cont_len < m_len) { m_wi = m_len; read(bufferStdBy(), m_len); m_ri = 0; m_len = m_wi; m_bid = !m_bid & 1; } } T *bufferActive() { return m_data[m_bid]; } T *bufferStdBy() { return m_data[!m_bid & 1]; } }; #include "Buffer.tcc" #endif // __PROCESSOR_BUFFER_HPP__