コード例 #1
0
/*-------------------------------------------------------------------
| Return the length of the object identified by the cursor Curs
 -------------------------------------------------------------------*/
int
APIENTRY
List_ItemLength(
                LPVOID Curs
                )
{
    LIST pit;
    if (Curs==NULL) {
        TRACE_ERROR("Bug: List_ItemLength NULL cursor.  Continuing...", FALSE);
        return 0;
    }
    MOVEBACK(Curs)
    pit = (LIST)Curs;
    return pit->iLen;
}
コード例 #2
0
/*-----------------------------------------------------------------------
| Let L1 be *pl1 and L2 be *pl2
| L1 := L1[...Curs] || L2 || L1[Curs+1...]; L2 := empty
| Curs=NULL means insert L2 at the start of L1
| The elements themselves are not moved, so pointers to them remain valid.
|
| L1 gets the elements of L1 from the start up to and including the element
| that Curs points at, in their original order,
| followed by all the elements that were in L2, in their original order,
| followed by the rest of L1
 ------------------------------------------------------------------------*/
void
APIENTRY
List_InsertListAfter(
                     LIST l1,
                     LIST l2,
                     LPVOID Curs
                     )
{
    LIST pitA;     /* The element after Curs, could be anchor */
    LIST pit;      /* The start of the element that Curs points at
                   |  or the anchor block if Curs==NULL
                   */

    if ( (l1==NULL) || (l2==NULL)) {
        TRACE_ERROR("Bug: List_InsertListAfter with bogus list.  Continuing...", FALSE);
        return;
    }
    l1->bOK = l1->bOK && l2->bOK;
    l2->bOK = TRUE;
    if (l2->pitNext==l2) {
        /* no elements need moving */
    } else if ( l1->pitNext==l1) {
        /* the easy way to code this would be simply to switch the two
        |  pointers l1 and l2, but they are value parameters and we don't
        |  want to change that.
        */
        SwitchLists(l1,l2);
        return;
    } else {
        if (Curs==NULL) {
            pit = l1;
        } else {
            MOVEBACK(Curs)
            pit = (LIST)Curs;
        }
        /* pit points to a block to insert after, could be anchor */
        pitA = pit->pitNext;           /* Cannot be same as P, already checked */
        l2->pitNext->pitPrev = pit;    /*  P<-- elems-of-l2    A */
        l2->pitPrev->pitNext = pitA;   /*  P<-- elems-of-l2 -->A */
        pit->pitNext = l2->pitNext;    /*  P<-->elems-of-l2 -->A */
        pitA->pitPrev = l2->pitPrev;   /*  P<-->elems-of-l2<-->A */

        l2->pitNext = l2;
        l2->pitPrev = l2;
    }
}
コード例 #3
0
/*------------------------------------------------------------------
| Delete the item that Curs identifies.
| This will be only a few (maybe as little as 3) machine instructions
| quicker than DeleteForwards or DeleteBackwards but leaves Curs dangling.
| It is therefore NOT usually to be preferred.
| It may be useful when you have a function which returns an LPVOID
| since the argument does not need to be a variable.
|     Trivial example: List_Delete(List_First(L));
 -------------------------------------------------------------------*/
void
APIENTRY
List_Delete(
            LPVOID Curs
            )
{
    LIST pit;
    if (Curs==NULL) {
        TRACE_ERROR("Bug: List_Delete NULL item", FALSE);
        return;
    }
    MOVEBACK(Curs)
    pit = (LIST)Curs;
    pit->pitNext->pitPrev = pit->pitPrev;
    pit->pitPrev->pitNext = pit->pitNext;
    list_Free(pit->pBlock, pit);
}
コード例 #4
0
/*------------------------------------------------------------------
| Return the address of the object after Curs^.
| List_Prev(List_First(L)) == NULL;  List_Prev(NULL) is an error.
 -------------------------------------------------------------------*/
