#include #include #include #include #include struct _patty_buffer { void * data; size_t size; size_t len; }; patty_buffer *patty_buffer_new(size_t size) { patty_buffer *buffer; if ((buffer = malloc(sizeof(*buffer))) == NULL) { goto error_malloc_buffer; } if ((buffer->data = malloc(size)) == NULL) { goto error_malloc_buffer_data; } buffer->size = size; buffer->len = 0; return buffer; error_malloc_buffer_data: free(buffer); error_malloc_buffer: return NULL; } void patty_buffer_destroy(patty_buffer *buffer) { free(buffer->data); free(buffer); } size_t patty_buffer_size(patty_buffer *buffer) { return buffer->size; } void *patty_buffer_data(patty_buffer *buffer, size_t *len) { *len = buffer->len; return buffer->data; } ssize_t patty_buffer_fill(patty_buffer *buffer, void *data, size_t len) { if (len == 0) { return 0; } if (len > buffer->size - buffer->len) { errno = EIO; goto error_io; } memcpy(((unsigned char *)buffer->data) + buffer->len, data, len); buffer->len += len; return len; error_io: return -1; } void patty_buffer_flush(patty_buffer *buffer, size_t len) { /* * Move everything from the buffer not processed up to this point, to the * beginning of the buffer. */ memmove(buffer->data, ((unsigned char *)buffer->data) + len, buffer->len - len); /* * Then, decrement the buffer length by the number of bytes already * processed. */ buffer->len -= len; }