diff options
Diffstat (limited to 'nxp/jni/com_android_nfc_list.cpp')
-rw-r--r-- | nxp/jni/com_android_nfc_list.cpp | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/nxp/jni/com_android_nfc_list.cpp b/nxp/jni/com_android_nfc_list.cpp new file mode 100644 index 00000000..f0487d3c --- /dev/null +++ b/nxp/jni/com_android_nfc_list.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <com_android_nfc_list.h> +#include <com_android_nfc.h> +#include <pthread.h> +#include <errno.h> +#include <cutils/log.h> + +#undef LOG_TAG +#define LOG_TAG "NFC_LIST" + +bool listInit(listHead* pList) +{ + pList->pFirst = NULL; + if(pthread_mutex_init(&pList->mutex, NULL) == -1) + { + ALOGE("Mutex creation failed (errno=0x%08x)", errno); + return false; + } + + return true; +} + +bool listDestroy(listHead* pList) +{ + bool bListNotEmpty = true; + while (bListNotEmpty) { + bListNotEmpty = listGetAndRemoveNext(pList, NULL); + } + + if(pthread_mutex_destroy(&pList->mutex) == -1) + { + ALOGE("Mutex destruction failed (errno=0x%08x)", errno); + return false; + } + + return true; +} + +bool listAdd(listHead* pList, void* pData) +{ + struct listNode* pNode; + struct listNode* pLastNode; + bool result; + + /* Create node */ + pNode = (struct listNode*)malloc(sizeof(listNode)); + if (pNode == NULL) + { + result = false; + ALOGE("Failed to malloc"); + goto clean_and_return; + } + TRACE("Allocated node: %8p (%8p)", pNode, pData); + pNode->pData = pData; + pNode->pNext = NULL; + + pthread_mutex_lock(&pList->mutex); + + /* Add the node to the list */ + if (pList->pFirst == NULL) + { + /* Set the node as the head */ + pList->pFirst = pNode; + } + else + { + /* Seek to the end of the list */ + pLastNode = pList->pFirst; + while(pLastNode->pNext != NULL) + { + pLastNode = pLastNode->pNext; + } + + /* Add the node to the current list */ + pLastNode->pNext = pNode; + } + + result = true; + +clean_and_return: + pthread_mutex_unlock(&pList->mutex); + return result; +} + +bool listRemove(listHead* pList, void* pData) +{ + struct listNode* pNode; + struct listNode* pRemovedNode; + bool result; + + pthread_mutex_lock(&pList->mutex); + + if (pList->pFirst == NULL) + { + /* Empty list */ + ALOGE("Failed to deallocate (list empty)"); + result = false; + goto clean_and_return; + } + + pNode = pList->pFirst; + if (pList->pFirst->pData == pData) + { + /* Get the removed node */ + pRemovedNode = pNode; + + /* Remove the first node */ + pList->pFirst = pList->pFirst->pNext; + } + else + { + while (pNode->pNext != NULL) + { + if (pNode->pNext->pData == pData) + { + /* Node found ! */ + break; + } + pNode = pNode->pNext; + } + + if (pNode->pNext == NULL) + { + /* Node not found */ + result = false; + ALOGE("Failed to deallocate (not found %8p)", pData); + goto clean_and_return; + } + + /* Get the removed node */ + pRemovedNode = pNode->pNext; + + /* Remove the node from the list */ + pNode->pNext = pNode->pNext->pNext; + } + + /* Deallocate the node */ + TRACE("Deallocating node: %8p (%8p)", pRemovedNode, pRemovedNode->pData); + free(pRemovedNode); + + result = true; + +clean_and_return: + pthread_mutex_unlock(&pList->mutex); + return result; +} + +bool listGetAndRemoveNext(listHead* pList, void** ppData) +{ + struct listNode* pNode; + bool result; + + pthread_mutex_lock(&pList->mutex); + + if (pList->pFirst) + { + /* Empty list */ + ALOGE("Failed to deallocate (list empty)"); + result = false; + goto clean_and_return; + } + + /* Work on the first node */ + pNode = pList->pFirst; + + /* Return the data */ + if (ppData != NULL) + { + *ppData = pNode->pData; + } + + /* Remove and deallocate the node */ + pList->pFirst = pNode->pNext; + TRACE("Deallocating node: %8p (%8p)", pNode, pNode->pData); + free(pNode); + + result = true; + +clean_and_return: + listDump(pList); + pthread_mutex_unlock(&pList->mutex); + return result; +} + +void listDump(listHead* pList) +{ + struct listNode* pNode = pList->pFirst; + + TRACE("Node dump:"); + while (pNode != NULL) + { + TRACE("- %8p (%8p)", pNode, pNode->pData); + pNode = pNode->pNext; + } +} |