X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcpbuffer.h;h=1478b740a9ac2512c971f85e61b0e962ab45279e;hb=36d2781d9f4890dda54419d38679d2da3d04b7bd;hp=94132ca2db001f224e36e5f0bea3e53743811df3;hpb=aa71ea68bce0819b73cce0a060b685ccf8012d6c;p=oweals%2Fdinit.git diff --git a/src/cpbuffer.h b/src/cpbuffer.h index 94132ca..1478b74 100644 --- a/src/cpbuffer.h +++ b/src/cpbuffer.h @@ -4,9 +4,9 @@ #include // control protocol buffer, a circular buffer with 1024-byte capacity. -class CPBuffer +template class CPBuffer { - char buf[1024]; + char buf[SIZE]; int cur_idx = 0; int length = 0; // number of elements in the buffer @@ -16,12 +16,43 @@ class CPBuffer return length; } + int get_free() noexcept + { + return SIZE - length; + } + + char * get_ptr(int index) + { + int pos = cur_idx + index; + if (pos >= SIZE) pos -= SIZE; + + return &buf[pos]; + } + + char * get_buf_base() + { + return buf; + } + + int get_contiguous_length(char *ptr) + { + int eidx = cur_idx + length; + if (eidx >= SIZE) eidx -= SIZE; + + if (buf + eidx > ptr) { + return (buf + eidx) - ptr; + } + else { + return (buf + SIZE) - ptr; + } + } + // fill by reading from the given fd, return positive if some was read or -1 on error. int fill(int fd) noexcept { int pos = cur_idx + length; - if (pos >= 1024) pos -= 1024; - int max_count = std::min(1024 - pos, 1024 - length); + if (pos >= SIZE) pos -= SIZE; + int max_count = std::min(SIZE - pos, SIZE - length); ssize_t r = read(fd, buf + pos, max_count); if (r >= 0) { length += r; @@ -29,9 +60,9 @@ class CPBuffer return r; } - // fill by readin from the given fd, until at least the specified number of bytes are in + // fill by reading from the given fd, until at least the specified number of bytes are in // the buffer. Return 0 if end-of-file reached before fill complete, or -1 on error. - int fillTo(int fd, int rlength) noexcept + int fill_to(int fd, int rlength) noexcept { while (length < rlength) { int r = fill(fd); @@ -40,27 +71,35 @@ class CPBuffer return 1; } - int operator[](int idx) noexcept + // Trim the buffer to the specified length (must be less than current length) + void trim_to(int new_length) + { + length = new_length; + } + + char operator[](int idx) noexcept { int dest_idx = cur_idx + idx; - if (dest_idx > 1024) dest_idx -= 1024; + if (dest_idx > SIZE) dest_idx -= SIZE; return buf[dest_idx]; } + // Remove the given number of bytes from the start of the buffer. void consume(int amount) noexcept { cur_idx += amount; - if (cur_idx >= 1024) cur_idx -= 1024; + if (cur_idx >= SIZE) cur_idx -= SIZE; length -= amount; } + // Extract bytes from the buffer. The bytes remain in the buffer. void extract(char *dest, int index, int length) noexcept { index += cur_idx; - if (index >= 1024) index -= 1024; - if (index + length > 1024) { + if (index >= SIZE) index -= SIZE; + if (index + length > SIZE) { // wrap-around copy - int half = 1024 - index; + int half = SIZE - index; std::memcpy(dest, buf + index, half); std::memcpy(dest + half, buf, length - half); } @@ -69,21 +108,40 @@ class CPBuffer } } - // Extract string of give length from given index + // Extract string of given length from given index // Throws: std::bad_alloc on allocation failure std::string extract_string(int index, int length) { index += cur_idx; - if (index >= 1024) index -= 1024; - if (index + length > 1024) { - std::string r(buf + index, 1024 - index); - r.insert(r.end(), buf, buf + length - (1024 - index)); + if (index >= SIZE) index -= SIZE; + if (index + length > SIZE) { + std::string r(buf + index, SIZE - index); + r.insert(r.end(), buf, buf + length - (SIZE - index)); return r; } else { return std::string(buf + index, length); } } + + // Append characters to the buffer. Caller must make certain there + // is enough space to contain the characters first. + void append(const char * s, int len) noexcept + { + int index = cur_idx + length; + if (index >= SIZE) index -= SIZE; + + length += len; // (before we destroy len) + + int max = SIZE - index; + std::memcpy(buf + index, s, std::min(max, len)); + if (len > max) { + // Wrapped around buffer: copy the rest + s += max; + len -= max; + std::memcpy(buf, s, len); + } + } }; #endif