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;
37 int get_contiguous_length(char *ptr)
39 int eidx = cur_idx + length;
40 if (eidx >= SIZE) eidx -= SIZE;
42 if (buf + eidx > ptr) {
43 return (buf + eidx) - ptr;
46 return (buf + SIZE) - ptr;
50 // fill by reading from the given fd, return positive if some was read or -1 on error.
51 int fill(int fd) noexcept
53 int pos = cur_idx + length;
54 if (pos >= SIZE) pos -= SIZE;
55 int max_count = std::min(SIZE - pos, SIZE - length);
56 ssize_t r = read(fd, buf + pos, max_count);
63 // fill by reading from the given fd, until at least the specified number of bytes are in
64 // the buffer. Return 0 if end-of-file reached before fill complete, or -1 on error.
65 int fill_to(int fd, int rlength) noexcept
67 while (length < rlength) {
74 // Trim the buffer to the specified length (must be less than current length)
75 void trim_to(int new_length)
80 char operator[](int idx) noexcept
82 int dest_idx = cur_idx + idx;
83 if (dest_idx > SIZE) dest_idx -= SIZE;
87 // Remove the given number of bytes from the start of the buffer.
88 void consume(int amount) noexcept
91 if (cur_idx >= SIZE) cur_idx -= SIZE;
95 // Extract bytes from the buffer. The bytes remain in the buffer.
96 void extract(char *dest, int index, int length) noexcept
99 if (index >= SIZE) index -= SIZE;
100 if (index + length > SIZE) {
102 int half = SIZE - index;
103 std::memcpy(dest, buf + index, half);
104 std::memcpy(dest + half, buf, length - half);
107 std::memcpy(dest, buf + index, length);
111 // Extract string of given length from given index
112 // Throws: std::bad_alloc on allocation failure
113 std::string extract_string(int index, int length)
116 if (index >= SIZE) index -= SIZE;
117 if (index + length > SIZE) {
118 std::string r(buf + index, SIZE - index);
119 r.insert(r.end(), buf, buf + length - (SIZE - index));
123 return std::string(buf + index, length);
127 // Append characters to the buffer. Caller must make certain there
128 // is enough space to contain the characters first.
129 void append(const char * s, int len) noexcept
131 int index = cur_idx + length;
132 if (index >= SIZE) index -= SIZE;
134 length += len; // (before we destroy len)
136 int max = SIZE - index;
137 std::memcpy(buf + index, s, std::min(max, len));
139 // Wrapped around buffer: copy the rest
142 std::memcpy(buf, s, len);