summaryrefslogtreecommitdiffstats
path: root/nxp/jni/com_android_nfc_list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxp/jni/com_android_nfc_list.cpp')
-rw-r--r--nxp/jni/com_android_nfc_list.cpp210
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;
+ }
+}