26 #include <graphlab/logger/assertions.hpp>
27 #include <graphlab/rpc/circular_char_buffer.hpp>
31 circular_char_buffer::circular_char_buffer(std::streamsize initial) {
32 initial = std::max<size_t>((size_t)initial, 4);
34 buffer = (
char*)malloc(initial);
41 circular_char_buffer::circular_char_buffer(
const circular_char_buffer &src) {
43 bufsize = std::max<size_t>(src.size(), 4);
44 buffer = (
char*)malloc(bufsize);
47 src.peek(buffer, src.size());
52 if (tail == bufsize) tail = 0;
56 circular_char_buffer::operator=(
const circular_char_buffer& src) {
61 src.peek(buffer, src.size());
64 if (tail == bufsize) tail = 0;
68 void circular_char_buffer::reserve(std::streamsize s) {
72 if (s <= bufsize)
return;
75 buffer = (
char*)realloc((
void*)buffer, s);
89 size_t excess = (size_t)s - bufsize;
91 size_t movebytes = std::min<size_t>(tail, excess);
92 memcpy(buffer + bufsize, buffer, movebytes);
94 memmove(buffer, buffer+movebytes, tail - movebytes);
99 tail = (head + len) % bufsize;
105 void circular_char_buffer::squeeze() {
107 if (bufsize <= 4)
return;
112 if (head > 0) memmove(buffer, buffer+head, len);
113 std::streamsize efflen = std::max(len + 1, std::streamsize(4));
114 buffer = (
char*)realloc((
void*)buffer, efflen);
121 std::streamsize efflen = std::max(len + 1, std::streamsize(4));
122 char *newbuf = (
char*)malloc(efflen);
136 void circular_char_buffer::align() {
138 if (bufsize <= 4)
return;
143 if (head > 0) memmove(buffer, buffer+head, len);
149 char *newbuf = (
char*)malloc(bufsize);
160 bool circular_char_buffer::align_requires_alloc() {
162 if (bufsize <= 4)
return false;
173 std::streamsize circular_char_buffer::peek(
char* c,
174 std::streamsize clen)
const {
175 std::streamsize readlen = std::min(clen, len);
177 if (readlen == 0)
return 0;
180 std::streamsize firstcopy = std::min(bufsize - head, readlen);
181 memcpy(c, buffer+head, firstcopy);
182 if (firstcopy == readlen)
return readlen;
184 std::streamsize secondcopy = std::min(tail, readlen - firstcopy);
185 memcpy(c+firstcopy, buffer, secondcopy);
192 std::streamsize circular_char_buffer::skip(std::streamsize clen) {
193 std::streamsize readlen = std::min(clen, len);
195 if (head >= bufsize) head -= bufsize;
201 std::streamsize circular_char_buffer::read(
char* c,
202 std::streamsize clen) {
203 if (len == 0)
return -1;
204 std::streamsize readlen = peek(c, clen);
211 std::streamsize circular_char_buffer::peek(std::string &c,
212 std::streamsize clen)
const{
215 return peek(const_cast<char*>(c.c_str()), clen);
218 std::streamsize circular_char_buffer::read(std::string &c,
219 std::streamsize clen) {
222 return read(const_cast<char*>(c.c_str()), clen);
226 std::streamsize circular_char_buffer::write(
const char* c,
227 std::streamsize clen) {
230 reserve(clen + len + 1);
233 std::streamsize firstcopy = std::min(clen, bufsize - tail);
234 memcpy(buffer + tail, c, firstcopy);
236 if (tail == bufsize) tail = 0;
237 if (firstcopy == clen) {
242 std::streamsize secondcopy = clen - firstcopy;
243 memcpy(buffer, c + firstcopy, secondcopy);
249 void circular_char_buffer::clear() {
250 head = 0; tail = 0; len = 0;
253 circular_char_buffer::~circular_char_buffer() {
257 std::streamsize circular_char_buffer::introspective_read(
char* &s) {
267 std::streamsize readlen = 0;
269 readlen = tail - head;
272 readlen = bufsize - head;
278 std::streamsize circular_char_buffer::introspective_read(
char* &s, std::streamsize clen) {
288 std::streamsize readlen = 0;
290 readlen = tail - head;
293 readlen = bufsize - head;
295 if (clen < readlen) readlen = clen;
302 std::streamsize circular_char_buffer::introspective_write(
char* &s) {
306 return bufsize - tail - (head==0);
310 return head - tail - 1;
314 void circular_char_buffer::advance_write(std::streamsize bytes) {
316 if (tail >= bufsize) tail -= bufsize;