/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Store data bytes in a variable-size queue. */ #include "DataQueue.h" #include #include #include /******************************************************************************* ** ** Function: DataQueue ** ** Description: Initialize member variables. ** ** Returns: None. ** *******************************************************************************/ DataQueue::DataQueue () { } /******************************************************************************* ** ** Function: ~DataQueue ** ** Description: Release all resources. ** ** Returns: None. ** *******************************************************************************/ DataQueue::~DataQueue () { mMutex.lock (); while (mQueue.empty() == false) { tHeader* header = mQueue.front (); mQueue.pop_front (); free (header); } mMutex.unlock (); } bool DataQueue::isEmpty() { mMutex.lock (); bool retval = mQueue.empty(); mMutex.unlock (); return retval; } /******************************************************************************* ** ** Function: enqueue ** ** Description: Append data to the queue. ** data: array of bytes ** dataLen: length of the data. ** ** Returns: True if ok. ** *******************************************************************************/ bool DataQueue::enqueue (uint8_t* data, uint16_t dataLen) { if ((data == NULL) || (dataLen==0)) return false; mMutex.lock (); bool retval = false; tHeader* header = (tHeader*) malloc (sizeof(tHeader) + dataLen); if (header) { memset (header, 0, sizeof(tHeader)); header->mDataLen = dataLen; memcpy (header+1, data, dataLen); mQueue.push_back (header); retval = true; } else { ALOGE("DataQueue::enqueue: out of memory ?????"); } mMutex.unlock (); return retval; } /******************************************************************************* ** ** Function: dequeue ** ** Description: Retrieve and remove data from the front of the queue. ** buffer: array to store the data. ** bufferMaxLen: maximum size of the buffer. ** actualLen: actual length of the data. ** ** Returns: True if ok. ** *******************************************************************************/ bool DataQueue::dequeue (uint8_t* buffer, uint16_t bufferMaxLen, uint16_t& actualLen) { mMutex.lock (); tHeader* header = mQueue.front (); bool retval = false; if (header && buffer && (bufferMaxLen>0)) { if (header->mDataLen <= bufferMaxLen) { //caller's buffer is big enough to store all data actualLen = header->mDataLen; char* src = (char*)(header) + sizeof(tHeader) + header->mOffset; memcpy (buffer, src, actualLen); mQueue.pop_front (); free (header); } else { //caller's buffer is too small actualLen = bufferMaxLen; char* src = (char*)(header) + sizeof(tHeader) + header->mOffset; memcpy (buffer, src, actualLen); //adjust offset so the next dequeue() will get the remainder header->mDataLen -= actualLen; header->mOffset += actualLen; } retval = true; } mMutex.unlock (); return retval; }