summaryrefslogtreecommitdiffstats
path: root/K2LABI/Common
diff options
context:
space:
mode:
Diffstat (limited to 'K2LABI/Common')
-rw-r--r--K2LABI/Common/FlowDecoder/FlowDecoder.cpp205
-rw-r--r--K2LABI/Common/FlowDecoder/FlowDecoder.h54
-rw-r--r--K2LABI/Common/FlowDecoder/IFlowDecoder.h16
-rwxr-xr-xK2LABI/Common/SystemUtilities/SEvent.h152
-rwxr-xr-xK2LABI/Common/SystemUtilities/SLock.h79
-rw-r--r--K2LABI/Common/k2l-type.h26
-rw-r--r--K2LABI/Common/linkedList.h490
-rw-r--r--K2LABI/Common/list.h26
-rw-r--r--K2LABI/Common/windows-adapter.cpp42
-rw-r--r--K2LABI/Common/windows-adapter.h27
10 files changed, 1117 insertions, 0 deletions
diff --git a/K2LABI/Common/FlowDecoder/FlowDecoder.cpp b/K2LABI/Common/FlowDecoder/FlowDecoder.cpp
new file mode 100644
index 0000000..f393416
--- /dev/null
+++ b/K2LABI/Common/FlowDecoder/FlowDecoder.cpp
@@ -0,0 +1,205 @@
+#include "FlowDecoder.h"
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+
+CFlowDecoder::CFlowDecoder() : m_nBytesInBuffer(0)
+ , m_pCurrentReadPointer(0)
+ , m_pBufferStart(0)
+ , m_pBufferEnd(0)
+ , m_DecoderState(E_WAITING_FOR_HEADER)
+ , m_nSynchronized(false)
+{
+}
+
+void CFlowDecoder::DecodeFlow(BYTE* pBuffer, unsigned long nLen)
+{
+ if (NULL == pBuffer || 0 ==nLen)
+ return;
+
+ InitializeBuffer(pBuffer, nLen);
+
+ // The decoder state machine
+ bool bWaitForNewData = false;
+
+ //::OutputDebugString(_T("Enter FlowDecoder!\n") );
+ // Stay in state machine until all data has been consumed and no overflow occured
+ while (!bWaitForNewData)
+ {
+ // Now process data in Buffer
+ switch (m_DecoderState)
+ {
+ case E_WAITING_FOR_HEADER:
+ switch (ReceiveHeader() )
+ {
+ case E_STATE_NEEDS_MORE_DATA:
+ // We need more data... we do nothing... just wait
+ bWaitForNewData = true;
+ break;
+
+ case E_STATE_GOT_WRONG_DATA:
+ m_nSynchronized = false;
+ break;
+
+ case E_STATE_OK:
+ // We found a header... now we wait for the payload
+ m_DecoderState = E_WAITING_FOR_PACKET_DATA;
+ break;
+
+ default:
+ case E_STATE_UNDEFINED:
+ assert(false);
+ break;
+ }
+ break;
+
+ case E_WAITING_FOR_PACKET_DATA:
+ switch (ReceivePacket() )
+ {
+ case E_STATE_NEEDS_MORE_DATA:
+ // We need more data... we do nothing... just wait
+ bWaitForNewData = true;
+ break;
+
+ case E_STATE_GOT_WRONG_DATA:
+ case E_STATE_OK:
+ // Now we wait for the next header
+ m_DecoderState = E_WAITING_FOR_HEADER;
+ break;
+
+ default:
+ case E_STATE_UNDEFINED:
+ assert(false);
+ break;
+ }
+ break;
+
+ default:
+ assert(false);
+ m_DecoderState = E_WAITING_FOR_HEADER;
+ break;
+ }
+ }
+}
+
+void CFlowDecoder::Reset()
+{
+ InitializeBuffer(0, 0);
+ m_DecoderState = E_WAITING_FOR_HEADER;
+}
+
+void CFlowDecoder::InitializeBuffer(BYTE* pBuffer, unsigned long nLen)
+{
+ m_nBytesInBuffer = nLen;
+ m_pCurrentReadPointer = pBuffer;
+ m_pBufferStart = pBuffer;
+ m_pBufferEnd = &pBuffer[nLen];
+}
+
+unsigned long CFlowDecoder::GetNumberOfBytesInBuffer() const
+{
+ return m_nBytesInBuffer;
+}
+
+unsigned long CFlowDecoder::GetNumberOfMemoryChunks() const
+{
+ return (&m_pCurrentReadPointer[m_nBytesInBuffer] <= m_pBufferEnd) ? 1 : 2;
+}
+
+bool CFlowDecoder::GetMemoryChunk(unsigned long nNum, BYTE*& pReadPointer, unsigned long& nBytesAvailable) const
+{
+ // Valid chunk number?
+ if (nNum >= GetNumberOfMemoryChunks() )
+ return false;
+
+ // Calculate number of bytes at end of buffer
+ nBytesAvailable = static_cast<unsigned long>(m_pBufferEnd - m_pCurrentReadPointer);
+
+ if (nNum == 0)
+ {
+ pReadPointer = m_pCurrentReadPointer;
+ }
+ else // if (nNum == 1)
+ {
+ pReadPointer = m_pBufferStart;
+
+ // Reuse already calculated number of bytes at end of buffer to calc number of bytes at start
+ nBytesAvailable = static_cast<unsigned long>(m_nBytesInBuffer - nBytesAvailable);
+ }
+
+ return true;
+}
+
+bool CFlowDecoder::CopyFromBuffer(BYTE* pTarget, unsigned long len) const
+{
+ if (len > GetNumberOfBytesInBuffer() )
+ return false;
+
+ BYTE* pBufferStart;
+ unsigned long nBytesAvailable;
+
+ // Chunk zero always exists
+ GetMemoryChunk(0, pBufferStart, nBytesAvailable);
+
+ // Now check if the whole packet is in first chunk; Do we need to get 2nd chunk?
+ if (nBytesAvailable >= len)
+ {
+ // Copy first part
+ ::memcpy(pTarget, pBufferStart, len);
+ }
+ else
+ {
+ // Merge first and 2nd chunk
+ // Copy first part
+ ::memcpy(pTarget, pBufferStart, nBytesAvailable);
+
+ pTarget = &pTarget[nBytesAvailable];
+ len -= nBytesAvailable;
+
+ // Now get 2nd part and merge
+ bool bRetVal = GetMemoryChunk(1, pBufferStart, nBytesAvailable);
+ assert(bRetVal);
+
+ ::memcpy(pTarget, pBufferStart, len);
+ }
+
+ return true;
+}
+
+bool CFlowDecoder::RemoveBytesFromBuffer(unsigned long len)
+{
+ if (len > m_nBytesInBuffer)
+ {
+ assert(false);
+ return false;
+ }
+
+ if (GetNumberOfMemoryChunks() == 1)
+ {
+ // Advance pointer in chunk 0
+ m_pCurrentReadPointer = &m_pCurrentReadPointer[len];
+ }
+ else
+ {
+ // Calculate number of bytes at end of buffer (i.e. chunk 0)
+ unsigned long nBytesAtEnd = static_cast<unsigned long>(m_pBufferEnd - m_pCurrentReadPointer);
+
+ if (len >= nBytesAtEnd)
+ {
+ m_pCurrentReadPointer = &m_pBufferStart[len - nBytesAtEnd];
+ }
+ else
+ {
+ // Advance pointer in chunk 0
+ m_pCurrentReadPointer = &m_pCurrentReadPointer[len];
+ }
+ }
+
+ m_nBytesInBuffer -= len;
+
+ assert(m_pCurrentReadPointer >= m_pBufferStart);
+ assert(m_pCurrentReadPointer <= m_pBufferEnd);
+
+ return true;
+}
diff --git a/K2LABI/Common/FlowDecoder/FlowDecoder.h b/K2LABI/Common/FlowDecoder/FlowDecoder.h
new file mode 100644
index 0000000..6f8be64
--- /dev/null
+++ b/K2LABI/Common/FlowDecoder/FlowDecoder.h
@@ -0,0 +1,54 @@
+#ifndef __FLOW_DECODER_H__
+#define __FLOW_DECODER_H__
+
+#include "IFlowDecoder.h"
+
+
+class CFlowDecoder : public IFlowDecoder
+{
+public:
+ CFlowDecoder();
+ virtual ~CFlowDecoder() {}
+
+ // Gets called to submit a new package to buffer
+ void DecodeFlow(BYTE* pBuffer, unsigned long nLen);
+ virtual void Reset();
+
+protected:
+ void InitializeBuffer(BYTE* pBuffer, unsigned long nLen);
+ unsigned long GetNumberOfBytesInBuffer() const;
+ unsigned long GetNumberOfMemoryChunks() const;
+ bool GetMemoryChunk(unsigned long nNum, BYTE*& pReadPointer, unsigned long& nBytesAvailable) const;
+ bool AddBytesToBuffer(BYTE* pBuffer, unsigned long nLen);
+ bool CopyFromBuffer(BYTE* pTarget, unsigned long len) const;
+ bool RemoveBytesFromBuffer(unsigned long len);
+
+protected:
+ enum eStateRetVal
+ {
+ E_STATE_NEEDS_MORE_DATA,
+ E_STATE_GOT_WRONG_DATA,
+ E_STATE_OK,
+ E_STATE_UNDEFINED
+ };
+
+ bool m_nSynchronized;
+
+ virtual eStateRetVal ReceiveHeader() = 0;
+ virtual eStateRetVal ReceivePacket() = 0;
+
+private:
+ enum eDecoderState
+ {
+ E_WAITING_FOR_HEADER,
+ E_WAITING_FOR_PACKET_DATA,
+ };
+
+ unsigned long m_nBytesInBuffer;
+ BYTE* m_pCurrentReadPointer;
+ BYTE* m_pBufferStart;
+ BYTE* m_pBufferEnd;
+ eDecoderState m_DecoderState;
+};
+
+#endif // __FLOW_DECODER_H__
diff --git a/K2LABI/Common/FlowDecoder/IFlowDecoder.h b/K2LABI/Common/FlowDecoder/IFlowDecoder.h
new file mode 100644
index 0000000..16dae7c
--- /dev/null
+++ b/K2LABI/Common/FlowDecoder/IFlowDecoder.h
@@ -0,0 +1,16 @@
+#ifndef __IFLOWDECODER_H__
+#define __IFLOWDECODER_H__
+
+#include "k2l-type.h"
+
+
+class IFlowDecoder
+{
+public:
+ IFlowDecoder() {}
+ virtual ~IFlowDecoder() {}
+
+ virtual void DecodeFlow(BYTE* pBuffer, unsigned long nLen) = 0;
+};
+
+#endif // __IFLOWDECODER_H__
diff --git a/K2LABI/Common/SystemUtilities/SEvent.h b/K2LABI/Common/SystemUtilities/SEvent.h
new file mode 100755
index 0000000..b95c6ee
--- /dev/null
+++ b/K2LABI/Common/SystemUtilities/SEvent.h
@@ -0,0 +1,152 @@
+#ifndef S_EVENT_H
+#define S_EVENT_H
+
+#include "k2l-type.h"
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+
+//-----------------------------------------------------------------------------
+enum
+{
+ ERR_EVENT_BASE = -56700,
+ ERR_EVENT_ALREADY_CREATED = ERR_EVENT_BASE - 1,
+ ERR_EVENT_INIT = ERR_EVENT_BASE - 2,
+ ERR_EVENT_TIMEOUT = ERR_EVENT_BASE - 4,
+};
+
+//-----------------------------------------------------------------------------
+class CEvent
+{
+public:
+ CEvent(bool bCreate = false);
+ ~CEvent();
+
+ int create();
+ int close();
+ int wait(); // infinite
+ int waitMsec (long lMsecs);
+ int waitSeconds(long lSeconds);
+ int signal();
+ int reset();
+
+private:
+ bool m_created;
+ pthread_mutex_t m_mutex;
+};
+
+//-----------------------------------------------------------------------------
+inline CEvent::CEvent(bool bCreate) : m_created(bCreate)
+{
+ if (bCreate)
+ create();
+}
+
+//-----------------------------------------------------------------------------
+inline CEvent::~CEvent()
+{
+ close();
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::create()
+{
+ if (m_created)
+ return ERR_EVENT_ALREADY_CREATED;
+
+ int err = pthread_mutex_init(&m_mutex, NULL);
+
+ //Lock the mutex, so the next locking attempt will block
+ if (!err)
+ {
+ err = pthread_mutex_lock (&m_mutex);
+ }
+ if (!err)
+ {
+ m_created = true;
+ }
+ else
+ {
+ fprintf(stderr, "Failed to create CEvent, last err: %d\n", err);
+ }
+
+ return err;
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::close()
+{
+ if (!m_created)
+ return ERR_EVENT_INIT;
+
+
+ return pthread_mutex_destroy (&m_mutex);
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::wait() // infinite
+{
+ return pthread_mutex_lock (&m_mutex);
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::waitMsec(long lMsecs)
+{
+ if (!m_created)
+ return ERR_EVENT_INIT;
+
+ // See: http://www.ibm.com/developerworks/linux/library/l-ipc2lin3/index.html
+ struct timespec delay; // structure for providing timeout
+ long timeout = 0;
+ int err = 0;
+ while (timeout < lMsecs )
+ {
+ delay.tv_sec = 0;
+ delay.tv_nsec = 1000000; // 1 milli sec delay
+ err = pthread_mutex_trylock(&m_mutex);
+ if (!err)
+ {
+ break;
+ }
+ else {
+ // check whether somebody else has the mutex
+ if (err == EBUSY ) {
+ // Yes, Resource already in use so sleep
+ nanosleep(&delay, NULL);
+ ++timeout;
+ }
+ else
+ {
+ fprintf(stderr, "Unexpected return value from pthread_mutex_trylock: %d \n", err);
+ }
+ }
+ }
+return err;
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::waitSeconds(long lSeconds)
+{
+ DWORD dwMsecs = DWORD(lSeconds) * 1000;
+ return waitMsec(dwMsecs);
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::signal()
+{
+ if (!m_created)
+ return ERR_EVENT_INIT;
+
+ return pthread_mutex_unlock(&m_mutex);
+}
+
+//-----------------------------------------------------------------------------
+inline int CEvent::reset()
+{
+ if (!m_created)
+ return ERR_EVENT_INIT;
+
+ return pthread_mutex_unlock(&m_mutex);
+}
+
+#endif // S_EVENT_H
diff --git a/K2LABI/Common/SystemUtilities/SLock.h b/K2LABI/Common/SystemUtilities/SLock.h
new file mode 100755
index 0000000..d08ddb3
--- /dev/null
+++ b/K2LABI/Common/SystemUtilities/SLock.h
@@ -0,0 +1,79 @@
+#ifndef S_LOCK_H
+#define S_LOCK_H
+
+#include "windows-adapter.h"
+
+//-----------------------------------------------------------------------------
+class CLock
+{
+public:
+ //-----------------------------------------------------------------------------
+ CLock(bool bCreate = true)
+ {
+ m_bCreated = false;
+ if (bCreate)
+ {
+ create();
+ }
+ }
+ //-----------------------------------------------------------------------------
+ ~CLock()
+ {
+ destroy();
+ }
+ //-----------------------------------------------------------------------------
+ virtual int create()
+ {
+ ::InitializeCriticalSection(&m_CS);
+ m_bCreated = true;
+ return 0;
+ }
+ //-----------------------------------------------------------------------------
+ virtual int destroy()
+ {
+ if (m_bCreated)
+ {
+ ::DeleteCriticalSection(&m_CS);
+ m_bCreated = false;
+ }
+ return 0;
+ }
+ //-----------------------------------------------------------------------------
+ virtual int lock()
+ {
+ ::EnterCriticalSection(&m_CS);
+ return 0;
+ }
+ //-----------------------------------------------------------------------------
+ virtual int unlock()
+ {
+ ::LeaveCriticalSection(&m_CS);
+ return 0;
+ }
+ //-----------------------------------------------------------------------------
+private:
+ CRITICAL_SECTION m_CS;
+ bool m_bCreated;
+};
+//-----------------------------------------------------------------------------
+class CSafeLock
+{
+public:
+ CSafeLock(CLock* p) : m_pLock(p)
+ {
+ m_pLock->lock();
+ }
+
+ ~CSafeLock()
+ {
+ m_pLock->unlock();
+ m_pLock = 0;
+ }
+
+private:
+ CLock* m_pLock;
+};
+//-----------------------------------------------------------------------------
+
+#endif // S_LOCK_H
+
diff --git a/K2LABI/Common/k2l-type.h b/K2LABI/Common/k2l-type.h
new file mode 100644
index 0000000..4d95be9
--- /dev/null
+++ b/K2LABI/Common/k2l-type.h
@@ -0,0 +1,26 @@
+//
+// k2l-type.h
+// AmbientLight
+//
+// Created by Thorsten Kummermehr on 10/9/13.
+//
+//
+#ifndef AmbientLight_k2l_type_h
+#define AmbientLight_k2l_type_h
+
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define K2LABI_API
+
+typedef uint8_t BYTE;
+typedef uint16_t WORD;
+typedef uint32_t DWORD;
+typedef uint32_t HRESULT;
+
+typedef char TCHAR;
+
+typedef void* HANDLE;
+
+#endif
diff --git a/K2LABI/Common/linkedList.h b/K2LABI/Common/linkedList.h
new file mode 100644
index 0000000..a49eda1
--- /dev/null
+++ b/K2LABI/Common/linkedList.h
@@ -0,0 +1,490 @@
+#pragma once
+#include <windows.h>
+#include "list.h"
+
+#define MAX_ITERATOR 10
+
+template <class T>
+
+class CLinkedList : public IList<T>
+{
+private:
+ class CNode
+ {
+ public:
+ CNode(T* item, CNode* pPrevious)
+ {
+ val = item;
+ m_pNext = 0;
+ m_pPrevious = pPrevious;
+ if(pPrevious)
+ {
+ pPrevious->m_pNext = this;
+ }
+ }
+ CNode(T* item, CNode* pPrevious, CNode* pNext)
+ {
+ val = item;
+ m_pNext = pNext;
+ m_pPrevious = pPrevious;
+ if(pNext)
+ {
+ pNext->m_pPrevious = this;
+ }
+ if(pPrevious)
+ {
+ pPrevious->m_pNext = this;
+ }
+ }
+ ~CNode()
+ {
+ }
+ CNode* m_pNext;
+ CNode* m_pPrevious;
+ T* val;
+ };
+public:
+ class CIterator : public IList<T>::IIterator
+ {
+
+ public:
+ CIterator(CNode* pHead, CLinkedList* pList)
+ {
+ m_pHead = pHead;
+ m_pCurNode = pHead;
+ m_pList = pList;
+ }
+ virtual ~CIterator()
+ {
+ }
+
+ bool hasNext()
+ {
+ return m_pCurNode != 0;
+ }
+ T* next()
+ {
+ T* pRet = 0;
+ m_pList->lock();
+ if(m_pCurNode)
+ {
+ pRet = m_pCurNode->val;
+ m_pCurNode = m_pCurNode->m_pNext;
+ }
+ m_pList->unlock();
+ return pRet;
+ }
+ void release()
+ {
+ delete this;
+ }
+ void reset()
+ {
+ m_pCurNode = m_pHead;
+ }
+ private:
+ void setCurrentNode(CNode* pHead)
+ {
+ m_pCurNode = pHead;
+ }
+ CNode* m_pCurNode;
+ CNode* m_pHead;
+ CLinkedList* m_pList;
+ friend class CLinkedList;
+
+ };
+
+public:
+ //-------------------------------------------------------------------------
+ CLinkedList()
+ {
+ m_nSize = 0;
+ m_pHead = 0;
+ m_pLastNode = 0;
+ ::InitializeCriticalSection(&m_CS);
+ m_bCreated = true;
+ }
+ //-------------------------------------------------------------------------
+ virtual ~CLinkedList()
+ {
+ if(m_bCreated)
+ {
+ ::DeleteCriticalSection(&m_CS);
+ m_bCreated = false;
+ }
+ }
+ //-------------------------------------------------------------------------
+ CIterator* getIterator()
+ {
+ return new CIterator(m_pHead, this);
+ }
+ //-------------------------------------------------------------------------
+ void releaseIterator(CIterator* pIterator)
+ {
+ delete pIterator;
+ }
+ //-------------------------------------------------------------------------
+ int size()
+ {
+ return m_nSize;
+ }
+ //-------------------------------------------------------------------------
+ T* find(T* pCmp, int* pnIdx = 0, bool bForward = true)
+ {
+ T* pRet = 0;
+ lock();
+ if(pCmp != 0)
+ {
+
+ CNode* e = (bForward) ? m_pHead : m_pLastNode;
+ if(!isEmpty())
+ {
+ int nIdx = 0;
+ while(e)
+ {
+ if(e->val->Compare(pCmp) == 0)
+ {
+ pRet = e->val;
+ break;
+ }
+ e = (bForward) ? e->m_pNext : e->m_pPrevious;
+ nIdx++;
+ }
+ if(pnIdx != 0)
+ {
+ *pnIdx = nIdx;
+ }
+ }
+ }
+ unlock();
+ return pRet;
+ }
+ //-------------------------------------------------------------------------
+ int add(T* pItem)
+ {
+ lock();
+ int nRet = 0;
+ if(m_pHead == 0)
+ {
+ m_pHead = new CNode(pItem, 0);
+ m_pLastNode = m_pHead;
+ }
+ else
+ {
+ m_pLastNode->m_pNext = new CNode(pItem, m_pLastNode);
+ m_pLastNode = m_pLastNode->m_pNext;
+ }
+ m_nSize++;
+ unlock();
+ return nRet;
+ }
+ //-------------------------------------------------------------------------
+ /*
+ * returns 0 if the item was successfully removed from the list and -1 if the item
+ * was not found in the list.
+ */
+ int remove(T* pItem, bool bDelete = true)
+ {
+ lock();
+ int nRet = -1;
+ if(!isEmpty())
+ {
+ CNode* e = m_pHead;
+ while(e)
+ {
+ if(e->val == pItem)
+ {
+ if(e->m_pPrevious)
+ {
+ e->m_pPrevious->m_pNext = e->m_pNext;
+ }
+ else
+ {
+ //the head will be removed.
+ m_pHead = e->m_pNext;
+ }
+ if(e->m_pNext)
+ {
+ e->m_pNext->m_pPrevious = e->m_pPrevious;
+ }
+ else
+ {
+ //the last item will be removed.
+ m_pLastNode = e->m_pPrevious;
+ }
+ if(bDelete)
+ {
+ delete e->val;
+ }
+ delete e;
+ m_nSize--;
+ nRet = 0;
+ break;
+ }
+ e = e->m_pNext;
+ }
+ }
+ unlock();
+ return nRet;
+ }
+ int removeByValue(T& item, bool bDelete = true)
+ {
+ lock();
+ int nRet = -1;
+ if(!isEmpty())
+ {
+ CNode* e = m_pHead;
+ while(e)
+ {
+ if(*(e->val) == item)
+ {
+ if(e->m_pPrevious)
+ {
+ e->m_pPrevious->m_pNext = e->m_pNext;
+ }
+ else
+ {
+ //the head will be removed.
+ m_pHead = e->m_pNext;
+ }
+ if(e->m_pNext)
+ {
+ e->m_pNext->m_pPrevious = e->m_pPrevious;
+ }
+ else
+ {
+ //the last item will be removed.
+ m_pLastNode = e->m_pPrevious;
+ }
+ if(bDelete)
+ {
+ delete e->val;
+ }
+ delete e;
+ m_nSize--;
+ nRet = 0;
+ break;
+ }
+ e = e->m_pNext;
+ }
+ }
+ unlock();
+ return nRet;
+ }
+ //-------------------------------------------------------------------------
+ /*
+ * adds an element to the list if the element dont exist otherwise dont
+ * dont add the element.
+ * returns 0 if the element was added successfully and return a pointer to the element found otherwise.
+ */
+ T* addNotExist(T* pItem)
+ {
+ T* pRet = 0;
+ T* p = find(pItem);
+ if(p == 0)
+ {
+ add(pItem);
+ }
+ else
+ {
+ pRet = p;
+ }
+ return pRet;
+ }
+ //-------------------------------------------------------------------------
+ int addAt(T* pItem, int nIndex)
+ {
+ int nRet = 0;
+ lock();
+ CNode* pNext = getNodeAt(nIndex);
+
+ if(pNext)
+ {
+ CNode* newNode = new CNode(pItem, pNext->m_pPrevious, pNext);
+ if(!newNode->m_pPrevious)
+ {
+ m_pHead = newNode;
+ }
+ m_nSize++;
+ }
+ else
+ {
+ if(isEmpty() && nIndex == 0)
+ {
+ add(pItem);
+ }
+ else if(nIndex == m_nSize)
+ {
+ addAfter(pItem, m_pLastNode);
+ }
+ }
+ unlock();
+ return nRet;
+ }
+ int removeAt(int nIndex, bool bDelete = true)
+ {
+ int nRet = 0;
+ lock();
+ CNode* e = getNodeAt(nIndex);
+ if(e)
+ {
+ if(e->m_pPrevious)
+ {
+ e->m_pPrevious->m_pNext = e->m_pNext;
+ }
+ else
+ {
+ //the head will be removed.
+ m_pHead = e->m_pNext;
+ }
+ if(e->m_pNext)
+ {
+ e->m_pNext->m_pPrevious = e->m_pPrevious;
+ }
+ else
+ {
+ //the last item will be removed.
+ m_pLastNode = e->m_pPrevious;
+ }
+ if(bDelete)
+ {
+ delete e->val;
+ }
+ delete e;
+ m_nSize--;
+ }
+
+ unlock();
+ return nRet;
+ }
+ //-------------------------------------------------------------------------
+ T* getAt(int nIndex)
+ {
+ T* ret = 0;
+ CNode* e = getNodeAt(nIndex);
+ if(e)
+ {
+ ret = (e->val);
+ }
+ return ret;
+ }
+ //-------------------------------------------------------------------------
+ T* getHead()
+ {
+ return (m_pHead != 0) ? m_pHead->val : 0;
+ }
+ //-------------------------------------------------------------------------
+ T* getLast()
+ {
+ CNode* pLastNode = getLastNode();
+ return (pLastNode != 0) ? pLastNode->val : 0;
+ }
+ //-------------------------------------------------------------------------
+ void clear(bool bDelete = true, bool bArr = false)
+ {
+ lock();
+ if(m_nSize > 0)
+ {
+ CNode* e = m_pHead;
+ CNode* next = e->m_pNext;
+ while(e)
+ {
+ if(bDelete)
+ {
+ if(bArr)
+ {
+ delete [] e->val;
+ }
+ else
+ {
+ delete e->val;
+ }
+ }
+ delete e;
+ e = next;
+ if(e)next = e->m_pNext;
+ }
+ m_pHead = 0;
+ m_nSize = 0;
+ m_pLastNode = 0;
+ }
+ unlock();
+ }
+ //-------------------------------------------------------------------------
+ bool isEmpty()
+ {
+ bool bRet = (m_nSize == 0);
+ return bRet;
+ }
+ //-------------------------------------------------------------------------
+ int lock()
+ {
+ ::EnterCriticalSection(&m_CS);
+ return 0;
+ }
+ int unlock()
+ {
+ ::LeaveCriticalSection(&m_CS);
+ return 0;
+ }
+private:
+ int addAfter(T* pItem, CNode* after)
+ {
+ int nRet = 0;
+ lock();
+ CNode* newNode = new CNode(pItem, after, after->m_pNext);
+ if(newNode)
+ {
+ if(!newNode->m_pNext)
+ {
+ m_pLastNode = newNode;
+ }
+ m_nSize++;
+ }
+ unlock();
+ return nRet;
+ }
+ //-------------------------------------------------------------------------
+ int addBefor(T* item, CNode* befor)
+ {
+ int nRet = 0;
+ return nRet;
+ }
+
+
+ //-------------------------------------------------------------------------
+ void show()
+ {
+ CNode *e;
+ for(e = m_pHead ; e != 0 ; e = e->m_pNext)
+ {
+ printf("previous %x node %x next %x\n", e->m_pPrevious, e, e->m_pNext);
+ }
+ printf("List size = %d\n", m_nSize);
+ }
+ //-------------------------------------------------------------------------
+ CNode* getLastNode()
+ {
+ return m_pLastNode;
+ }
+ //-------------------------------------------------------------------------
+ CNode* getNodeAt(int nIndex)
+ {
+ CNode* ret = 0;
+ lock();
+ if(0 <= nIndex && nIndex < m_nSize)
+ {
+ CNode* e = m_pHead;
+ for(int i = 0 ; i < nIndex ; e = e->m_pNext,i++);
+ ret = e;
+ }
+ unlock();
+ return ret;
+ }
+
+ int m_nSize;
+ CNode *m_pHead;
+ CNode *m_pLastNode;
+ CRITICAL_SECTION m_CS;
+ bool m_bCreated;
+};
diff --git a/K2LABI/Common/list.h b/K2LABI/Common/list.h
new file mode 100644
index 0000000..4e34323
--- /dev/null
+++ b/K2LABI/Common/list.h
@@ -0,0 +1,26 @@
+#ifndef ILIST_H_
+#define ILIST_H_
+
+template<class T>
+
+class IList
+{
+public:
+ class IIterator
+ {
+ public:
+ virtual ~IIterator(){}
+ virtual bool hasNext() = 0;
+ virtual T* next() = 0;
+ virtual void release() = 0;
+ };
+ virtual ~IList(){}
+
+ virtual IIterator* getIterator() = 0;
+ virtual int add(T* pItem) = 0;
+ virtual T* getAt(int nIndex) = 0;
+ virtual void clear(bool bDelete = true, bool bArr = false) = 0;
+ virtual bool isEmpty() = 0;
+};
+
+#endif \ No newline at end of file
diff --git a/K2LABI/Common/windows-adapter.cpp b/K2LABI/Common/windows-adapter.cpp
new file mode 100644
index 0000000..6236010
--- /dev/null
+++ b/K2LABI/Common/windows-adapter.cpp
@@ -0,0 +1,42 @@
+//
+// windows-adapter.cpp
+// AmbientLight
+//
+// Created by Thorsten Kummermehr on 10/9/13.
+//
+//
+
+#include "windows-adapter.h"
+
+void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
+{
+ if (NULL == lpCriticalSection)
+ return;
+ pthread_mutexattr_t mutexattr;
+
+ // Set the mutex as a recursive mutex
+ pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&lpCriticalSection->m_mutex, &mutexattr);
+
+ // destroy the attribute
+ pthread_mutexattr_destroy(&mutexattr);
+
+}
+
+void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
+{
+ if (NULL == lpCriticalSection)
+ return;
+ pthread_mutex_destroy (&lpCriticalSection->m_mutex);
+}
+
+void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
+{
+ pthread_mutex_lock (&lpCriticalSection->m_mutex);
+}
+
+void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
+{
+ pthread_mutex_unlock (&lpCriticalSection->m_mutex);
+} \ No newline at end of file
diff --git a/K2LABI/Common/windows-adapter.h b/K2LABI/Common/windows-adapter.h
new file mode 100644
index 0000000..9f08d4b
--- /dev/null
+++ b/K2LABI/Common/windows-adapter.h
@@ -0,0 +1,27 @@
+//
+// windows-adapter.h
+// AmbientLight
+//
+// Created by Thorsten Kummermehr on 10/9/13.
+//
+//
+
+#ifndef AmbientLight_windows_adapter_h
+#define AmbientLight_windows_adapter_h
+
+#include "k2l-type.h"
+#include <pthread.h>
+
+typedef struct
+{
+ pthread_mutex_t m_mutex;
+} CRITICAL_SECTION;
+
+typedef CRITICAL_SECTION * LPCRITICAL_SECTION;
+
+void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection );
+void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+
+#endif