diff options
-rw-r--r-- | src/hir/serialise_lowlevel.cpp | 69 | ||||
-rw-r--r-- | src/hir/serialise_lowlevel.hpp | 15 |
2 files changed, 53 insertions, 31 deletions
diff --git a/src/hir/serialise_lowlevel.cpp b/src/hir/serialise_lowlevel.cpp index 1678b114..a7c1a0c7 100644 --- a/src/hir/serialise_lowlevel.cpp +++ b/src/hir/serialise_lowlevel.cpp @@ -21,52 +21,63 @@ void ::HIR::serialise::Writer::write(const void* buf, size_t len) } +::HIR::serialise::ReadBuffer::ReadBuffer(size_t cap): + m_ofs(0) +{ + m_backing.reserve(cap); +} +size_t ::HIR::serialise::ReadBuffer::read(void* dst, size_t len) +{ + size_t rem = m_backing.size() - m_ofs; + if( rem >= len ) + { + memcpy(dst, m_backing.data() + m_ofs, len); + m_ofs += len; + return len; + } + else + { + memcpy(dst, m_backing.data() + m_ofs, rem); + m_ofs = m_backing.size(); + return rem; + } +} +void ::HIR::serialise::ReadBuffer::populate(::std::istream& is) +{ + m_backing.resize( m_backing.capacity(), 0 ); + is.read(reinterpret_cast<char*>(m_backing.data()), m_backing.capacity()); + m_backing.resize( is.gcount() ); + m_ofs = 0; +} + ::HIR::serialise::Reader::Reader(const ::std::string& filename): m_backing( filename ), - m_buffer(), - m_buffer_ofs(0) + m_buffer(1024) { - m_buffer.reserve(1024); m_is.push( ::boost::iostreams::zlib_decompressor() ); m_is.push( m_backing ); } void ::HIR::serialise::Reader::read(void* buf, size_t len) { - size_t rem = m_buffer.size() - m_buffer_ofs; - if( m_buffer_ofs < m_buffer.size() ) { - if( len <= rem ) { - memcpy(buf, m_buffer.data() + m_buffer_ofs, len); - m_buffer_ofs += len; - return ; - } - else { - memcpy(buf, m_buffer.data() + m_buffer_ofs, rem); - m_buffer_ofs += rem; - len -= rem; - } + auto used = m_buffer.read(buf, len); + if( used == len ) { + return ; } - // m_bufer_ofs == m_buffer.size() + buf = reinterpret_cast<uint8_t*>(buf) + used; + len -= used; if( len >= m_buffer.capacity() ) { - // If the new read is longer than the buffer size, skip the buffer. m_is.read(reinterpret_cast<char*>(buf), len); + if( !m_is ) + throw ""; } else { - m_buffer.resize( m_buffer.capacity(), 0 ); - m_buffer_ofs = 0; - m_is.read(reinterpret_cast<char*>(m_buffer.data()), m_buffer.capacity()); - size_t dat_len = m_is.gcount(); - - if( dat_len == 0 ) - throw ""; - if( dat_len < len ) + m_buffer.populate( m_is ); + used = m_buffer.read(buf, len); + if( used != len ) throw ""; - - m_buffer.resize( dat_len ); - memcpy(reinterpret_cast<uint8_t*>(buf) + rem, m_buffer.data(), len); - m_buffer_ofs = len; } } diff --git a/src/hir/serialise_lowlevel.hpp b/src/hir/serialise_lowlevel.hpp index c1e4a4c8..39c7867d 100644 --- a/src/hir/serialise_lowlevel.hpp +++ b/src/hir/serialise_lowlevel.hpp @@ -123,13 +123,24 @@ public: }; +class ReadBuffer +{ + ::std::vector<uint8_t> m_backing; + unsigned int m_ofs; +public: + ReadBuffer(size_t size); + + size_t capacity() const { return m_backing.capacity(); } + size_t read(void* dst, size_t len); + void populate(::std::istream& is); +}; + class Reader { ::std::ifstream m_backing; ::boost::iostreams::filtering_istream m_is; - ::std::vector<uint8_t> m_buffer; - unsigned int m_buffer_ofs; + ReadBuffer m_buffer; public: Reader(const ::std::string& path); Reader(const Writer&) = delete; |