1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Store data bytes in a variable-size queue. 19 */ 20 21 #include "DataQueue.h" 22 23 #include <malloc.h> 24 #include <string.h> 25 26 #include <android-base/stringprintf.h> 27 #include <base/logging.h> 28 29 using android::base::StringPrintf; 30 /******************************************************************************* 31 ** 32 ** Function: DataQueue 33 ** 34 ** Description: Initialize member variables. 35 ** 36 ** Returns: None. 37 ** 38 *******************************************************************************/ 39 DataQueue::DataQueue() {} 40 41 /******************************************************************************* 42 ** 43 ** Function: ~DataQueue 44 ** 45 ** Description: Release all resources. 46 ** 47 ** Returns: None. 48 ** 49 *******************************************************************************/ 50 DataQueue::~DataQueue() { 51 mMutex.lock(); 52 while (mQueue.empty() == false) { 53 tHeader* header = mQueue.front(); 54 mQueue.pop_front(); 55 free(header); 56 } 57 mMutex.unlock(); 58 } 59 60 bool DataQueue::isEmpty() { 61 mMutex.lock(); 62 bool retval = mQueue.empty(); 63 mMutex.unlock(); 64 return retval; 65 } 66 67 /******************************************************************************* 68 ** 69 ** Function: enqueue 70 ** 71 ** Description: Append data to the queue. 72 ** data: array of bytes 73 ** dataLen: length of the data. 74 ** 75 ** Returns: True if ok. 76 ** 77 *******************************************************************************/ 78 bool DataQueue::enqueue(uint8_t* data, uint16_t dataLen) { 79 if ((data == NULL) || (dataLen == 0)) return false; 80 81 mMutex.lock(); 82 83 bool retval = false; 84 tHeader* header = (tHeader*)malloc(sizeof(tHeader) + dataLen); 85 86 if (header) { 87 memset(header, 0, sizeof(tHeader)); 88 header->mDataLen = dataLen; 89 memcpy(header + 1, data, dataLen); 90 91 mQueue.push_back(header); 92 93 retval = true; 94 } else { 95 LOG(ERROR) << StringPrintf("DataQueue::enqueue: out of memory ?????"); 96 } 97 mMutex.unlock(); 98 return retval; 99 } 100 101 /******************************************************************************* 102 ** 103 ** Function: dequeue 104 ** 105 ** Description: Retrieve and remove data from the front of the queue. 106 ** buffer: array to store the data. 107 ** bufferMaxLen: maximum size of the buffer. 108 ** actualLen: actual length of the data. 109 ** 110 ** Returns: True if ok. 111 ** 112 *******************************************************************************/ 113 bool DataQueue::dequeue(uint8_t* buffer, uint16_t bufferMaxLen, 114 uint16_t& actualLen) { 115 mMutex.lock(); 116 117 tHeader* header = mQueue.front(); 118 bool retval = false; 119 120 if (header && buffer && (bufferMaxLen > 0)) { 121 if (header->mDataLen <= bufferMaxLen) { 122 // caller's buffer is big enough to store all data 123 actualLen = header->mDataLen; 124 char* src = (char*)(header) + sizeof(tHeader) + header->mOffset; 125 memcpy(buffer, src, actualLen); 126 127 mQueue.pop_front(); 128 free(header); 129 } else { 130 // caller's buffer is too small 131 actualLen = bufferMaxLen; 132 char* src = (char*)(header) + sizeof(tHeader) + header->mOffset; 133 memcpy(buffer, src, actualLen); 134 // adjust offset so the next dequeue() will get the remainder 135 header->mDataLen -= actualLen; 136 header->mOffset += actualLen; 137 } 138 retval = true; 139 } 140 mMutex.unlock(); 141 return retval; 142 } 143