void flush() { if (!m_open) return; size_t n; if ((n = m_buf.size()) > 0) { m_file.write(m_buf.read(n), n); m_buf.crunch(); } }
/// open file for reading void open(const std::string& a_fname) { if (m_open) return; // make sure exception thrown in case of error m_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); m_file.open(a_fname.c_str(), std::ios::in | std::ios::binary); // further read can set failbit in case there is not enough data // this case should not throw an exception in our class m_file.exceptions(std::ifstream::badbit); m_open = true; m_fname = a_fname; m_buf.reset(); BOOST_ASSERT(m_buf.capacity() > 0); }
void open(const std::string& a_fname, bool a_append = false) { using std::ios; using std::ios_base; if (m_open) return; m_file.exceptions(ios::failbit | ios::badbit); ios_base::openmode l_mode = ios::out | ios::binary; if (a_append) l_mode |= ios::app; else l_mode |= ios::trunc; m_file.open(a_fname.c_str(), l_mode); m_offset = m_file.tellp(); m_open = true; m_fname = a_fname; m_buf.reset(); BOOST_ASSERT(m_buf.capacity() > 0); }
/// read portion of file into internal buffer /// if a_crunch == true, crunch buffer before reading bool read(bool a_crunch = true) { if (!m_open || !m_file.is_open()) return false; if (a_crunch) m_buf.crunch(); while (true) { BOOST_ASSERT(m_buf.capacity() > 0); m_file.read(m_buf.wr_ptr(), m_buf.capacity()); int n = m_file.gcount(); if (n == 0) { if (m_file.good()) continue; if (m_file.eof()) return false; // this should never happen since we have set badbit throw io_error(errno, "Unexpected error reading ", m_fname); } m_buf.commit(n); return true; } }
void commit(size_t n) { m_buf.commit(n); }
char* wr_ptr() { return m_buf.wr_ptr(); }
size_t capacity() const { return m_buf.capacity(); }
/// confirm consuming of n bytes void commit(size_t n) { m_buf.read(n); }
/// current read pointer. const char* rd_ptr() const { return m_buf.rd_ptr(); }
/// current number of bytes available to read. size_t size() const { return m_buf.size(); }