• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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