6 // control protocol buffer, a circular buffer with 1024-byte capacity.
7 template <int SIZE> class CPBuffer
11 int length = 0; // number of elements in the buffer
14 int get_length() noexcept
19 int get_free() noexcept
24 char * get_ptr(int index)
26 int pos = cur_idx + index;
27 if (pos >= SIZE) pos -= SIZE;
32 int get_contiguous_length(char *ptr)
34 int eidx = cur_idx + length;
35 if (eidx >= SIZE) eidx -= SIZE;
37 if (buf + eidx > ptr) {
38 return (buf + eidx) - ptr;
41 return (buf + SIZE) - ptr;
45 // fill by reading from the given fd, return positive if some was read or -1 on error.
46 int fill(int fd) noexcept
48 int pos = cur_idx + length;
49 if (pos >= SIZE) pos -= SIZE;
50 int max_count = std::min(SIZE - pos, SIZE - length);
51 ssize_t r = read(fd, buf + pos, max_count);
58 // fill by reading from the given fd, until at least the specified number of bytes are in
59 // the buffer. Return 0 if end-of-file reached before fill complete, or -1 on error.
60 int fill_to(int fd, int rlength) noexcept
62 while (length < rlength) {
69 // Trim the buffer to the specified length (must be less than current length)
70 void trim_to(int new_length)
75 char operator[](int idx) noexcept
77 int dest_idx = cur_idx + idx;
78 if (dest_idx > SIZE) dest_idx -= SIZE;
82 // Remove the given number of bytes from the start of the buffer.
83 void consume(int amount) noexcept
86 if (cur_idx >= SIZE) cur_idx -= SIZE;
90 // Extract bytes from the buffer. The bytes remain in the buffer.
91 void extract(char *dest, int index, int length) noexcept
94 if (index >= SIZE) index -= SIZE;
95 if (index + length > SIZE) {
97 int half = SIZE - index;
98 std::memcpy(dest, buf + index, half);
99 std::memcpy(dest + half, buf, length - half);
102 std::memcpy(dest, buf + index, length);
106 // Extract string of given length from given index
107 // Throws: std::bad_alloc on allocation failure
108 std::string extract_string(int index, int length)
111 if (index >= SIZE) index -= SIZE;
112 if (index + length > SIZE) {
113 std::string r(buf + index, SIZE - index);
114 r.insert(r.end(), buf, buf + length - (SIZE - index));
118 return std::string(buf + index, length);
122 // Append characters to the buffer. Caller must make certain there
123 // is enough space to contain the characters first.
124 void append(const char * s, int len) noexcept
126 int index = cur_idx + length;
127 if (index >= SIZE) index -= SIZE;
129 length += len; // (before we destroy len)
131 int max = SIZE - index;
132 std::memcpy(buf + index, s, std::min(max, len));
134 // Wrapped around buffer: copy the rest
137 std::memcpy(buf, s, len);