Home | History | Annotate | Download | only in jni
      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 *******************************************************************************/
     35 DataQueue::DataQueue ()
     36 {
     37 }
     38 
     39 
     40 /*******************************************************************************
     41 **
     42 ** Function:        ~DataQueue
     43 **
     44 ** Description:      Release all resources.
     45 **
     46 ** Returns:         None.
     47 **
     48 *******************************************************************************/
     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 
     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 *******************************************************************************/
     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 *******************************************************************************/
    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