/***********************************************************************
 * 
 *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 ***********************************************************************/

#ifndef _LIST_ENTRY_H_
#define _LIST_ENTRY_H_

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" 
{
#endif

//===[ Include files ]=====================================================

//#include <micasa_types.h>

//===[ Type definitions ]==================================================

#ifndef CSAPI
#if defined(WIN32)
#define CSAPI __stdcall
#else
#define CSAPI
#endif
#endif

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif

#ifndef INOUT
#define INOUT
#endif

#ifndef WIN32
//
// LIST_ENTRY Type
// Doubly linked list structure
//
typedef struct _LIST_ENTRY
{
   struct _LIST_ENTRY * volatile Flink;
   struct _LIST_ENTRY * volatile Blink;
} LIST_ENTRY, *PLIST_ENTRY;
#endif

//===[ Inlines functions   ]===============================================

//
// Inline functions for operating on LIST_ENTRY double-linked lists
//

__inline static void InitializeListHead(
   IN    PLIST_ENTRY       pListEntry )
{
   pListEntry->Flink = pListEntry->Blink = pListEntry;
}

__inline static void InsertEntryAfter(
   IN    PLIST_ENTRY       pListEntry,
   IN    PLIST_ENTRY       pAfterEntry )
{
   pListEntry->Flink = pAfterEntry->Flink;
   pListEntry->Blink = pAfterEntry;
   pListEntry->Flink->Blink = pAfterEntry->Flink = pListEntry;
}

__inline static void InsertEntryBefore(
   IN    PLIST_ENTRY       pListEntry,
   IN    PLIST_ENTRY       pBeforeEntry )
{
   pListEntry->Flink = pBeforeEntry;
   pListEntry->Blink = pBeforeEntry->Blink;
   pListEntry->Blink->Flink = pBeforeEntry->Blink = pListEntry;
}

__inline static void InsertHeadList(
   IN    PLIST_ENTRY       pListHead,
   IN    PLIST_ENTRY       pListEntry )
{
   pListEntry->Blink = pListHead;
   pListEntry->Flink = pListHead->Flink;
   pListEntry->Flink->Blink = pListHead->Flink = pListEntry;
}

__inline static void InsertTailList(
   IN    PLIST_ENTRY       pListHead,
   IN    PLIST_ENTRY       pListEntry )
{
   pListEntry->Flink = pListHead;
   pListEntry->Blink = pListHead->Blink;
   pListEntry->Blink->Flink = pListHead->Blink = pListEntry;
}

__inline static bool IsListEmpty(
   IN    PLIST_ENTRY       pListHead )
{
   bool rc = false;
   if(pListHead->Flink == pListHead)
      rc = true;
   return(rc);
}

__inline static void RemoveEntryList(
   IN    PLIST_ENTRY       pListEntry )
{
   pListEntry->Flink->Blink = pListEntry->Blink;
   pListEntry->Blink->Flink = pListEntry->Flink;
   pListEntry->Flink = pListEntry->Blink = (PLIST_ENTRY) 0xbaadf00d;
}

__inline static PLIST_ENTRY RemoveHeadList(
   IN    PLIST_ENTRY       pListHead )
{
   PLIST_ENTRY Entry = (PLIST_ENTRY)0;
   if(pListHead->Flink != pListHead)
   {
      Entry = pListHead->Flink;
      RemoveEntryList(Entry);
   }
   return(Entry);
}

__inline static PLIST_ENTRY RemoveTailList(
   IN    PLIST_ENTRY       pListHead )
{
   PLIST_ENTRY Entry= (PLIST_ENTRY)0;
   if(pListHead->Blink != pListHead)
   {
      Entry = pListHead->Blink;
      RemoveEntryList(Entry);
   }
   return(Entry);
}

__inline static PLIST_ENTRY GetFirstListEntry(
   IN    PLIST_ENTRY pList)
{
   PLIST_ENTRY Entry = (PLIST_ENTRY)0;
   if(pList != pList->Flink)
      Entry = pList->Flink;
   return(Entry);
}

__inline static PLIST_ENTRY GetNextListEntry(
   IN    PLIST_ENTRY pList,
   IN    PLIST_ENTRY pEntry)
{
   PLIST_ENTRY Entry = (PLIST_ENTRY)0;
   if(pList != pEntry->Flink)
      Entry = pEntry->Flink;
   return(Entry);
}


//=========================================================================


#if defined(__cplusplus) || defined(c_plusplus)
}
#endif // #if defined(__cplusplus) || defined(c_plusplus)

#endif // #ifndef _LIST_ENTRY_H_