/* * 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 #include using android::base::StringPrintf; /******************************************************************************* ** ** 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 { LOG(ERROR) << StringPrintf("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; }