LPVOID
APIENTRY
List_Prev(
          LPVOID Curs
          )
{
    LIST pit;

    if (Curs==NULL) {
        TRACE_ERROR("Bug: List_Prev of NULL cursor.  Continuing...", FALSE);
        return NULL;
    }
    MOVEBACK(Curs)
    pit = (LIST)Curs;
    pit = pit->pitPrev;
    if (pit->bAnchor) {
        return NULL;
    } else {
        return &(pit->Data);
    }
}
コード例 #5
0
/*-----------------------------------------------------------------------
| Let l1 be l1 and l2 be l2
| Split l2 off from the front of l1:    final l2,l1 = original l1
|
| Split l1 into l2: objects of l1 up to and including Curs object
|               l1: objects of l1 after Curs
| Any original contents of l2 are freed.
| List_Spilt(l1, l2, NULL) splits l1 before the first object so l1 gets all.
| The elements themselves are not moved.
 ------------------------------------------------------------------------*/
void
APIENTRY
List_SplitAfter(
                LIST l1,
                LIST l2,
                LPVOID Curs
                )
{
    LIST pit;

    if ((l1==NULL) || (l2==NULL)) {
        TRACE_ERROR("Bug: List_SplitAfter bogus list.  Continuing...", FALSE);
        return;
    }
    if (l2->pitNext!=l2) {
        List_Clear(l2);
    };
    if (Curs!=NULL) {
        MOVEBACK(Curs)
        pit = (LIST)Curs;
        /* Curs had better be an item in l1! l2 had better be created! */
        if (pit==l1) {
            l1->bOK = FALSE;
            l2->bOK = FALSE;
            return;
        }
        if (pit->pitNext==l1) {
            /* transfer whole of l2 to l1 */
            SwitchLists(l2,l1);
            return;
        }
        l2->pitPrev = pit;
        l2->pitNext = l1->pitNext;
        l1->pitNext = pit->pitNext;
        pit->pitNext = l2;
        l2->pitNext->pitPrev = l2;
        l1->pitNext->pitPrev = l1;
    }
}
コード例 #6
0
/*----------------------------------------------------------------------
| Split l2 off from the back of l1:  final l1,l2 = original l1
|
| Split l1 into l1: objects of l1 up to but not including Curs object
|               l2: objects of l1 from Curs onwards
| Any original contants of l2 are freed.
| List_Spilt(l1, l2, NULL) splits l1 after the last object so l1 gets all.
| The elements themselves are not moved.
 -----------------------------------------------------------------------*/
void
APIENTRY
List_SplitBefore(
                 LIST l1,
                 LIST l2,
                 LPVOID Curs
                 )
{
    LIST pit;

    if ((l1==NULL) || (l2==NULL)) {
        TRACE_ERROR("Bug: List_SplitBefore bogus list.  Continuing...", FALSE);
        return;
    }
    if (l2->pitNext!=l2) {
        List_Clear(l2);
    }
    if (Curs!=NULL) {
        MOVEBACK(Curs)
        pit = (LIST)Curs;
        /* Curs had better be an item in L1! L2 had better be created! */
        if (pit==l1) {
            l1->bOK = FALSE;
            l2->bOK = FALSE;
            return;
        }
        if (pit->pitPrev==l1) {
            SwitchLists(l2,l1);
            return;
        }
        l2->pitNext = pit;
        l2->pitPrev = l1->pitPrev;
        l1->pitPrev = pit->pitPrev;
        pit->pitPrev = l2;
        l2->pitPrev->pitNext = l2;
        l1->pitPrev->pitNext = l1;
    }
}
コード例 #7
0
ファイル: list.cpp プロジェクト: firewood/sdkdiff
/*--------------------------------------------------------------------
| Add an item holding Object to lst immediately before Curs.
| List_AddBefore(Lst,NULL,Object,uLen) adds it to the end of the list
 ---------------------------------------------------------------------*/
