Fix some of the comments on StreamBuffer
This commit is contained in:
@@ -89,6 +89,13 @@ void StreamBuffer::make_space_slow(int64_t bytes) {
|
|||||||
write_cursor_ = buf_lo_ + data_size;
|
write_cursor_ = buf_lo_ + data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamBuffer::wrote_space(int64_t bytes) {
|
||||||
|
int64_t available = buf_hi_ - write_cursor_;
|
||||||
|
assert(bytes >= 0);
|
||||||
|
assert(available >= bytes);
|
||||||
|
write_cursor_ += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
char *StreamBuffer::get_overwrite(int64_t size, int64_t write_count_after) {
|
char *StreamBuffer::get_overwrite(int64_t size, int64_t write_count_after) {
|
||||||
int64_t write_count_before = write_count_after - size;
|
int64_t write_count_before = write_count_after - size;
|
||||||
assert(write_count_before >= total_reads());
|
assert(write_count_before >= total_reads());
|
||||||
@@ -159,7 +166,6 @@ static inline bool safe_to_cast_to_uint64(uint64_t vv) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StreamBuffer::write_bytes(const char *s, int64_t len) {
|
void StreamBuffer::write_bytes(const char *s, int64_t len) {
|
||||||
make_space(len);
|
make_space(len);
|
||||||
memcpy(write_cursor_, s, len);
|
memcpy(write_cursor_, s, len);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// const int bufsize = 16384;
|
// const int bufsize = 16384;
|
||||||
//
|
//
|
||||||
// // Allocate transient space in the streambuffer.
|
// // Allocate transient space in the streambuffer.
|
||||||
// char *space = streambuffer.alloc_space(bufsize);
|
// char *space = streambuffer.make_space(bufsize);
|
||||||
//
|
//
|
||||||
// // Call the linux 'read' function.
|
// // Call the linux 'read' function.
|
||||||
// ssize_t bytes_read = read(fd, space, bufsize);
|
// ssize_t bytes_read = read(fd, space, bufsize);
|
||||||
@@ -25,17 +25,17 @@
|
|||||||
// // Append the bytes read to the streambuffer.
|
// // Append the bytes read to the streambuffer.
|
||||||
// streambuffer.wrote_space(bytes_read);
|
// streambuffer.wrote_space(bytes_read);
|
||||||
//
|
//
|
||||||
// Now, let's dig into the semantics of this. The method 'alloc_space' MUST be
|
// The make_space operation allocates an array of bytes where the data can be
|
||||||
// followed by 'wrote_space'. It is an error to invoke these methods unless you
|
// written, and returns a pointer to that array of bytes. The read operation
|
||||||
// do them in that sequence. Together, these two methods count as a single
|
// fills some or all of the allocated bytes. Finally, the wrote_space operation
|
||||||
// 'write' operation into the StreamBuffer.
|
// notifies the StreamBuffer that some of the bytes have been filled with data.
|
||||||
|
// These bytes are appended to the StreamBuffer.
|
||||||
//
|
//
|
||||||
// 'alloc_space' allocates a block of bytes within the StreamBuffer. The
|
// The pointer returned by 'make_space' is only valid until you mutate the
|
||||||
// pointer returned here is only valid until the 'wrote_space' operation. The
|
// StreamBuffer. Therefore, you should call 'make_space', then immediately fill
|
||||||
// method 'wrote_space' tells the StreamBuffer that the space has been populated
|
// the bytes. It is imperative that 'wrote_space' be the first mutator after
|
||||||
// with the specified amount of data. The data is then officially appended to
|
// 'make_space.' You should think of 'make_space' followed by 'wrote_space' as
|
||||||
// the StreamBuffer. Again, the two methods 'alloc_space' followed by
|
// a single two-phase operation.
|
||||||
// 'wrote_space' together count as a single write operation.
|
|
||||||
//
|
//
|
||||||
// THE OVERWRITE_INT METHODS:
|
// THE OVERWRITE_INT METHODS:
|
||||||
//
|
//
|
||||||
@@ -101,21 +101,6 @@
|
|||||||
// When you call read_bytes, it returns a pointer to a block of bytes. This
|
// When you call read_bytes, it returns a pointer to a block of bytes. This
|
||||||
// pointer only remains valid until you do a 'write' into the stream.
|
// pointer only remains valid until you do a 'write' into the stream.
|
||||||
//
|
//
|
||||||
// NESTED DECODING
|
|
||||||
//
|
|
||||||
// Here is an interesting construct:
|
|
||||||
//
|
|
||||||
// // Read a message from the stream.
|
|
||||||
// size_t len = streambuffer.read_int32()
|
|
||||||
// const char *bytes = streambuffer.read_bytes(len);
|
|
||||||
//
|
|
||||||
// // Construct another stream object to decode the message.
|
|
||||||
// StreamBuffer substream(bytes, len);
|
|
||||||
// decode(substream);
|
|
||||||
//
|
|
||||||
// This is perfectly valid and a potentially convenient way to parse the
|
|
||||||
// contents of a message.
|
|
||||||
//
|
|
||||||
// UNREADING BYTES
|
// UNREADING BYTES
|
||||||
//
|
//
|
||||||
// It's possible to 'unread' bytes that you've already read from a stream. This
|
// It's possible to 'unread' bytes that you've already read from a stream. This
|
||||||
@@ -167,6 +152,23 @@
|
|||||||
// total_writes for such a buffer returns the 'len' value that you initialized
|
// total_writes for such a buffer returns the 'len' value that you initialized
|
||||||
// the buffer with.
|
// the buffer with.
|
||||||
//
|
//
|
||||||
|
// NESTED DECODING
|
||||||
|
//
|
||||||
|
// Here is an interesting construct:
|
||||||
|
//
|
||||||
|
// // Read a message from the stream.
|
||||||
|
// size_t len = streambuffer.read_int32()
|
||||||
|
// const char *bytes = streambuffer.read_bytes(len);
|
||||||
|
//
|
||||||
|
// // Construct another stream object to decode the message.
|
||||||
|
// StreamBuffer substream(bytes, len);
|
||||||
|
// decode(substream);
|
||||||
|
//
|
||||||
|
// This is perfectly valid and a potentially convenient way to parse the
|
||||||
|
// contents of a message. Note that the substream contains a pointer to
|
||||||
|
// the parent stream's buffer, and therefore, data corruption will occur
|
||||||
|
// if you mutate the parent stream while reading the substream.
|
||||||
|
//
|
||||||
// USING A STREAMBUFFER TO READ AN ENTIRE FILE
|
// USING A STREAMBUFFER TO READ AN ENTIRE FILE
|
||||||
//
|
//
|
||||||
// If you wish to read an entire file and store the file contents in a
|
// If you wish to read an entire file and store the file contents in a
|
||||||
@@ -281,7 +283,9 @@ public:
|
|||||||
|
|
||||||
// Read a block of bytes from the buffer.
|
// Read a block of bytes from the buffer.
|
||||||
//
|
//
|
||||||
// Throws StreamEof if the specified number of bytes aren't present.
|
// Caution: the pointer returned is a pointer to the stream's buffer. It is
|
||||||
|
// only valid until you mutate the buffer. Throws StreamEof if the specified
|
||||||
|
// number of bytes aren't present.
|
||||||
//
|
//
|
||||||
const char *read_bytes(int64_t bytes);
|
const char *read_bytes(int64_t bytes);
|
||||||
|
|
||||||
@@ -409,12 +413,16 @@ private:
|
|||||||
void init(bool fixed, bool owned, char *buf, int64_t size);
|
void init(bool fixed, bool owned, char *buf, int64_t size);
|
||||||
|
|
||||||
// Make the specified amount of space in the buffer for writing.
|
// Make the specified amount of space in the buffer for writing.
|
||||||
void make_space(int64_t bytes) {
|
// Return a pointer to the space.
|
||||||
|
char *make_space(int64_t bytes) {
|
||||||
int64_t available = buf_hi_ - write_cursor_;
|
int64_t available = buf_hi_ - write_cursor_;
|
||||||
if (available < bytes) make_space_slow(bytes);
|
if (available < bytes) make_space_slow(bytes);
|
||||||
|
return write_cursor_;
|
||||||
}
|
}
|
||||||
void make_space_slow(int64_t bytes);
|
void make_space_slow(int64_t bytes);
|
||||||
|
|
||||||
|
void wrote_space(int64_t bytes);
|
||||||
|
|
||||||
// Make sure the specified number of bytes are available to read.
|
// Make sure the specified number of bytes are available to read.
|
||||||
void check_available(int64_t bytes) {
|
void check_available(int64_t bytes) {
|
||||||
int64_t avail = write_cursor_ - read_cursor_;
|
int64_t avail = write_cursor_ - read_cursor_;
|
||||||
|
|||||||
Reference in New Issue
Block a user