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*******************************************************************************/
35DataQueue::DataQueue ()
36{
37}
38
39
40/*******************************************************************************
41**
42** Function:        ~DataQueue
43**
44** Description:      Release all resources.
45**
46** Returns:         None.
47**
48*******************************************************************************/
49DataQueue::~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
62bool 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*******************************************************************************/
82bool 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*******************************************************************************/
123bool 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