7 #include "baseproc-sys.h"
9 // control protocol buffer, a circular buffer with fixed capacity.
10 template <int SIZE> class cpbuffer
14 int length = 0; // number of elements in the buffer
17 int get_length() noexcept
22 int get_free() noexcept
27 char * get_ptr(int index)
29 int pos = cur_idx + index;
30 if (pos >= SIZE) pos -= SIZE;
40 int get_contiguous_length(char *ptr)
42 int eidx = cur_idx + length;
43 if (eidx >= SIZE) eidx -= SIZE;
45 if (buf + eidx > ptr) {
46 return (buf + eidx) - ptr;
49 return (buf + SIZE) - ptr;
53 // Fill by reading from the given fd, return positive if some was read or -1 on error.
54 int fill(int fd) noexcept
56 int pos = cur_idx + length;
57 if (pos >= SIZE) pos -= SIZE;
58 int max_count = std::min(SIZE - pos, SIZE - length);
59 ssize_t r = bp_sys::read(fd, buf + pos, max_count);
66 // Fill by reading up to the specified amount of bytes from the given fd,
67 // Return is the number of bytes read, 0 on end-of-file or -1 on error.
68 int fill(int fd, int limit) noexcept
70 int pos = cur_idx + length;
71 if (pos >= SIZE) pos -= SIZE;
72 int max_count = std::min(SIZE - pos, SIZE - length);
73 max_count = std::min(max_count, limit);
74 ssize_t r = bp_sys::read(fd, buf + pos, max_count);
81 // fill by reading from the given fd, until at least the specified number of bytes are in
82 // the buffer. Return 0 if end-of-file reached before fill complete, or -1 on error.
83 int fill_to(int fd, int rlength) noexcept
85 while (length < rlength) {
92 // Trim the buffer to the specified length (must be less than current length)
93 void trim_to(int new_length)
98 char operator[](int idx) noexcept
100 int dest_idx = cur_idx + idx;
101 if (dest_idx > SIZE) dest_idx -= SIZE;
102 return buf[dest_idx];
105 // Remove the given number of bytes from the start of the buffer.
106 void consume(int amount) noexcept
109 if (cur_idx >= SIZE) cur_idx -= SIZE;
113 // Extract bytes from the buffer. The bytes remain in the buffer.
114 void extract(char *dest, int index, int length) noexcept
117 if (index >= SIZE) index -= SIZE;
118 if (index + length > SIZE) {
120 int half = SIZE - index;
121 std::memcpy(dest, buf + index, half);
122 std::memcpy(dest + half, buf, length - half);
125 std::memcpy(dest, buf + index, length);
129 // Extract string of given length from given index
130 // Throws: std::bad_alloc on allocation failure
131 std::string extract_string(int index, int length)
134 if (index >= SIZE) index -= SIZE;
135 if (index + length > SIZE) {
136 std::string r(buf + index, SIZE - index);
137 r.insert(r.end(), buf, buf + length - (SIZE - index));
141 return std::string(buf + index, length);
145 // Append characters to the buffer. Caller must make certain there
146 // is enough space to contain the characters first.
147 void append(const char * s, int len) noexcept
149 int index = cur_idx + length;
150 if (index >= SIZE) index -= SIZE;
152 length += len; // (before we destroy len)
154 int max = SIZE - index;
155 std::memcpy(buf + index, s, std::min(max, len));
157 // Wrapped around buffer: copy the rest
160 std::memcpy(buf, s, len);