bool InflaterIOChannel::seek(std::streampos pos) { if (m_error) { log_debug("Inflater is in error condition"); return false; } // If we're seeking backwards, then restart from the beginning. if (pos < m_logical_stream_pos) { log_debug("inflater reset due to seek back from %d to %d", m_logical_stream_pos, pos ); reset(); } unsigned char temp[ZBUF_SIZE]; // Now seek forwards, by just reading data in blocks. while (m_logical_stream_pos < pos) { std::streamsize to_read = pos - m_logical_stream_pos; assert(to_read > 0); std::streamsize readNow = std::min<std::streamsize>(to_read, ZBUF_SIZE); assert(readNow > 0); std::streamsize bytes_read = inflate_from_stream(temp, readNow); assert(bytes_read <= readNow); if (bytes_read == 0) { // Trouble; can't seek any further. log_debug("Trouble: can't seek any further.. "); return false; break; } } assert(m_logical_stream_pos == pos); return true; }
// See dox in IOChannel virtual std::streamsize read(void* dst, std::streamsize bytes) { if (m_error) return 0; return inflate_from_stream(dst, bytes); }
void InflaterIOChannel::go_to_end() { if (m_error) { throw IOException("InflaterIOChannel is in error condition, " "can't seek to end"); } // Keep reading until we can't read any more. unsigned char temp[ZBUF_SIZE]; // Seek forwards. for (;;) { const std::streamsize bytes_read = inflate_from_stream(temp, ZBUF_SIZE); if (!bytes_read) { // We've seeked as far as we can. break; } } }