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