taler-xotp_fw

xOTP generator firmware
Log | Files | Refs | Submodules | README

ringbuffer.c (4003B)


      1 /**
      2  * @file ringbuffer.c
      3  * @author Adrian STEINER (steia19@bfh.ch)
      4  * @brief Base ringbuffer header file for handling an unspecific data in a ring buffer design
      5  * @version 0.2
      6  * @date 2024-03-15
      7  * @date 2025-02-13
      8  *
      9  * @copyright (C) 2025 Adrian STEINER
     10  * This program is free software: you can redistribute it and/or modify
     11  * it under the terms of the GNU General Public License as published by
     12  * the Free Software Foundation, either version 3 of the License, or
     13  * (at your option) any later version.
     14  *
     15  * This program is distributed in the hope that it will be useful,
     16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  * GNU General Public License for more details.
     19  *
     20  * You should have received a copy of the GNU General Public License
     21  * along with this program.  If not, see <https: //www.gnu.org/licenses/>.
     22  *
     23  */
     24 
     25 #include "ringbuffer.h"
     26 #include <stddef.h>
     27 #include <string.h>
     28 
     29 ringbuffer_StatusType
     30 ringbuffer_init(ringbuffer_handler *rbHandler, void *buffer, uint32_t length, uint32_t elmSize) {
     31   if (rbHandler == NULL || buffer == NULL || length == 0 || elmSize == 0) {
     32     return RINGBUFFER_ARGUMENT_ERROR;
     33   }
     34   rbHandler->dataBuffer = buffer;
     35   rbHandler->length = length;
     36   rbHandler->elmSize = elmSize;
     37 
     38   // Initialise head and tail positions
     39   rbHandler->headPos = 0;
     40   rbHandler->tailPos = 0;
     41 
     42   return RINGBUFFER_OK;
     43 }
     44 
     45 void *ringbuffer_destroy(ringbuffer_handler *rbHandler) {
     46   if (rbHandler == NULL) {
     47     return NULL;
     48   }
     49   void *bufferArray = rbHandler->dataBuffer;
     50   rbHandler->dataBuffer = NULL;
     51   return bufferArray;
     52 }
     53 
     54 ringbuffer_StatusType ringbuffer_enqueue(ringbuffer_handler *rbHandler, void *data) {
     55   if (rbHandler == NULL || data == NULL) {
     56     return RINGBUFFER_ARGUMENT_ERROR;
     57   }
     58 
     59   if (ringbuffer_isFull(rbHandler)) {
     60     return RINGBUFFER_OVERFLOW;
     61   }
     62 
     63   /* Insert element */
     64   if (
     65       NULL == memcpy(
     66                   data,
     67                   (void *)((uint8_t *)rbHandler->dataBuffer + (rbHandler->tailPos * rbHandler->elmSize)),
     68                   rbHandler->elmSize)) {
     69     return RINGBUFFER_ERROR;
     70   }
     71   rbHandler->tailPos = (rbHandler->tailPos + 1) % rbHandler->length;
     72   return RINGBUFFER_OK;
     73 }
     74 
     75 ringbuffer_StatusType ringbuffer_dequeue(ringbuffer_handler *rbHandler, void **data) {
     76   if (rbHandler == NULL || data == NULL) {
     77     return RINGBUFFER_ARGUMENT_ERROR;
     78   }
     79 
     80   if (ringbuffer_isEmpty(rbHandler)) {
     81     return RINGBUFFER_EMPTY;
     82   }
     83 
     84   (*data) = (uint8_t *)rbHandler->dataBuffer + (rbHandler->headPos * rbHandler->elmSize);
     85 
     86   rbHandler->headPos = (rbHandler->headPos + 1) % rbHandler->length;
     87 
     88   return RINGBUFFER_OK;
     89 }
     90 
     91 void *ringbuffer_peek(const ringbuffer_handler *rbHandler) {
     92   if (rbHandler == NULL) {
     93     return NULL;
     94   }
     95   if (ringbuffer_isEmpty(rbHandler)) {
     96     return NULL;
     97   }
     98   return (void *)((uint8_t *)rbHandler->dataBuffer + rbHandler->headPos * rbHandler->elmSize);
     99 }
    100 
    101 uint32_t ringbuffer_size(const ringbuffer_handler *rbHandler) {
    102   if (rbHandler == NULL) {
    103     return 0;
    104   }
    105   // Check if a overflow of array is recognised
    106   if (rbHandler->headPos > rbHandler->tailPos) {
    107     return (rbHandler->length - rbHandler->headPos + rbHandler->tailPos);
    108   }
    109   // No overflow, calculate back - front
    110   else {
    111     return rbHandler->headPos - rbHandler->tailPos;
    112   }
    113 }
    114 
    115 bool ringbuffer_isFull(const ringbuffer_handler *rbHandler) {
    116   if (rbHandler == NULL) {
    117     return false;
    118   }
    119 
    120   if ((rbHandler->tailPos + 1) % rbHandler->length == rbHandler->headPos) {
    121     return true;
    122   } else {
    123     return false;
    124   }
    125 }
    126 
    127 bool ringbuffer_isEmpty(const ringbuffer_handler *rbHandler) {
    128   if (rbHandler == NULL) {
    129     return false;
    130   }
    131 
    132   if (rbHandler->tailPos == rbHandler->headPos) {
    133     return true;
    134   } else {
    135     return false;
    136   }
    137 }
    138 
    139 ringbuffer_StatusType ringbuffer_clear(ringbuffer_handler *rbHandler) {
    140   if (rbHandler == NULL) {
    141     return RINGBUFFER_ARGUMENT_ERROR;
    142   }
    143   rbHandler->tailPos = rbHandler->headPos;
    144   return RINGBUFFER_OK;
    145 }