blob: 272533bef17a56c9405237485865f85ee6f082dd [file] [log] [blame]
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
#ifndef RR_COMPRESSED_READER_H_
#define RR_COMPRESSED_READER_H_
#include <pthread.h>
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "ScopedFd.h"
namespace rr {
/**
* CompressedReader opens an input file written by CompressedWriter
* and reads data from it. Currently data is decompressed by the thread that
* calls read().
*/
class CompressedReader {
public:
CompressedReader(const std::string& filename);
CompressedReader(const CompressedReader& aOther);
~CompressedReader();
bool good() const { return !error; }
bool at_end() const {
const_cast<CompressedReader*>(this)->process_skip();
return eof && buffer_read_pos == buffer.size();
}
// Returns true if successful. Otherwise there's an error and good()
// will be false.
bool read(void* data, size_t size);
// Returns pointer/size of some buffered data. Does not change the state.
// Returns zero size if at EOF.
bool get_buffer(const uint8_t** data, size_t* size);
// Advances the read position by the given size.
void skip(size_t size) {
buffer_skip_bytes += size;
}
void rewind();
void close();
/**
* Save the current position. Nested saves are not allowed.
*/
void save_state();
/**
* Restore previously saved position.
*/
void restore_state();
/**
* Discard saved position
*/
void discard_state();
/**
* Gathers stats on the file stream. These are independent of what's
* actually been read.
*/
uint64_t uncompressed_bytes() const;
uint64_t compressed_bytes() const;
protected:
void process_skip();
bool refill_buffer(size_t* skip_bytes = nullptr);
/* Our fd might be the dup of another fd, so we can't rely on its current file
position.
Instead track the current position in fd_offset and use pread. */
uint64_t fd_offset;
std::shared_ptr<ScopedFd> fd;
bool error;
bool eof;
std::vector<uint8_t> buffer;
// within `buffer`
size_t buffer_read_pos;
size_t buffer_skip_bytes;
bool have_saved_state;
bool have_saved_buffer;
uint64_t saved_fd_offset;
std::vector<uint8_t> saved_buffer;
size_t saved_buffer_read_pos;
};
} // namespace rr
#endif /* RR_COMPRESSED_READER_H_ */