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