#include #include /* * ring_new * build a new ring buffer object * * parameters: * struct ring_t *buf - ring object (provided by user) * size_t len - length to build the buffer * * returns the ring object (buf) or NULL if there is an error */ struct ring_t *ring_new(struct ring_t *buf, size_t len) { if(len < 3) { return NULL; } buf->buflen = len + 1; buf->buffer = malloc(buf->buflen); if(buf->buffer == NULL) { return NULL; } buf->begin = buf->buffer; buf->end = buf->buffer + len; buf->writer = buf->buffer; buf->reader = buf->buffer; return buf; } /* * ring_write * write data into the buffer * * parameters: * struct ring_t *buf - ring object (provided by user) * char *str - string to write to the buffer * size_t orig_len - length of the string to write * * returns the number of characters left to write */ size_t ring_write(struct ring_t *buf, char *str, size_t orig_len) { size_t len = orig_len; while(len > 0) { if(buf->writer == buf->end && buf->reader == buf->begin) { break; } else if(buf->writer == buf->end + 1) { buf->writer = buf->begin; } if(buf->writer == buf->reader - 1) { break; } *buf->writer = *str; --len, ++str, ++buf->writer; } return len; } /* * ring_read * read data from the buffer * * parameters: * struct ring_t *buf - ring object (provided by user) * size_t *len - length of the string to read (modified to the number of characters read) * * returns the number of characters left to read */ char *ring_read(struct ring_t *buf, size_t *len) { char *str = malloc(*len); size_t index = 0; if(str == NULL) { return NULL; } while(index < *len && buf->reader != buf->writer) { str[index] = *buf->reader; ++index, ++buf->reader; if(buf->reader == buf->end + 1) { buf->reader = buf->begin; } } if(index == 0) { *len = 0; return NULL; } else { *len -= index; return str; } } /* * ring_readln * read a line of data from the buffer * * parameters: * struct ring_t *buf - ring object (provided by user) * size_t *len - length of the line read * * returns the retreived line */ char *ring_readln(struct ring_t *buf, size_t *len) { *len = 0; char *index = buf->reader; while(*index != '\n' && index != buf->writer) { ++index, ++(*len); if(index == buf->end + 1) { index = buf->begin; } } if(*index != '\n') { *len = 0; return NULL; } else { size_t length = *len + 1; char *str = ring_read(buf, &length); if(str != NULL) { str[*len] = '\0'; } return str; } } /* * ring_del * delete a ring buffer object * * parameters: * struct ring_t *buf - ring object (provided by user) * * returns nothing */ void ring_del(struct ring_t *buf) { buf->buflen = 0; buf->begin = NULL; buf->end = NULL; buf->writer = NULL; buf->reader = NULL; free(buf->buffer); }