| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560 |
- // Author: Ershov V.
- // Modified: Sychov. A / 12/2020
- #include "ringbuffer/ring_buffer.h"
- #include <stdlib.h>
- #include <string.h>
- #include "my_assert.h"
- STATIC_ASSERT(sizeof(RING_BUFFER_RC_TYPE) >= sizeof(RING_BUFFER_RC_TYPE),
- error);
- //see ringbuf_pop
- STATIC_ASSERT(sizeof(RING_BUFFER_RC_TYPE) > RING_BUFFER_ELEMENT_SIZE, error);
- //ToDo ring buffer with power of 2 buffer size
- RING_BUFFER_RC_TYPE ringbuf_write_s(ringbuf_t * self,
- const RING_BUFFER_ELEMENT_TYPE * buffer,
- RING_BUFFER_SIZE_TYPE size);
- static inline RING_BUFFER_SIZE_TYPE ringbuf_wr_index_to_tail_s(const ringbuf_t * self);
- static inline RING_BUFFER_SIZE_TYPE ringbuf_rd_index_to_tail_s(const ringbuf_t * self);
- static inline void ringbuf_add_index_s(RING_BUFFER_SIZE_TYPE * index,
- RING_BUFFER_SIZE_TYPE capacity,
- RING_BUFFER_SIZE_TYPE add);
- static inline void ringbuf_add_write_index_s(ringbuf_t * self,
- RING_BUFFER_SIZE_TYPE add);
- static inline void ringbuf_add_read_index_s(ringbuf_t * self,
- RING_BUFFER_SIZE_TYPE add);
- static inline void ringbuf_reset_s(ringbuf_t * self);
- RING_BUFFER_RC_TYPE ringbuf_init(ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE capacity)
- {
- RINGBUF_ASSERT(self);
- if(NULL == buffer || 0 >= capacity)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- memset(self, 0x00, sizeof(*self));
- self->buffer = buffer;
- self->capacity = capacity;
- return RINGBUF_RC_NO_ERROR;
- }
- RING_BUFFER_RC_TYPE ringbuf_peek_offset(const ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE size,
- RING_BUFFER_SIZE_TYPE offset )
- {
- RINGBUF_ASSERT(self && buffer);
- if(NULL == buffer || 0 >= size)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- char * buf = buffer;
- RING_BUFFER_RC_TYPE rc = self->size;
- if( offset >= rc )
- {
- return RINGBUF_RC_NO_DATA;
- }
- if(rc > size + offset)
- {
- rc = size;
- }
- else
- {
- size = rc - offset;
- rc -= offset;
- }
- RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
- ringbuf_add_index_s(&readIndex, self->capacity, offset);
- while(size)
- {
- RING_BUFFER_SIZE_TYPE bytes = self->capacity - readIndex;
- if(bytes > size)
- {
- bytes = size;
- }
- memcpy(buf, &self->buffer[readIndex], bytes);
- buf += bytes;
- size -= bytes;
- ringbuf_add_index_s(&readIndex, self->capacity, bytes);
- }
- return rc;
- }
- RING_BUFFER_RC_TYPE ringbuf_read(ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE size)
- {
- RINGBUF_ASSERT(self);
- if(NULL == buffer || 0 >= size)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- char * buf = buffer;
- RING_BUFFER_RC_TYPE rc = self->size;
- if(rc > size)
- {
- rc = size;
- }
- else
- {
- size = rc;
- }
- while(size)
- {
- RING_BUFFER_SIZE_TYPE bytes = ringbuf_rd_index_to_tail_s(self);
- if(bytes > size)
- {
- bytes = size;
- }
- memcpy(buf, &self->buffer[self->readIndex], bytes);
- buf += bytes;
- size -= bytes;
- ringbuf_add_read_index_s(self, bytes);
- }
- self->size -= rc;
- #if 0 // refactoring
- RING_BUFFER_SIZE_TYPE tail = ringbuf_bytes_to_tail_s(self);
- if(tail < size)
- {
- memcpy(buffer, &self->buffer[self->readIndex], tail);
- buffer += tail;
- size -= tail;
- self->readIndex = 0;
- }
- if(size)
- {
- memcpy(buffer, &self->buffer[self->readIndex], size);
- }
- ringbuf_add_read_index_s(self, size);
- self->size -= rc;
- #endif
- return rc;
- }
- RING_BUFFER_RC_TYPE ringbuf_write(ringbuf_t * self,
- const void * buffer,
- RING_BUFFER_SIZE_TYPE size)
- {
- RINGBUF_ASSERT(self);
- if(NULL == buffer || 0 >= size)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- RING_BUFFER_RC_TYPE rc = ringbuf_free_space(self);
- #if 0 // refactoring
- if(rc > size)
- {
- rc = size;
- }
- else
- {
- size = rc;
- }
- #endif
- if(size > rc)
- {
- size = rc;
- }
- return ringbuf_write_s(self, buffer, size);
- #if 0 // refactoring
- while(size)
- {
- RING_BUFFER_SIZE_TYPE bytes = ringbuf_wr_index_to_tail_s(self);
- if(bytes > size)
- {
- bytes = size;
- }
- memcpy(&self->buffer[self->writeIndex], buffer, bytes);
- buffer += bytes;
- size -= bytes;
- ringbuf_add_write_index_s(self, bytes);
- }
- self->size += rc;
- #endif
- #if 0 // refactoring
- RING_BUFFER_SIZE_TYPE tail = ringbuf_space_to_tail_s(self);
- if(tail < size)
- {
- memcpy(&self->buffer[self->writeIndex], buffer, tail);
- buffer += tail;
- size -= tail;
- self->writeIndex = 0;
- }
- if(size)
- {
- memcpy(&self->buffer[self->writeIndex], buffer, size);
- }
- ringbuf_add_write_index_s(self, size);
- self->size += rc;
- #endif
- //return rc;
- }
- RING_BUFFER_RC_TYPE ringbuf_write_front(ringbuf_t * self,
- const void * buffer,
- RING_BUFFER_SIZE_TYPE size)
- {
- RINGBUF_ASSERT(self);
- if(NULL == buffer || 0 >= size)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- const char * buf = buffer;
- RING_BUFFER_RC_TYPE rc = ringbuf_free_space(self);
- if(size > rc)
- {
- size = rc;
- }
- // Caching return value.
- rc = size;
- // Using read index instead of write index because it is a front writing.
- // Shifting read index into initial position.
- self->readIndex -= size;
- if(self->readIndex < 0)
- {
- self->readIndex += self->capacity;
- }
- RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
- while(size)
- {
- RING_BUFFER_SIZE_TYPE bytes = ringbuf_rd_index_to_tail_s(self);
- if(bytes > size)
- {
- bytes = size;
- }
- memcpy(&self->buffer[readIndex], buf, size);
- buf += bytes;
- size -= bytes;
- ringbuf_add_index_s(&readIndex, self->capacity, bytes);
- }
- self->size += rc;
- return rc;
- }
- RING_BUFFER_RC_TYPE ringbuf_front(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- if(!self->size)
- {
- return RINGBUF_RC_NO_DATA;
- }
- return self->buffer[self->readIndex];
- }
- RING_BUFFER_RC_TYPE ringbuf_back(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- if(!self->size)
- {
- return RINGBUF_RC_NO_DATA;
- }
- RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
- ringbuf_add_index_s(&readIndex, self->capacity, self->size);
- return self->buffer[readIndex];
- }
- RING_BUFFER_RC_TYPE ringbuf_push(ringbuf_t * self,
- RING_BUFFER_ELEMENT_TYPE element)
- {
- RINGBUF_ASSERT(self);
- if(!ringbuf_free_space(self))
- {
- return RINGBUF_RC_OVERFLOW;
- }
- self->buffer[self->writeIndex] = element;
- ringbuf_add_write_index_s(self, 1);
- ++self->size;
- return 1;
- }
- RING_BUFFER_RC_TYPE ringbuf_pop(ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- if(!self->size)
- {
- return RINGBUF_RC_NO_DATA;
- }
- RING_BUFFER_RC_TYPE rc = self->buffer[self->readIndex];
- ringbuf_add_read_index_s(self, 1);
- --self->size;
- return rc;
- }
- //RING_BUFFER_RC_TYPE ringbuf_push_front(ringbuf_t * self,
- // RING_BUFFER_ELEMENT_TYPE element);
- //RING_BUFFER_RC_TYPE ringbuf_pop_front(ringbuf_t * self);
- //RING_BUFFER_RC_TYPE ringbuf_push_back(ringbuf_t * self,
- // RING_BUFFER_ELEMENT_TYPE element);
- //RING_BUFFER_RC_TYPE ringbuf_pop_back(ringbuf_t * self);
- RING_BUFFER_RC_TYPE ringbuf_at(const ringbuf_t * self, RING_BUFFER_SIZE_TYPE index)
- {
- RINGBUF_ASSERT(self);
- if(index >= self->size)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
- ringbuf_add_index_s(&readIndex, self->capacity, index);
- return self->buffer[readIndex];
- }
- void ringbuf_clear(ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- self->size = 0;
- self->writeIndex = 0;
- self->readIndex = 0;
- }
- RING_BUFFER_RC_TYPE ringbuf_erase(ringbuf_t * self, RING_BUFFER_SIZE_TYPE count)
- {
- RINGBUF_ASSERT(self);
- RING_BUFFER_RC_TYPE rc = self->size;
- if(rc > count)
- {
- rc = count;
- }
- else
- {
- count = rc;
- }
- ringbuf_add_read_index_s(self, rc);
- self->size -= rc;
- return rc;
- }
- RING_BUFFER_RC_TYPE ringbuf_copy(ringbuf_t * lhs, ringbuf_t * rhs)
- {
- if(NULL == lhs || NULL == rhs)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- if(ringbuf_free_space(lhs) < rhs->size)
- {
- return RINGBUF_RC_OVERFLOW;
- }
- RING_BUFFER_SIZE_TYPE size = rhs->size;
- RING_BUFFER_SIZE_TYPE readIndex = rhs->readIndex;
- while(size)
- {
- RING_BUFFER_SIZE_TYPE bytes = rhs->capacity - readIndex;
- if(bytes > size)
- {
- bytes = size;
- }
- size -= ringbuf_write_s(lhs, &rhs->buffer[readIndex], bytes);
- ringbuf_add_index_s(&readIndex, rhs->capacity, bytes);
- }
- return rhs->size;
- }
- RING_BUFFER_RC_TYPE ringbuf_move(ringbuf_t * lhs, ringbuf_t * rhs)
- {
- if(NULL == lhs || NULL == rhs)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- memcpy(lhs, rhs, sizeof(*lhs));
- ringbuf_reset_s(rhs);
- return RINGBUF_RC_NO_ERROR;
- }
- RING_BUFFER_RC_TYPE ringbuf_find(ringbuf_t * self,
- void * context,
- pfRingbuf_predicate_t predicate)
- {
- RINGBUF_ASSERT(self);
- if(NULL == predicate)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- RING_BUFFER_SIZE_TYPE index = 0;
- RING_BUFFER_SIZE_TYPE size = self->size;
- RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
- while(size--)
- {
- if(predicate(context, self->buffer[readIndex]))
- {
- goto FEND;
- }
- ringbuf_add_index_s(&readIndex, self->capacity, 1);
- ++index;
- }
- index = RINGBUF_RC_NO_DATA;
- FEND:
- return index;
- }
- RING_BUFFER_RC_TYPE ringbuf_visit(ringbuf_t * self,
- void * context,
- pfRingbuf_visitor_t visitor)
- {
- RINGBUF_ASSERT(self);
- if(NULL == visitor)
- {
- return RINGBUF_RC_BAD_PARAM;
- }
- RING_BUFFER_SIZE_TYPE size = self->size;
- RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
- while(size--)
- {
- visitor(context, self->buffer[readIndex]);
- ringbuf_add_index_s(&readIndex, self->capacity, 1);
- }
- return self->size;
- }
- RING_BUFFER_RC_TYPE ringbuf_write_s(ringbuf_t * self,
- const RING_BUFFER_ELEMENT_TYPE * buffer,
- RING_BUFFER_SIZE_TYPE size)
- {
- RINGBUF_ASSERT(self && buffer && size >= 0);
- RING_BUFFER_RC_TYPE rc = size;
- while(size)
- {
- RING_BUFFER_SIZE_TYPE bytes = ringbuf_wr_index_to_tail_s(self);
- if(bytes > size)
- {
- bytes = size;
- }
- memcpy(&self->buffer[self->writeIndex], buffer, bytes);
- buffer += bytes;
- size -= bytes;
- ringbuf_add_write_index_s(self, bytes);
- }
- self->size += rc;
- return rc;
- }
- static inline RING_BUFFER_SIZE_TYPE ringbuf_wr_index_to_tail_s(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->capacity - self->writeIndex;
- }
- static inline RING_BUFFER_SIZE_TYPE ringbuf_rd_index_to_tail_s(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->capacity - self->readIndex;
- }
- static inline void ringbuf_add_index_s(RING_BUFFER_SIZE_TYPE * index,
- RING_BUFFER_SIZE_TYPE capacity,
- RING_BUFFER_SIZE_TYPE add)
- {
- RINGBUF_ASSERT(index && capacity > 0 && add >= 0);
- *index += add;
- if(*index >= capacity)
- {
- *index -= capacity;
- }
- }
- static inline void ringbuf_add_write_index_s(ringbuf_t * self,
- RING_BUFFER_SIZE_TYPE add)
- {
- RINGBUF_ASSERT(self);
- ringbuf_add_index_s(&self->writeIndex, self->capacity, add);
- }
- static inline void ringbuf_add_read_index_s(ringbuf_t * self,
- RING_BUFFER_SIZE_TYPE add)
- {
- RINGBUF_ASSERT(self);
- ringbuf_add_index_s(&self->readIndex, self->capacity, add);
- }
- static inline void ringbuf_reset_s(ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- memset(self, 0x00, sizeof(*self));
- }
|