//------------------------------------------------------------------------------
// File: WXList.h
//
// Desc: DirectShow base classes - defines a non-MFC generic template list
//       class.
//
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


/* A generic list of pointers to objects.
   No storage management or copying is done on the objects pointed to.
   Objectives: avoid using MFC libraries in ndm kernel mode and
   provide a really useful list type.

   The class is thread safe in that separate threads may add and
   delete items in the list concurrently although the application
   must ensure that constructor and destructor access is suitably
   synchronised. An application can cause deadlock with operations
   which use two lists by simultaneously calling
   list1->Operation(list2) and list2->Operation(list1).  So don't!

   The names must not conflict with MFC classes as an application
   may use both.
   */

#ifndef __WXLIST__
#define __WXLIST__

   /* A POSITION represents (in some fashion that's opaque) a cursor
      on the list that can be set to identify any element.  NULL is
      a valid value and several operations regard NULL as the position
      "one step off the end of the list".  (In an n element list there
      are n+1 places to insert and NULL is that "n+1-th" value).
      The POSITION of an element in the list is only invalidated if
      that element is deleted.  Move operations may mean that what
      was a valid POSITION in one list is now a valid POSITION in
      a different list.

      Some operations which at first sight are illegal are allowed as
      harmless no-ops.  For instance RemoveHead is legal on an empty
      list and it returns NULL.  This allows an atomic way to test if
      there is an element there, and if so, get it.  The two operations
      AddTail and RemoveHead thus implement a MONITOR (See Hoare's paper).

      Single element operations return POSITIONs, non-NULL means it worked.
      whole list operations return a BOOL.  TRUE means it all worked.

      This definition is the same as the POSITION type for MFCs, so we must
      avoid defining it twice.
   */
#ifndef __AFX_H__
struct __POSITION { int unused; };
typedef __POSITION* POSITION;
#endif

const int DEFAULTCACHE = 10;    /* Default node object cache size */

/* A class representing one node in a list.
   Each node knows a pointer to it's adjacent nodes and also a pointer
   to the object that it looks after.
   All of these pointers can be retrieved or set through member functions.
*/
class CBaseList 
#ifdef DEBUG
    : public CBaseObject
