14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------* 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * CircularBuffer.c * 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Copyright 2007, 2008 Nuance Communciations, Inc. * 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the 'License'); * 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * you may not use this file except in compliance with the License. * 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * You may obtain a copy of the License at * 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 * 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software * 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * distributed under the License is distributed on an 'AS IS' BASIS, * 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * See the License for the specific language governing permissions and * 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * limitations under the License. * 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/ 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifdef _WIN32 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if _MSC_VER >= 1100 // Visual C++ 5.x 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#pragma warning( disable : 4786 4503 ) 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "CircularBuffer.h" 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pmemory.h" 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef __vxworks 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <memory.h> 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode CircularBufferCreate(size_t capacity, const LCHAR* mtag, CircularBuffer** buffer) 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project CircularBuffer* Interface; 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer == NULL || capacity <= 0) 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Interface = (CircularBuffer *) MALLOC(sizeof(CircularBuffer) + capacity, mtag); 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (Interface == NULL) 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_OUT_OF_MEMORY; 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Interface->capacity = capacity; 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project CircularBufferReset(Interface); 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *buffer = Interface; 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint CircularBufferRead(CircularBuffer* buffer, void* data, size_t bufSize) 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t nbRead = 0; 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *bufferData = NULL; 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer == NULL || (data == NULL && bufSize > 0)) 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return -1; 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->size < bufSize) 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bufSize = buffer->size; 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (bufSize == 0) 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return 0; 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bufferData = ((unsigned char *) buffer) + sizeof(CircularBuffer); 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->readIdx >= buffer->writeIdx) 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project nbRead = buffer->capacity - buffer-> readIdx; 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (nbRead > bufSize) nbRead = bufSize; 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(data, bufferData + buffer->readIdx, nbRead); 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->size -= nbRead; 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->readIdx += nbRead; 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->readIdx == buffer->capacity) 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->readIdx = 0; 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (nbRead < bufSize) 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int toRead = bufSize - nbRead; 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(((unsigned char *) data) + nbRead, bufferData + buffer->readIdx, toRead); 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->size -= toRead; 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->readIdx += toRead; 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return bufSize; 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint CircularBufferSkip(CircularBuffer* buffer, size_t bufSize) 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if ( buffer == NULL ) 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return -1; 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->size < bufSize) 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bufSize = buffer->size; 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (bufSize == 0) 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return 0; 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->readIdx += bufSize; 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->readIdx >= buffer->capacity) 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->readIdx -= buffer->capacity; 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->size -= bufSize; 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return bufSize; 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint CircularBufferWrite(CircularBuffer* buffer, const void *data, size_t bufSize) 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t nbWritten = 0; 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *bufferData; 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t available = buffer->capacity - buffer->size; 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (data == NULL && bufSize > 0) 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return -1; 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (available < bufSize) /* We need to force an error to be logged here */ 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return -1; 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* bufSize = available; Throwing data on the floor with no notice is asking for trouble */ 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (bufSize == 0) 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return 0; 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bufferData = ((unsigned char*) buffer) + sizeof(CircularBuffer); 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->writeIdx >= buffer->readIdx) 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project nbWritten = buffer->capacity - buffer->writeIdx; 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (nbWritten > bufSize) nbWritten = bufSize; 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(bufferData + buffer->writeIdx, data, nbWritten); 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->size += nbWritten; 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->writeIdx += nbWritten; 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (buffer->writeIdx == buffer->capacity) 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->writeIdx = 0; 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (nbWritten < bufSize) 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t toWrite = bufSize - nbWritten; 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(bufferData + buffer->writeIdx, ((unsigned char*) data) + nbWritten, toWrite); 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->size += toWrite; 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->writeIdx += toWrite; 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return bufSize; 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint CircularBufferUnwrite(CircularBuffer* buffer, size_t amount) 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t available = buffer->capacity - buffer->size; 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (available < amount) 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project amount = available; 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project buffer->size -= amount; 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return amount; 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 158