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