• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CircularBufferCreate(size_t capacity,const LCHAR * mtag,CircularBuffer ** buffer)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 
CircularBufferRead(CircularBuffer * buffer,void * data,size_t bufSize)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 
CircularBufferSkip(CircularBuffer * buffer,size_t bufSize)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 
CircularBufferWrite(CircularBuffer * buffer,const void * data,size_t bufSize)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 
CircularBufferUnwrite(CircularBuffer * buffer,size_t amount)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