summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/serialise_lowlevel.cpp69
-rw-r--r--src/hir/serialise_lowlevel.hpp15
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;