// File: crn_buffer_stream.h // See Copyright Notice and license at the end of inc/crnlib.h #pragma once #include "crn_data_stream.h" namespace crnlib { class buffer_stream : public data_stream { public: buffer_stream() : data_stream(), m_pBuf(NULL), m_size(0), m_ofs(0) { } buffer_stream(void* p, uint size) : data_stream(), m_pBuf(NULL), m_size(0), m_ofs(0) { open(p, size); } buffer_stream(const void* p, uint size) : data_stream(), m_pBuf(NULL), m_size(0), m_ofs(0) { open(p, size); } virtual ~buffer_stream() { } bool open(const void* p, uint size) { CRNLIB_ASSERT(p); close(); if ((!p) || (!size)) return false; m_opened = true; m_pBuf = (uint8*)(p); m_size = size; m_ofs = 0; m_attribs = cDataStreamSeekable | cDataStreamReadable; return true; } bool open(void* p, uint size) { CRNLIB_ASSERT(p); close(); if ((!p) || (!size)) return false; m_opened = true; m_pBuf = static_cast(p); m_size = size; m_ofs = 0; m_attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable; return true; } virtual bool close() { if (m_opened) { m_opened = false; m_pBuf = NULL; m_size = 0; m_ofs = 0; return true; } return false; } const void* get_buf() const { return m_pBuf; } void* get_buf() { return m_pBuf; } virtual const void* get_ptr() const { return m_pBuf; } virtual uint read(void* pBuf, uint len) { CRNLIB_ASSERT(pBuf && (len <= 0x7FFFFFFF)); if ((!m_opened) || (!is_readable()) || (!len)) return 0; CRNLIB_ASSERT(m_ofs <= m_size); uint bytes_left = m_size - m_ofs; len = math::minimum(len, bytes_left); if (len) memcpy(pBuf, &m_pBuf[m_ofs], len); m_ofs += len; return len; } virtual uint write(const void* pBuf, uint len) { CRNLIB_ASSERT(pBuf && (len <= 0x7FFFFFFF)); if ((!m_opened) || (!is_writable()) || (!len)) return 0; CRNLIB_ASSERT(m_ofs <= m_size); uint bytes_left = m_size - m_ofs; len = math::minimum(len, bytes_left); if (len) memcpy(&m_pBuf[m_ofs], pBuf, len); m_ofs += len; return len; } virtual bool flush() { if (!m_opened) return false; return true; } virtual uint64 get_size() { if (!m_opened) return 0; return m_size; } virtual uint64 get_remaining() { if (!m_opened) return 0; CRNLIB_ASSERT(m_ofs <= m_size); return m_size - m_ofs; } virtual uint64 get_ofs() { if (!m_opened) return 0; return m_ofs; } virtual bool seek(int64 ofs, bool relative) { if ((!m_opened) || (!is_seekable())) return false; int64 new_ofs = relative ? (m_ofs + ofs) : ofs; if (new_ofs < 0) return false; else if (new_ofs > m_size) return false; m_ofs = static_cast(new_ofs); post_seek(); return true; } private: uint8* m_pBuf; uint m_size; uint m_ofs; }; } // namespace crnlib