diff options
Diffstat (limited to 'nci/jni/DataQueue.cpp')
-rw-r--r-- | nci/jni/DataQueue.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/nci/jni/DataQueue.cpp b/nci/jni/DataQueue.cpp new file mode 100644 index 0000000..caa2575 --- /dev/null +++ b/nci/jni/DataQueue.cpp @@ -0,0 +1,155 @@ +/* + * 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; +} + |