#endif
{
    /* Making these classes inherit from CBaseObject does nothing
       functionally but it allows us to check there are no memory
       leaks in debug builds. 
    */

public:

#ifdef DEBUG
    class CNode : public CBaseObject {
#else
    class CNode {
#endif

        CNode *m_pPrev;         /* Previous node in the list */
        CNode *m_pNext;         /* Next node in the list */
        void *m_pObject;      /* Pointer to the object */

    public:

        /* Constructor - initialise the object's pointers */
        CNode()
#ifdef DEBUG
            : CBaseObject(NAME("List node"))
#endif
        {
        };


        /* Return the previous node before this one */
        __out CNode *Prev() const { return m_pPrev; };


        /* Return the next node after this one */
        __out CNode *Next() const { return m_pNext; };


        /* Set the previous node before this one */
        void SetPrev(__in_opt CNode *p) { m_pPrev = p; };


        /* Set the next node after this one */
        void SetNext(__in_opt CNode *p) { m_pNext = p; };


        /* Get the pointer to the object for this node */
        __out void *GetData() const { return m_pObject; };


        /* Set the pointer to the object for this node */
        void SetData(__in void *p) { m_pObject = p; };
    };

    class CNodeCache
    {
    public:
        CNodeCache(INT iCacheSize) : m_iCacheSize(iCacheSize),
                                     m_pHead(NULL),
                                     m_iUsed(0)
                                     {};
        ~CNodeCache() {
            CNode *pNode = m_pHead;
            while (pNode) {
                CNode *pCurrent = pNode;
                pNode = pNode->Next();
                delete pCurrent;
            }
        };
        void AddToCache(__inout CNode *pNode)
        {
            if (m_iUsed < m_iCacheSize) {
                pNode->SetNext(m_pHead);
                m_pHead = pNode;
                m_iUsed++;
            } else {
                delete pNode;
            }
        };
        CNode *RemoveFromCache()
        {
            CNode *pNode = m_pHead;
            if (pNode != NULL) {
                m_pHead = pNode->Next();
                m_iUsed--;
                ASSERT(m_iUsed >= 0);
            } else {
                ASSERT(m_iUsed == 0);
            }
            return pNode;
        };
    private:
        INT m_iCacheSize;
        INT m_iUsed;
        CNode *m_pHead;
    };

protected:

    CNode* m_pFirst;    /* Pointer to first node in the list */
    CNode* m_pLast;     /* Pointer to the last node in the list */
    LONG m_Count;       /* Number of nodes currently in the list */

private:

    CNodeCache m_Cache; /* Cache of unused node pointers */

private:

    /* These override the default copy constructor and assignment
       operator for all list classes. They are in the private class
       declaration section so that anybody trying to pass a list
       object by value will generate a compile time error of
       "cannot access the private member function". If these were
       not here then the compiler will create default constructors
       and assignment operators which when executed first take a
       copy of all member variables and then during destruction
       delete them all. This must not be done for any heap
       allocated data.
    */
    CBaseList(const CBaseList &refList);
    CBaseList &operator=(const CBaseList &refList);

public:

    CBaseList(__in_opt LPCTSTR pName,
              INT iItems);

    CBaseList(__in_opt LPCTSTR pName);
#ifdef UNICODE
    CBaseList(__in_opt LPCSTR pName,
              INT iItems);

    CBaseList(__in_opt LPCSTR pName);
#endif
    ~CBaseList();

    /* Remove all the nodes from *this i.e. make the list empty */
    void RemoveAll();


    /* Return a cursor which identifies the first element of *this */
    __out_opt POSITION GetHeadPositionI() const;


    /* Return a cursor which identifies the last element of *this */
    __out_opt POSITION GetTailPositionI() const;


    /* Return the number of objects in *this */
    int GetCountI() const;

protected:
    /* Return the pointer to the object at rp,
       Update rp to the next node in *this
       but make it NULL if it was at the end of *this.
       This is a wart retained for backwards compatibility.
       GetPrev is not implemented.
       Use Next, Prev and Get separately.
    */
    __out void *GetNextI(__inout POSITION& rp) const;


    /* Return a pointer to the object at p
       Asking for the object at NULL will return NULL harmlessly.
    */
    __out_opt void *GetI(__in_opt POSITION p) const;
    __out void *GetValidI(__in POSITION p) const;

public:
    /* return the next / prev position in *this
       return NULL when going past the end/start.
       Next(NULL) is same as GetHeadPosition()
       Prev(NULL) is same as GetTailPosition()
       An n element list therefore behaves like a n+1 element
       cycle with NULL at the start/end.

       !!WARNING!! - This handling of NULL is DIFFERENT from GetNext.

       Some reasons are:
       1. For a list of n items there are n+1 positions to insert
          These are conveniently encoded as the n POSITIONs and NULL.
       2. If you are keeping a list sorted (fairly common) and you
          search forward for an element to insert before and don't
          find it you finish up with NULL as the element before which
          to insert.  You then want that NULL to be a valid POSITION
          so that you can insert before it and you want that insertion
          point to mean the (n+1)-th one that doesn't have a POSITION.
          (symmetrically if you are working backwards through the list).
       3. It simplifies the algebra which the methods generate.
          e.g. AddBefore(p,x) is identical to AddAfter(Prev(p),x)
          in ALL cases.  All the other arguments probably are reflections
          of the algebraic point.
    */
    __out_opt POSITION Next(__in_opt POSITION pos) const
    {
        if (pos == NULL) {
            return (POSITION) m_pFirst;
        }
        CNode *pn = (CNode *) pos;
        return (POSITION) pn->Next();
    } //Next

    // See Next
    __out_opt POSITION Prev(__in_opt POSITION pos) const
    {
        if (pos == NULL) {
            return (POSITION) m_pLast;
        }
        CNode *pn = (CNode *) pos;
        return (POSITION) pn->Prev();
    } //Prev


    /* Return the first position in *this which holds the given
       pointer.  Return NULL if the pointer was not not found.
    */
protected:
    __out_opt POSITION FindI( __in void * pObj) const;

    // ??? Should there be (or even should there be only)
    // ??? POSITION FindNextAfter(void * pObj, POSITION p)
    // ??? And of course FindPrevBefore too.
    // ??? List.Find(&Obj) then becomes List.FindNextAfter(&Obj, NULL)


    /* Remove the first node in *this (deletes the pointer to its
       object from the list, does not free the object itself).
       Return the pointer to its object.
       If *this was already empty it will harmlessly return NULL.
    */
    __out_opt void *RemoveHeadI();


    /* Remove the last node in *this (deletes the pointer to its
       object from the list, does not free the object itself).
       Return the pointer to its object.
       If *this was already empty it will harmlessly return NULL.
    */
    __out_opt void *RemoveTailI();


    /* Remove the node identified by p from the list (deletes the pointer
       to its object from the list, does not free the object itself).
       Asking to Remove the object at NULL will harmlessly return NULL.
       Return the pointer to the object removed.
    */
    __out_opt void *RemoveI(__in_opt POSITION p);

    /* Add single object *pObj to become a new last element of the list.
       Return the new tail position, NULL if it fails.
       If you are adding a COM objects, you might want AddRef it first.
       Other existing POSITIONs in *this are still valid
    */
    __out_opt POSITION AddTailI(__in void * pObj);
public:


    /* Add all the elements in *pList to the tail of *this.
       This duplicates all the nodes in *pList (i.e. duplicates
       all its pointers to objects).  It does not duplicate the objects.
       If you are adding a list of pointers to a COM object into the list
       it's a good idea to AddRef them all  it when you AddTail it.
       Return TRUE if it all worked, FALSE if it didn't.
       If it fails some elements may have been added.
       Existing POSITIONs in *this are still valid

       If you actually want to MOVE the elements, use MoveToTail instead.
    */
    BOOL AddTail(__in CBaseList *pList);


    /* Mirror images of AddHead: */

    /* Add single object to become a new first element of the list.
       Return the new head position, NULL if it fails.
       Existing POSITIONs in *this are still valid
    */
protected:
    __out_opt POSITION AddHeadI(__in void * pObj);
public:

    /* Add all the elements in *pList to the head of *this.
       Same warnings apply as for AddTail.
       Return TRUE if it all worked, FALSE if it didn't.
       If it fails some of the objects may have been added.

       If you actually want to MOVE the elements, use MoveToHead instead.
    */
    BOOL AddHead(__in CBaseList *pList);


    /* Add the object *pObj to *this after position p in *this.
       AddAfter(NULL,x) adds x to the start - equivalent to AddHead
       Return the position of the object added, NULL if it failed.
       Existing POSITIONs in *this are undisturbed, including p.
    */
protected:
    __out_opt POSITION AddAfterI(__in_opt POSITION p, __in void * pObj);
public:

    /* Add the list *pList to *this after position p in *this
       AddAfter(NULL,x) adds x to the start - equivalent to AddHead
       Return TRUE if it all worked, FALSE if it didn't.
       If it fails, some of the objects may be added
       Existing POSITIONs in *this are undisturbed, including p.
    */
    BOOL AddAfter(__in_opt POSITION p, __in CBaseList *pList);


    /* Mirror images:
       Add the object *pObj to this-List after position p in *this.
       AddBefore(NULL,x) adds x to the end - equivalent to AddTail
       Return the position of the new object, NULL if it fails
       Existing POSITIONs in *this are undisturbed, including p.
    */
    protected:
    __out_opt POSITION AddBeforeI(__in_opt POSITION p, __in void * pObj);
    public:

    /* Add the list *pList to *this before position p in *this
       AddAfter(NULL,x) adds x to the start - equivalent to AddHead
       Return TRUE if it all worked, FALSE if it didn't.
       If it fails, some of the objects may be added
       Existing POSITIONs in *this are undisturbed, including p.
    */
    BOOL AddBefore(__in_opt POSITION p, __in CBaseList *pList);


    /* Note that AddAfter(p,x) is equivalent to AddBefore(Next(p),x)
       even in cases where p is NULL or Next(p) is NULL.
       Similarly for mirror images etc.
       This may make it easier to argue about programs.
    */



    /* The following operations do not copy any elements.
       They move existing blocks of elements around by switching pointers.
       They are fairly efficient for long lists as for short lists.
       (Alas, the Count slows things down).

       They split the list into two parts.
       One part remains as the original list, the other part
       is appended to the second list.  There are eight possible
       variations:
       Split the list {after/before} a given element
       keep the {head/tail} portion in the original list
       append the rest to the {head/tail} of the new list.

       Since After is strictly equivalent to Before Next
       we are not in serious need of the Before/After variants.
       That leaves only four.

       If you are processing a list left to right and dumping
       the bits that you have processed into another list as
       you go, the Tail/Tail variant gives the most natural result.
       If you are processing in reverse order, Head/Head is best.

       By using NULL positions and empty lists judiciously either
       of the other two can be built up in two operations.

       The definition of NULL (see Next/Prev etc) means that
       degenerate cases include
          "move all elements to new list"
          "Split a list into two lists"
          "Concatenate two lists"
          (and quite a few no-ops)

       !!WARNING!! The type checking won't buy you much if you get list
       positions muddled up - e.g. use a POSITION that's in a different
       list and see what a mess you get!
    */

    /* Split *this after position p in *this
       Retain as *this the tail portion of the original *this
       Add the head portion to the tail end of *pList
       Return TRUE if it all worked, FALSE if it didn't.

       e.g.
          foo->MoveToTail(foo->GetHeadPosition(), bar);
              moves one element from the head of foo to the tail of bar
          foo->MoveToTail(NULL, bar);
              is a no-op, returns NULL
          foo->MoveToTail(foo->GetTailPosition, bar);
              concatenates foo onto the end of bar and empties foo.

       A better, except excessively long name might be
           MoveElementsFromHeadThroughPositionToOtherTail
    */
    BOOL MoveToTail(__in_opt POSITION pos, __in CBaseList *pList);


    /* Mirror image:
       Split *this before position p in *this.
       Retain in *this the head portion of the original *this
       Add the tail portion to the start (i.e. head) of *pList

       e.g.
          foo->MoveToHead(foo->GetTailPosition(), bar);
              moves one element from the tail of foo to the head of bar
          foo->MoveToHead(NULL, bar);
              is a no-op, returns NULL
          foo->MoveToHead(foo->GetHeadPosition, bar);
              concatenates foo onto the start of bar and empties foo.
    */
    BOOL MoveToHead(__in_opt POSITION pos, __in CBaseList *pList);


    /* Reverse the order of the [pointers to] objects in *this
    */
    void Reverse();


    /* set cursor to the position of each element of list in turn  */
    #define TRAVERSELIST(list, cursor)               \
    for ( cursor = (list).GetHeadPosition()           \
        ; cursor!=NULL                               \
        ; cursor = (list).Next(cursor)                \
        )


    /* set cursor to the position of each element of list in turn
       in reverse order
    */
    #define REVERSETRAVERSELIST(list, cursor)        \
    for ( cursor = (list).GetTailPosition()           \
        ; cursor!=NULL                               \
        ; cursor = (list).Prev(cursor)                \
        )

}; // end of class declaration

template<class OBJECT> class CGenericList : public CBaseList
{
public:
    CGenericList(__in_opt LPCTSTR pName,
                 INT iItems,
                 BOOL bLock = TRUE,
                 BOOL bAlert = FALSE) :
                     CBaseList(pName, iItems) {
        UNREFERENCED_PARAMETER(bAlert);
        UNREFERENCED_PARAMETER(bLock);
    };
    CGenericList(__in_opt LPCTSTR pName) :
                     CBaseList(pName) {
    };

    __out_opt POSITION GetHeadPosition() const { return (POSITION)m_pFirst; }
    __out_opt POSITION GetTailPosition() const { return (POSITION)m_pLast; }
    int GetCount() const { return m_Count; }

    __out OBJECT *GetNext(__inout POSITION& rp) const { return (OBJECT *) GetNextI(rp); }

    __out_opt OBJECT *Get(__in_opt POSITION p) const { return (OBJECT *) GetI(p); }
    __out OBJECT *GetValid(__in POSITION p) const { return (OBJECT *) GetValidI(p); }
    __out_opt OBJECT *GetHead() const  { return Get(GetHeadPosition()); }

    __out_opt OBJECT *RemoveHead() { return (OBJECT *) RemoveHeadI(); }

    __out_opt OBJECT *RemoveTail() { return (OBJECT *) RemoveTailI(); }

    __out_opt OBJECT *Remove(__in_opt POSITION p) { return (OBJECT *) RemoveI(p); }
    __out_opt POSITION AddBefore(__in_opt POSITION p, __in OBJECT * pObj) { return AddBeforeI(p, pObj); }
    __out_opt POSITION AddAfter(__in_opt POSITION p, __in OBJECT * pObj)  { return AddAfterI(p, pObj); }
    __out_opt POSITION AddHead(__in OBJECT * pObj) { return AddHeadI(pObj); }
    __out_opt POSITION AddTail(__in OBJECT * pObj)  { return AddTailI(pObj); }
    BOOL AddTail(__in CGenericList<OBJECT> *pList)
            { return CBaseList::AddTail((CBaseList *) pList); }
    BOOL AddHead(__in CGenericList<OBJECT> *pList)
            { return CBaseList::AddHead((CBaseList *) pList); }
    BOOL AddAfter(__in_opt POSITION p, __in CGenericList<OBJECT> *pList)
            { return CBaseList::AddAfter(p, (CBaseList *) pList); };
    BOOL AddBefore(__in_opt POSITION p, __in CGenericList<OBJECT> *pList)
            { return CBaseList::AddBefore(p, (CBaseList *) pList); };
    __out_opt POSITION Find( __in OBJECT * pObj) const { return FindI(pObj); }
}; // end of class declaration



/* These define the standard list types */

typedef CGenericList<CBaseObject> CBaseObjectList;
typedef CGenericList<IUnknown> CBaseInterfaceList;

#endif /* __WXLIST__ */

