Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2010 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 #include <com_android_nfc_list.h>
     18 #include <com_android_nfc.h>
     19 #include <pthread.h>
     20 #include <errno.h>
     21 #include <cutils/log.h>
     22 
     23 #undef LOG_TAG
     24 #define LOG_TAG "NFC_LIST"
     25 
     26 bool listInit(listHead* pList)
     27 {
     28    pList->pFirst = NULL;
     29    if(pthread_mutex_init(&pList->mutex, NULL) == -1)
     30    {
     31       LOGE("Mutex creation failed (errno=0x%08x)", errno);
     32       return false;
     33    }
     34 
     35    return true;
     36 }
     37 
     38 bool listDestroy(listHead* pList)
     39 {
     40    bool bListNotEmpty = true;
     41    while (bListNotEmpty) {
     42       bListNotEmpty = listGetAndRemoveNext(pList, NULL);
     43    }
     44 
     45    if(pthread_mutex_destroy(&pList->mutex) == -1)
     46    {
     47       LOGE("Mutex destruction failed (errno=0x%08x)", errno);
     48       return false;
     49    }
     50 
     51    return true;
     52 }
     53 
     54 bool listAdd(listHead* pList, void* pData)
     55 {
     56    struct listNode* pNode;
     57    struct listNode* pLastNode;
     58    bool result;
     59 
     60    /* Create node */
     61    pNode = (struct listNode*)malloc(sizeof(listNode));
     62    if (pNode == NULL)
     63    {
     64       result = false;
     65       LOGE("Failed to malloc");
     66       goto clean_and_return;
     67    }
     68    TRACE("Allocated node: %8p (%8p)", pNode, pData);
     69    pNode->pData = pData;
     70    pNode->pNext = NULL;
     71 
     72    pthread_mutex_lock(&pList->mutex);
     73 
     74    /* Add the node to the list */
     75    if (pList->pFirst == NULL)
     76    {
     77        /* Set the node as the head */
     78       pList->pFirst = pNode;
     79    }
     80    else
     81    {
     82       /* Seek to the end of the list */
     83       pLastNode = pList->pFirst;
     84       while(pLastNode->pNext != NULL)
     85       {
     86           pLastNode = pLastNode->pNext;
     87       }
     88 
     89       /* Add the node to the current list */
     90       pLastNode->pNext = pNode;
     91    }
     92 
     93    result = true;
     94 
     95 clean_and_return:
     96    pthread_mutex_unlock(&pList->mutex);
     97    return result;
     98 }
     99 
    100 bool listRemove(listHead* pList, void* pData)
    101 {
    102    struct listNode* pNode;
    103    struct listNode* pRemovedNode;
    104    bool result;
    105 
    106    pthread_mutex_lock(&pList->mutex);
    107 
    108    if (pList->pFirst == NULL)
    109    {
    110       /* Empty list */
    111       LOGE("Failed to deallocate (list empty)");
    112       result = false;
    113       goto clean_and_return;
    114    }
    115 
    116    pNode = pList->pFirst;
    117    if (pList->pFirst->pData == pData)
    118    {
    119       /* Get the removed node */
    120       pRemovedNode = pNode;
    121 
    122       /* Remove the first node */
    123       pList->pFirst = pList->pFirst->pNext;
    124    }
    125    else
    126    {
    127       while (pNode->pNext != NULL)
    128       {
    129          if (pNode->pNext->pData == pData)
    130          {
    131             /* Node found ! */
    132             break;
    133          }
    134          pNode = pNode->pNext;
    135       }
    136 
    137       if (pNode->pNext == NULL)
    138       {
    139          /* Node not found */
    140           result = false;
    141           LOGE("Failed to deallocate (not found %8p)", pData);
    142           goto clean_and_return;
    143       }
    144 
    145       /* Get the removed node */
    146       pRemovedNode = pNode->pNext;
    147 
    148       /* Remove the node from the list */
    149       pNode->pNext = pNode->pNext->pNext;
    150    }
    151 
    152    /* Deallocate the node */
    153    TRACE("Deallocating node: %8p (%8p)", pRemovedNode, pRemovedNode->pData);
    154    free(pRemovedNode);
    155 
    156    result = true;
    157 
    158 clean_and_return:
    159    pthread_mutex_unlock(&pList->mutex);
    160    return result;
    161 }
    162 
    163 bool listGetAndRemoveNext(listHead* pList, void** ppData)
    164 {
    165    struct listNode* pNode;
    166    bool result;
    167 
    168    pthread_mutex_lock(&pList->mutex);
    169 
    170    if (pList->pFirst)
    171    {
    172       /* Empty list */
    173       LOGE("Failed to deallocate (list empty)");
    174       result = false;
    175       goto clean_and_return;
    176    }
    177 
    178    /* Work on the first node */
    179    pNode = pList->pFirst;
    180 
    181    /* Return the data */
    182    if (ppData != NULL)
    183    {
    184       *ppData = pNode->pData;
    185    }
    186 
    187    /* Remove and deallocate the node */
    188    pList->pFirst = pNode->pNext;
    189    TRACE("Deallocating node: %8p (%8p)", pNode, pNode->pData);
    190    free(pNode);
    191 
    192    result = true;
    193 
    194 clean_and_return:
    195    listDump(pList);
    196    pthread_mutex_unlock(&pList->mutex);
    197    return result;
    198 }
    199 
    200 void listDump(listHead* pList)
    201 {
    202    struct listNode* pNode = pList->pFirst;
    203 
    204    TRACE("Node dump:");
    205    while (pNode != NULL)
    206    {
    207       TRACE("- %8p (%8p)", pNode, pNode->pData);
    208       pNode = pNode->pNext;
    209    }
    210 }
    211