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 <cutils/log.h> 27 28 29 /******************************************************************************* 30 ** 31 ** Function: DataQueue 32 ** 33 ** Description: Initialize member variables. 34 ** 35 ** Returns: None. 36 ** 37 *******************************************************************************/ DataQueue()38 DataQueue::DataQueue () 39 { 40 } 41 42 43 /******************************************************************************* 44 ** 45 ** Function: ~DataQueue 46 ** 47 ** Description: Release all resources. 48 ** 49 ** Returns: None. 50 ** 51 *******************************************************************************/ ~DataQueue()52 DataQueue::~DataQueue () 53 { 54 mMutex.lock (); 55 while (mQueue.empty() == false) 56 { 57 tHeader* header = mQueue.front (); 58 mQueue.pop_front (); 59 free (header); 60 } 61 mMutex.unlock (); 62 } 63 64 isEmpty()65 bool DataQueue::isEmpty() 66 { 67 mMutex.lock (); 68 bool retval = mQueue.empty(); 69 mMutex.unlock (); 70 return retval; 71 } 72 73 74 /******************************************************************************* 75 ** 76 ** Function: enqueue 77 ** 78 ** Description: Append data to the queue. 79 ** data: array of bytes 80 ** dataLen: length of the data. 81 ** 82 ** Returns: True if ok. 83 ** 84 *******************************************************************************/ enqueue(UINT8 * data,UINT16 dataLen)85 bool DataQueue::enqueue (UINT8* data, UINT16 dataLen) 86 { 87 if ((data == NULL) || (dataLen==0)) 88 return false; 89 90 mMutex.lock (); 91 92 bool retval = false; 93 tHeader* header = (tHeader*) malloc (sizeof(tHeader) + dataLen); 94 95 if (header) 96 { 97 memset (header, 0, sizeof(tHeader)); 98 header->mDataLen = dataLen; 99 memcpy (header+1, data, dataLen); 100 101 mQueue.push_back (header); 102 103 retval = true; 104 } 105 else 106 { 107 ALOGE ("DataQueue::enqueue: out of memory ?????"); 108 } 109 mMutex.unlock (); 110 return retval; 111 } 112 113 114 /******************************************************************************* 115 ** 116 ** Function: dequeue 117 ** 118 ** Description: Retrieve and remove data from the front of the queue. 119 ** buffer: array to store the data. 120 ** bufferMaxLen: maximum size of the buffer. 121 ** actualLen: actual length of the data. 122 ** 123 ** Returns: True if ok. 124 ** 125 *******************************************************************************/ dequeue(UINT8 * buffer,UINT16 bufferMaxLen,UINT16 & actualLen)126 bool DataQueue::dequeue (UINT8* buffer, UINT16 bufferMaxLen, UINT16& actualLen) 127 { 128 mMutex.lock (); 129 130 tHeader* header = mQueue.front (); 131 bool retval = false; 132 133 if (header && buffer && (bufferMaxLen>0)) 134 { 135 if (header->mDataLen <= bufferMaxLen) 136 { 137 //caller's buffer is big enough to store all data 138 actualLen = header->mDataLen; 139 char* src = (char*)(header) + sizeof(tHeader) + header->mOffset; 140 memcpy (buffer, src, actualLen); 141 142 mQueue.pop_front (); 143 free (header); 144 } 145 else 146 { 147 //caller's buffer is too small 148 actualLen = bufferMaxLen; 149 char* src = (char*)(header) + sizeof(tHeader) + header->mOffset; 150 memcpy (buffer, src, actualLen); 151 //adjust offset so the next dequeue() will get the remainder 152 header->mDataLen -= actualLen; 153 header->mOffset += actualLen; 154 } 155 retval = true; 156 } 157 mMutex.unlock (); 158 return retval; 159 } 160 161