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 <android-base/stringprintf.h>
     27 #include <base/logging.h>
     28 
     29 using android::base::StringPrintf;
     30 /*******************************************************************************
     31 **
     32 ** Function:        DataQueue
     33 **
     34 ** Description:     Initialize member variables.
     35 **
     36 ** Returns:         None.
     37 **
     38 *******************************************************************************/
     39 DataQueue::DataQueue() {}
     40 
     41 /*******************************************************************************
     42 **
     43 ** Function:        ~DataQueue
     44 **
     45 ** Description:      Release all resources.
     46 **
     47 ** Returns:         None.
     48 **
     49 *******************************************************************************/
     50 DataQueue::~DataQueue() {
     51   mMutex.lock();
     52   while (mQueue.empty() == false) {
     53     tHeader* header = mQueue.front();
     54     mQueue.pop_front();
     55     free(header);
     56   }
     57   mMutex.unlock();
     58 }
     59 
     60 bool DataQueue::isEmpty() {
     61   mMutex.lock();
     62   bool retval = mQueue.empty();
     63   mMutex.unlock();
     64   return retval;
     65 }
     66 
     67 /*******************************************************************************
     68 **
     69 ** Function:        enqueue
     70 **
     71 ** Description:     Append data to the queue.
     72 **                  data: array of bytes
     73 **                  dataLen: length of the data.
     74 **
     75 ** Returns:         True if ok.
     76 **
     77 *******************************************************************************/
     78 bool DataQueue::enqueue(uint8_t* data, uint16_t dataLen) {
     79   if ((data == NULL) || (dataLen == 0)) return false;
     80 
     81   mMutex.lock();
     82 
     83   bool retval = false;
     84   tHeader* header = (tHeader*)malloc(sizeof(tHeader) + dataLen);
     85 
     86   if (header) {
     87     memset(header, 0, sizeof(tHeader));
     88     header->mDataLen = dataLen;
     89     memcpy(header + 1, data, dataLen);
     90 
     91     mQueue.push_back(header);
     92 
     93     retval = true;
     94   } else {
     95     LOG(ERROR) << StringPrintf("DataQueue::enqueue: out of memory ?????");
     96   }
     97   mMutex.unlock();
     98   return retval;
     99 }
    100 
    101 /*******************************************************************************
    102 **
    103 ** Function:        dequeue
    104 **
    105 ** Description:     Retrieve and remove data from the front of the queue.
    106 **                  buffer: array to store the data.
    107 **                  bufferMaxLen: maximum size of the buffer.
    108 **                  actualLen: actual length of the data.
    109 **
    110 ** Returns:         True if ok.
    111 **
    112 *******************************************************************************/
    113 bool DataQueue::dequeue(uint8_t* buffer, uint16_t bufferMaxLen,
    114                         uint16_t& actualLen) {
    115   mMutex.lock();
    116 
    117   tHeader* header = mQueue.front();
    118   bool retval = false;
    119 
    120   if (header && buffer && (bufferMaxLen > 0)) {
    121     if (header->mDataLen <= bufferMaxLen) {
    122       // caller's buffer is big enough to store all data
    123       actualLen = header->mDataLen;
    124       char* src = (char*)(header) + sizeof(tHeader) + header->mOffset;
    125       memcpy(buffer, src, actualLen);
    126 
    127       mQueue.pop_front();
    128       free(header);
    129     } else {
    130       // caller's buffer is too small
    131       actualLen = bufferMaxLen;
    132       char* src = (char*)(header) + sizeof(tHeader) + header->mOffset;
    133       memcpy(buffer, src, actualLen);
    134       // adjust offset so the next dequeue() will get the remainder
    135       header->mDataLen -= actualLen;
    136       header->mOffset += actualLen;
    137     }
    138     retval = true;
    139   }
    140   mMutex.unlock();
    141   return retval;
    142 }
    143