void
APIENTRY
List_AddBefore(
               LIST lst,
               LPVOID Curs,
               LPVOID pObject,
               UINT uLen
                            )
{
    LIST pitNew;
    LIST pitBefore;

    if (lst==NULL) {
        TRACE_ERROR("Bug: List_AddBefore in bogus list.  Continuing...", FALSE);
        return;
    }
    if (Curs==NULL) {
        List_AddLast(lst, pObject, uLen);
    } else {
        MOVEBACK(Curs);
        pitBefore = (LIST)Curs;
        pitNew = (LIST)list_Alloc(iHeaderSize+uLen);
        if (pitNew==NULL) {
            lst->bOK = FALSE;
            return;
        }
        pitNew->pBlock = pCurrent;
        LeaveCriticalSection(&CritSec);
        pitNew->iLen = uLen;
        pitNew->pitNext = pitBefore;
        pitNew->pitPrev = pitBefore->pitPrev;
        pitBefore->pitPrev->pitNext = pitNew;
        pitBefore->pitPrev = pitNew;
        pitNew->bAnchor = FALSE;
        memcpy( &(pitNew->Data), pObject, uLen );
    }
}
コード例 #8
0
/*-----------------------------------------------------------------------
| Delete the item that Curs identifies and return a cursor that
| identifies the previous item (NULL if already on first)
 ------------------------------------------------------------------------*/
LPVOID
APIENTRY
List_DeleteBackwards(
                     LPVOID Curs
                     )
{
    LIST pitDel;  /* the one to delete */
    LIST pitB;    /* the one before */

    if (Curs==NULL) {
        TRACE_ERROR("List_DeleteBackwards NULL cursor.  Continuing...", FALSE);
        return NULL;
    }
    MOVEBACK(Curs)
    pitDel = (LIST)Curs;
    pitB = pitDel->pitPrev;
    pitDel->pitNext->pitPrev = pitB;
    pitB->pitNext = pitDel->pitNext;
    list_Free(pitDel->pBlock, pitDel);
    if (pitB->bAnchor)
        return NULL;
    else
        return (char *)&(pitB->Data);
}
コード例 #9
0
/*-----------------------------------------------------------------------
| Delete the item that Curs identifies and return a cursor that
| identifies the next item (NULL if already on last)
 ------------------------------------------------------------------------*/
LPVOID
APIENTRY
List_DeleteForwards(
                    LPVOID Curs
                    )
{
    LIST pitDel;  /* the item to delete */
    LIST pitN;    /* the item after (could be anchor) */
    if (Curs==NULL) {
        TRACE_ERROR("Bug: List_DeleteForwards NULL cursor. Continuing...", FALSE);
        return NULL;
    }
    MOVEBACK(Curs)
    pitDel = (LIST)Curs;
    pitN = pitDel->pitNext;

    pitN->pitPrev = pitDel->pitPrev;
    pitDel->pitPrev->pitNext = pitN;
    list_Free(pitDel->pBlock, pitDel);
    if (pitN->bAnchor)
        return NULL;
    else
        return (char *)&(pitN->Data);
}
コード例 #10
0
/*--------------------------------------------------------------------
| Return the address of the place for uLen bytes of data in a new
| item immediately after Curs.
| List_NewAfter(Lst,NULL,uLen) returns a pointer
| to space for uLen bytes in a new first element.
 ---------------------------------------------------------------------*/
LPVOID
APIENTRY
List_NewAfter(
              LIST lst,
              LPVOID Curs,
              UINT uLen
              )
{
    LIST pitNew;
    LIST pitAfter;

    if (lst==NULL) {
        TRACE_ERROR("Bug: List_NewAfter in bogus list. Continuing...", FALSE);
        return NULL;
    }
    if (Curs==NULL) {
        return List_NewFirst(lst, uLen);
    } else {
        MOVEBACK(Curs);
        pitAfter = (LIST)Curs;
        pitNew = (LIST)list_Alloc(iHeaderSize+uLen);
        if (pitNew==NULL) {
            lst->bOK = FALSE;
            return NULL;
        }
        pitNew->pBlock = pCurrent;
        LeaveCriticalSection(&CritSec);
        pitNew->iLen = uLen;
        pitNew->pitPrev = pitAfter;
        pitNew->pitNext = pitAfter->pitNext;
        pitAfter->pitNext->pitPrev = pitNew;
        pitAfter->pitNext = pitNew;
        pitNew->bAnchor = FALSE;
        return (char *)&(pitNew->Data);
    }
}