Polish the streambuffer API a bit

This commit is contained in:
2021-07-19 17:32:24 -04:00
parent f8f8a9843f
commit 08ca274444
5 changed files with 303 additions and 195 deletions

View File

@@ -237,6 +237,130 @@ public:
};
class StreamBuffer {
public:
// Construct an empty buffer.
StreamBuffer();
// Construct an empty buffer, preallocate the specified amount of space.
StreamBuffer(int64_t size, bool fixed_size);
// Construct a streambuffer that reads from an external block of bytes.
StreamBuffer(const char *s, int64_t len);
// Delete a StreamBuffer.
~StreamBuffer();
// Get the total number of bytes ever read from this buffer.
int64_t read_count() const;
// Get the total number of bytes ever written to this buffer.
int64_t write_count() const;
// Delete all data and (if not fixed-size) free the buffer.
// Also resets the read and write counts.
void clear();
// Write block of bytes into the buffer.
//
// Caution: this function doesn't write the length!
// It just writes the bytes.
//
void write_bytes(const char *bytes, int64_t len);
// Read a block of bytes from the buffer.
//
// May throw StreamEof if the specified number of bytes aren't present.
//
const char *read_bytes(int64_t bytes);
// Write integers and floats into the buffer.
//
// Note that integral parameters are all 64 bits. That's so that I can do
// runtime error checking to verify that the numbers are all in-range.
//
void write_int8(int64_t v);
void write_int16(int64_t v);
void write_int32(int64_t v);
void write_int64(int64_t v);
void write_uint8(uint64_t v);
void write_uint16(uint64_t v);
void write_uint32(uint64_t v);
void write_uint64(uint64_t v);
void write_float(float f);
void write_double(double d);
// Read fixed-size integers from the buffer.
//
// May throw StreamEof if the specified number of bytes aren't present.
//
int8_t read_int8();
int16_t read_int16();
int32_t read_int32();
int64_t read_int64();
uint8_t read_uint8() { return read_int8(); }
uint16_t read_uint16() { return read_int16(); }
uint32_t read_uint32() { return read_int32(); }
uint64_t read_uint64() { return read_int64(); }
float read_float();
double read_double();
// Write other types into the buffer.
//
// Note that strings are preceded by a length field. Reading
// a string works by reading the length field, and then reading
// the correct number of bytes.
//
void write_bool(bool b) { write_int8(b ? 1 : 0); }
void write_hashvalue(const util::HashValue &hv);
void write_string(const std::string &s);
// Read other types from the buffer.
//
// May throw StreamEof if the specified number of bytes aren't present.
// Read string with a length limit will throw 'StreamCorruption' if the
// length is too long.
//
bool read_bool() { return read_int8(); }
util::HashValue read_hashvalue();
std::string read_string();
std::string read_string_limit(int64_t max_allowed);
// Overwrite values previously written to the buffer.
//
// See the comment at the top of this file for an explanation.
//
void overwrite_int8(int64_t write_count_after, int64_t v);
void overwrite_int16(int64_t write_count_after, int64_t v);
void overwrite_int32(int64_t write_count_after, int64_t v);
void overwrite_int64(int64_t write_count_after, int64_t v);
void overwrite_uint8(int64_t write_count_after, uint64_t v);
void overwrite_uint16(int64_t write_count_after, uint64_t v);
void overwrite_uint32(int64_t write_count_after, uint64_t v);
void overwrite_uint64(int64_t write_count_after, uint64_t v);
// Return true if the buffer is empty.
bool at_eof();
// Verify that the buffer is empty, if not, throw StreamCorruption.
void verify_eof();
// Rewind the read cursor to a previous position.
void unread_to(int64_t read_count);
// Rewind the write cursor to a previous position.
void unwrite_to(int64_t write_count);
// Calculate a noncryptographic but good hash of what's in the buffer.
util::HashValue hash() const;
// Use the stream buffer as a lua_Writer.
static int lua_writer(lua_State *L, const void* p, size_t sz, void* ud);
void *lua_writer_ud();
// Use the stream buffer as a lua_Reader.
static const char *lua_reader(lua_State *L, void *data, size_t *size);
void *lua_reader_ud(int64_t bytes);
private:
// Start and end of the allocated block.
char *buf_lo_;
@@ -280,115 +404,10 @@ private:
// Implementation for the overwrite_int functions.
char *get_overwrite(int64_t size, int64_t write_count_after);
// This is mainly for unit testing.
// This is for unit testing.
bool layout_is(int64_t a, int64_t b, int64_t c);
friend int unittests_streambuffer(lua_State *L);
public:
// Construct an empty buffer.
StreamBuffer();
// Construct an empty buffer, preallocate the specified amount of space.
StreamBuffer(int64_t size, bool fixed_size);
// Construct a streambuffer that reads from an external block of bytes.
StreamBuffer(const char *s, int64_t len);
// Delete a StreamBuffer.
~StreamBuffer();
// Get the total number of bytes ever read from this buffer.
int64_t read_count() const;
// Get the total number of bytes ever written to this buffer.
int64_t write_count() const;
// Delete all data and (if not fixed-size) free the buffer.
// Also resets the read and write counts.
void clear();
// Alloc_space and wrote_space need to be invoked together.
char *alloc_space(int64_t bytes);
void wrote_space(int64_t bytes);
// Write numbers into the buffer.
void write_int8(int8_t v);
void write_int16(int16_t v);
void write_int32(int32_t v);
void write_int64(int64_t v);
void write_float(float f);
void write_double(double d);
void write_hashvalue(const util::HashValue &hv);
void write_uint8(uint8_t v) { write_int8(v); }
void write_uint16(uint16_t v) { write_int16(v); }
void write_uint32(uint32_t v) { write_int32(v); }
void write_uint64(uint64_t v) { write_int64(v); }
void write_size(size_t sz) { write_int64(sz); }
void write_bool(bool b) { write_int8(b ? 1 : 0); }
// Write strings or blocks of bytes into the buffer.
void write_string(const std::string &s);
void write_bytes(const char *bytes, int64_t len);
void write_ztbytes(const char *bytes);
// Overwrite values previously written to the buffer.
void overwrite_int8(int64_t write_count_after, int8_t v);
void overwrite_int16(int64_t write_count_after, int16_t v);
void overwrite_int32(int64_t write_count_after, int32_t v);
void overwrite_int64(int64_t write_count_after, int64_t v);
void overwrite_uint8(int64_t write_count_after, uint8_t v) { overwrite_int8(write_count_after, v); }
void overwrite_uint16(int64_t write_count_after, uint16_t v) { overwrite_int16(write_count_after, v); }
void overwrite_uint32(int64_t write_count_after, uint32_t v) { overwrite_int32(write_count_after, v); }
void overwrite_uint64(int64_t write_count_after, uint64_t v) { overwrite_int64(write_count_after, v); }
// Read numbers from the buffer. May throw StreamEof.
int8_t read_int8();
int16_t read_int16();
int32_t read_int32();
int64_t read_int64();
float read_float();
double read_double();
util::HashValue read_hashvalue();
uint8_t read_uint8() { return read_int8(); }
uint16_t read_uint16() { return read_int16(); }
uint32_t read_uint32() { return read_int32(); }
uint64_t read_uint64() { return read_int64(); }
bool read_bool() { return read_int8(); }
// May throw StreamEof or StreamCorruption.
size_t read_size();
size_t read_size_limit(size_t limit);
// Read a string of no more than the specified length.
// May throw StreamEof or StreamCorruption.
std::string read_string();
std::string read_string_limit(int64_t max_allowed);
// Read a block of bytes. May throw StreamEof.
const char *read_bytes(int64_t bytes);
// Return true if the buffer is empty.
bool at_eof();
// Verify that the buffer is empty, if not, throw StreamCorruption.
void verify_eof();
// Rewind the read cursor to a previous position.
void unread_to(int64_t read_count);
// Rewind the write cursor to a previous position.
void unwrite_to(int64_t write_count);
// Calculate a noncryptographic but good hash of what's in the buffer.
util::HashValue hash() const;
// Use the stream buffer as a lua_Writer.
static int lua_writer(lua_State *L, const void* p, size_t sz, void* ud);
void *lua_writer_ud();
// Use the stream buffer as a lua_Reader.
static const char *lua_reader(lua_State *L, void *data, size_t *size);
void *lua_reader_ud(int64_t bytes);
};