diff options
author | Kirill Volinsky <mataes2007@gmail.com> | 2012-10-13 08:54:34 +0000 |
---|---|---|
committer | Kirill Volinsky <mataes2007@gmail.com> | 2012-10-13 08:54:34 +0000 |
commit | de6eb3e4bc30eff928dc932c03812ede3077926a (patch) | |
tree | 966a57948af890b1c47699e5ec0db23a26a7add9 /protocols/MRA/src/Sdk/ListMT.h | |
parent | 870d3d99c22c77a94a352ad292ed67e8eb81edf0 (diff) |
MRA: folders restructurization
git-svn-id: http://svn.miranda-ng.org/main/trunk@1900 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/MRA/src/Sdk/ListMT.h')
-rw-r--r-- | protocols/MRA/src/Sdk/ListMT.h | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/protocols/MRA/src/Sdk/ListMT.h b/protocols/MRA/src/Sdk/ListMT.h new file mode 100644 index 0000000000..38d9247488 --- /dev/null +++ b/protocols/MRA/src/Sdk/ListMT.h @@ -0,0 +1,360 @@ +/*
+ * Copyright (c) 2003 Rozhuk Ivan <rozhuk.im@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */ +
+
+
+#if !defined(AFX_LIST_MT__H__INCLUDED_)
+#define AFX_LIST_MT__H__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#include <InterlockedFunctions.h>
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(push)
+#endif
+#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size
+#endif
+#endif
+
+
+// структура для работы со списком, элемент списка
+typedef struct _LIST_MT_ITEM
+{
+#ifdef __cplusplus
+ _LIST_MT_ITEM *plmtiPrev; // *предыдущий элемент в списке
+ _LIST_MT_ITEM *plmtiNext; // *следующий элемент в списке
+#else
+ LPVOID *plmtiPrev; // *предыдущий элемент в списке
+ LPVOID *plmtiNext; // *следующий элемент в списке
+#endif
+ LPVOID lpListMT; // указатель на заголовок списка, см структуру ниже
+ LPVOID lpData; // указатель на данные, связанные с элементом списка
+}LIST_MT_ITEM, *PLIST_MT_ITEM, *LPLIST_MT_ITEM;
+typedef CONST PLIST_MT_ITEM PCLIST_MT_ITEM, LPCLIST_MT_ITEM;
+
+
+// структура для работы со списком, заголовок списка
+typedef struct _LIST_MT
+{
+ size_t nCount; // *колличество элементов в списке
+ PLIST_MT_ITEM plmtiFirst; // *указывает на первый элемент в списке
+ PLIST_MT_ITEM plmtiLast; // *указывает на последний элемент в списке
+ CRITICAL_SECTION cs; // *section for exclysive access to List
+}LIST_MT, *PLIST_MT, *LPLIST_MT;
+typedef CONST PLIST_MT PCLIST_MT, LPCLIST_MT;
+
+
+// структура для работы с итератором
+typedef struct _LIST_MT_ITERATOR
+{
+ PLIST_MT_ITEM plmtListMTItem;
+}LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR;
+//typedef LIST_MT_ITEM LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR;
+typedef CONST PLIST_MT_ITERATOR PCLIST_MT_ITERATOR, LPCLIST_MT_ITERATOR;
+
+
+
+
+__inline DWORD ListMTInitialize(PCLIST_MT pclmtListMT,DWORD dwSpinCount)
+{
+ DWORD dwRetErrorCode;
+
+#if (_WIN32_WINNT >= 0x0403)
+ if (InitializeCriticalSectionAndSpinCount(&pclmtListMT->cs,((dwSpinCount)? (dwSpinCount | 0x80000000):0L)))
+#else
+ InitializeCriticalSection(&pclmtListMT->cs);
+ if (TRUE)
+#endif
+ {
+ InterlockedExchangePointer((volatile PVOID*)&pclmtListMT->nCount,NULL);
+ pclmtListMT->plmtiFirst=NULL;
+ pclmtListMT->plmtiLast=NULL;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=GetLastError();
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline void ListMTDestroy(PCLIST_MT pclmtListMT)
+{
+ InterlockedExchangePointer((volatile PVOID*)&pclmtListMT->nCount,NULL);
+ pclmtListMT->plmtiFirst=NULL;
+ pclmtListMT->plmtiLast=NULL;
+ DeleteCriticalSection(&pclmtListMT->cs);
+ SecureZeroMemory(&pclmtListMT->cs,sizeof(CRITICAL_SECTION));
+}
+
+
+__inline BOOL ListMTTryLock(PCLIST_MT pclmtListMT)
+{
+#if (_WIN32_WINNT >= 0x0400)
+ return(TryEnterCriticalSection(&pclmtListMT->cs));
+#else
+ return(FALSE);
+#endif
+}
+
+class mt_lock
+{
+ PCLIST_MT m_list;
+
+public:
+ __forceinline mt_lock(PCLIST_MT _pList) :
+ m_list( _pList )
+ { EnterCriticalSection(&_pList->cs);
+ }
+
+ __forceinline ~mt_lock()
+ { LeaveCriticalSection(&m_list->cs);
+ }
+};
+
+__inline size_t ListMTGetCount(PCLIST_MT pclmtListMT)
+{
+ return((size_t)InterlockedCompareExchangePointer((LPVOID*)&pclmtListMT->nCount,NULL,NULL));
+}
+
+
+__inline size_t ListMTItemAdd(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem,LPVOID lpData)
+{
+ size_t dwRet=(size_t)InterlockedIncrementPointer(&pclmtListMT->nCount);//pclmtListMT->nCount++;
+ pclmtListMTItem->lpData=lpData;
+ pclmtListMTItem->lpListMT=pclmtListMT;
+
+ if (pclmtListMT->plmtiLast)
+ {// add node to end of list
+ pclmtListMTItem->plmtiPrev=pclmtListMT->plmtiLast;
+ pclmtListMTItem->plmtiNext=NULL;
+ pclmtListMT->plmtiLast->plmtiNext=pclmtListMTItem;
+ pclmtListMT->plmtiLast=pclmtListMTItem;
+ }else{// add the first node to the linked list
+ pclmtListMTItem->plmtiPrev=NULL;
+ pclmtListMTItem->plmtiNext=NULL;
+ pclmtListMT->plmtiFirst=pclmtListMTItem;
+ pclmtListMT->plmtiLast=pclmtListMTItem;
+ }
+
+return(dwRet);
+}
+
+
+__inline DWORD ListMTItemDelete(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem)
+{
+ DWORD dwRetErrorCode;
+
+ if (pclmtListMTItem->lpListMT==pclmtListMT && pclmtListMT)
+ {// Данный элемент принадлежит к этому списку, можно удалить.
+ PLIST_MT_ITEM plmtiPrevNode=pclmtListMTItem->plmtiPrev,plmtiNextNode=pclmtListMTItem->plmtiNext;
+
+ if (plmtiPrevNode || plmtiNextNode)
+ {
+ if (plmtiPrevNode && plmtiNextNode==NULL)
+ {// This is the start node in the list to delete
+ // отключился последний подключившийся
+ plmtiPrevNode->plmtiNext=NULL;
+ pclmtListMT->plmtiLast=plmtiPrevNode;
+ }else{
+ if (plmtiPrevNode==NULL && plmtiNextNode)
+ {// This is the end node in the list to delete
+ // отключился первый подключившийся
+ plmtiNextNode->plmtiPrev=NULL;
+ pclmtListMT->plmtiFirst=plmtiNextNode;
+ }else{// оключился клиент не первый и не последний
+ //if (plmtiPrev && plmtiNext)
+ {// Neither start node nor end node in the list
+ plmtiPrevNode->plmtiNext=plmtiNextNode;
+ plmtiNextNode->plmtiPrev=plmtiPrevNode;
+ }
+ }
+ }
+ }else{// This is the only node in the list to delete
+ pclmtListMT->plmtiFirst=NULL;
+ pclmtListMT->plmtiLast=NULL;
+ }
+
+ pclmtListMTItem->lpListMT=NULL;
+ InterlockedDecrementPointer(&pclmtListMT->nCount);// pclmtListMT->nCount--;
+ dwRetErrorCode=NO_ERROR;
+ }else{// попытались удалить элемент не относящийся к данному списку
+ dwRetErrorCode=ERROR_INVALID_HANDLE;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline LPVOID ListMTItemDataGet(PCLIST_MT_ITEM pclmtListMTItem)
+{
+ return(pclmtListMTItem->lpData);
+}
+
+
+__inline void ListMTItemDataSet(PCLIST_MT_ITEM pclmtListMTItem, LPVOID lpData)
+{
+ pclmtListMTItem->lpData=lpData;
+}
+
+
+__inline DWORD ListMTItemGetFirst(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ DWORD dwRetErrorCode;
+
+ if (pclmtListMT->plmtiFirst)
+ {
+ if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiFirst;
+ if (plpData) (*plpData)=pclmtListMT->plmtiFirst->lpData;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_NO_MORE_ITEMS;
+ }
+return(dwRetErrorCode);
+}
+
+
+__inline DWORD ListMTItemGetLast(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ DWORD dwRetErrorCode;
+
+ if (pclmtListMT->plmtiLast)
+ {
+ if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiLast;
+ if (plpData) (*plpData)=pclmtListMT->plmtiLast->lpData;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_NO_MORE_ITEMS;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+__inline void ListMTItemSwap(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem1,PCLIST_MT_ITEM pclmtListMTItem2)
+{// поменять два элемента списка местами, даже если они из разных списков
+
+ if (pclmtListMTItem1!=pclmtListMTItem2)
+ {// это разные элементы списка
+ PLIST_MT_ITEM lpTemp;
+
+ lpTemp=pclmtListMTItem1->plmtiPrev;
+ if ((pclmtListMTItem1->plmtiPrev=pclmtListMTItem2->plmtiPrev)==NULL)
+ {// pclmtListMTItem2 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem1
+ pclmtListMT->plmtiFirst=pclmtListMTItem1;
+ }
+
+ if ((pclmtListMTItem2->plmtiPrev=lpTemp)==NULL)
+ {// pclmtListMTItem1 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem2
+ pclmtListMT->plmtiFirst=pclmtListMTItem2;
+ }
+
+
+ lpTemp=pclmtListMTItem1->plmtiNext;
+ if ((pclmtListMTItem1->plmtiNext=pclmtListMTItem2->plmtiNext)==NULL)
+ {// pclmtListMTItem2 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem1
+ pclmtListMT->plmtiLast=pclmtListMTItem1;
+ }
+
+ if ((pclmtListMTItem2->plmtiNext=lpTemp)==NULL)
+ {// pclmtListMTItem1 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem2
+ pclmtListMT->plmtiLast=pclmtListMTItem2;
+ }
+ }
+}
+
+
+__inline BOOL ListMTIteratorMoveFirst(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiFirst)? TRUE:FALSE);
+}
+
+
+__inline BOOL ListMTIteratorMoveLast(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiLast)? TRUE:FALSE);
+}
+
+
+__inline BOOL ListMTIteratorMovePrev(PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ BOOL bRet=FALSE;
+
+ if (pclmtiIterator->plmtListMTItem)
+ {
+ if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiPrev) bRet=TRUE;
+ }
+return(bRet);
+}
+
+
+__inline BOOL ListMTIteratorMoveNext(PCLIST_MT_ITERATOR pclmtiIterator)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ BOOL bRet=FALSE;
+
+ if (pclmtiIterator->plmtListMTItem)
+ {
+ if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiNext) bRet=TRUE;
+ }
+return(bRet);
+}
+
+
+__inline DWORD ListMTIteratorGet(PCLIST_MT_ITERATOR pclmtiIterator,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData)
+{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock
+ DWORD dwRetErrorCode;
+
+ if (pclmtiIterator->plmtListMTItem)
+ {
+ if (pplmtListMTItem) (*pplmtListMTItem)=pclmtiIterator->plmtListMTItem;
+ if (plpData) (*plpData)=pclmtiIterator->plmtListMTItem->lpData;
+ dwRetErrorCode=NO_ERROR;
+ }else{
+ dwRetErrorCode=ERROR_NO_MORE_ITEMS;
+ }
+return(dwRetErrorCode);
+}
+
+
+
+#if defined(_MSC_VER)
+#if _MSC_VER >= 800
+#if _MSC_VER >= 1200
+#pragma warning(pop)
+#else
+#pragma warning(default:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size
+#endif
+#endif
+#endif
+
+
+
+#endif // !defined(AFX_LIST_MT__H__INCLUDED_)
|