From de6eb3e4bc30eff928dc932c03812ede3077926a Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 13 Oct 2012 08:54:34 +0000 Subject: MRA: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1900 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MRA/src/Sdk/ListMT.h | 360 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 protocols/MRA/src/Sdk/ListMT.h (limited to 'protocols/MRA/src/Sdk/ListMT.h') 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 + * 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 + +#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_) -- cgit v1.2.3