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