| /* |
| * 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" |
| |
| |
| /******************************************************************************* |
| ** |
| ** 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* data, UINT16 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* buffer, UINT16 bufferMaxLen, UINT16& 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; |
| } |
| |