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