Home | History | Annotate | Download | only in src
      1 /*---------------------------------------------------------------------------*
      2  *  CircularBuffer.c  *
      3  *                                                                           *
      4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
      5  *                                                                           *
      6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
      7  *  you may not use this file except in compliance with the License.         *
      8  *                                                                           *
      9  *  You may obtain a copy of the License at                                  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
     11  *                                                                           *
     12  *  Unless required by applicable law or agreed to in writing, software      *
     13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
     15  *  See the License for the specific language governing permissions and      *
     16  *  limitations under the License.                                           *
     17  *                                                                           *
     18  *---------------------------------------------------------------------------*/
     19 
     20 
     21 
     22 #ifdef _WIN32
     23 #if _MSC_VER >= 1100    // Visual C++ 5.x
     24 #pragma warning( disable : 4786 4503 )
     25 #endif
     26 #endif
     27 
     28 #include "CircularBuffer.h"
     29 #include "pmemory.h"
     30 #ifndef __vxworks
     31 #include <memory.h>
     32 #endif
     33 
     34 ESR_ReturnCode CircularBufferCreate(size_t capacity, const LCHAR* mtag, CircularBuffer** buffer)
     35 {
     36   CircularBuffer* Interface;
     37   if (buffer == NULL || capacity <= 0)
     38     return ESR_INVALID_ARGUMENT;
     39 
     40   Interface = (CircularBuffer *) MALLOC(sizeof(CircularBuffer) + capacity, mtag);
     41   if (Interface == NULL)
     42     return ESR_OUT_OF_MEMORY;
     43   Interface->capacity = capacity;
     44   CircularBufferReset(Interface);
     45   *buffer = Interface;
     46   return ESR_SUCCESS;
     47 }
     48 
     49 
     50 int CircularBufferRead(CircularBuffer* buffer, void* data, size_t bufSize)
     51 {
     52   size_t nbRead = 0;
     53   unsigned char *bufferData = NULL;
     54 
     55   if (buffer == NULL || (data == NULL && bufSize > 0))
     56     return -1;
     57 
     58   if (buffer->size < bufSize)
     59     bufSize = buffer->size;
     60 
     61   if (bufSize == 0)
     62     return 0;
     63 
     64   bufferData = ((unsigned char *) buffer) + sizeof(CircularBuffer);
     65 
     66   if (buffer->readIdx >= buffer->writeIdx)
     67   {
     68     nbRead = buffer->capacity - buffer-> readIdx;
     69     if (nbRead > bufSize) nbRead = bufSize;
     70 
     71     memcpy(data, bufferData + buffer->readIdx, nbRead);
     72     buffer->size -= nbRead;
     73     buffer->readIdx += nbRead;
     74     if (buffer->readIdx == buffer->capacity)
     75       buffer->readIdx = 0;
     76   }
     77 
     78   if (nbRead < bufSize)
     79   {
     80     int toRead = bufSize - nbRead;
     81     memcpy(((unsigned char *) data) + nbRead, bufferData + buffer->readIdx, toRead);
     82     buffer->size -= toRead;
     83     buffer->readIdx += toRead;
     84   }
     85 
     86   return bufSize;
     87 }
     88 
     89 int CircularBufferSkip(CircularBuffer* buffer, size_t bufSize)
     90 {
     91   if ( buffer == NULL )
     92     return -1;
     93 
     94   if (buffer->size < bufSize)
     95     bufSize = buffer->size;
     96 
     97   if (bufSize == 0)
     98     return 0;
     99 
    100   buffer->readIdx += bufSize;
    101   if (buffer->readIdx >= buffer->capacity)
    102     buffer->readIdx -= buffer->capacity;
    103 
    104   buffer->size -= bufSize;
    105 
    106   return bufSize;
    107 }
    108 
    109 int CircularBufferWrite(CircularBuffer* buffer, const void *data, size_t bufSize)
    110 {
    111   size_t nbWritten = 0;
    112   unsigned char *bufferData;
    113   size_t available = buffer->capacity - buffer->size;
    114 
    115   if (data == NULL && bufSize > 0)
    116     return -1;
    117 
    118   if (available < bufSize)	/* We need to force an error to be logged here */
    119     return -1;
    120 /*    bufSize = available;	Throwing data on the floor with no notice is asking for trouble */
    121 
    122   if (bufSize == 0)
    123     return 0;
    124 
    125   bufferData = ((unsigned char*) buffer) + sizeof(CircularBuffer);
    126 
    127   if (buffer->writeIdx >= buffer->readIdx)
    128   {
    129     nbWritten = buffer->capacity - buffer->writeIdx;
    130     if (nbWritten > bufSize) nbWritten = bufSize;
    131     memcpy(bufferData + buffer->writeIdx, data, nbWritten);
    132     buffer->size += nbWritten;
    133     buffer->writeIdx += nbWritten;
    134     if (buffer->writeIdx == buffer->capacity)
    135       buffer->writeIdx = 0;
    136   }
    137 
    138   if (nbWritten < bufSize)
    139   {
    140     size_t toWrite = bufSize - nbWritten;
    141     memcpy(bufferData + buffer->writeIdx, ((unsigned char*) data) + nbWritten, toWrite);
    142     buffer->size += toWrite;
    143     buffer->writeIdx += toWrite;
    144   }
    145 
    146   return bufSize;
    147 }
    148 
    149 int CircularBufferUnwrite(CircularBuffer* buffer, size_t amount)
    150 {
    151   size_t available = buffer->capacity - buffer->size;
    152 
    153   if (available < amount)
    154     amount = available;
    155   buffer->size -= amount;
    156   return amount;
    157 }
    158