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