160 lines
2.9 KiB
C
160 lines
2.9 KiB
C
|
#include <ring.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
/*
|
||
|
* 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);
|
||
|
}
|