1 /******************************************************************************
2  *
3  *  Copyright (C) 2016 Realtek Corporation.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 /******************************************************************************
19 *
20 *	Module Name:
21 *	    bt_list.c
22 *
23 *	Abstract:
24 *	    To implement list data structure
25 *
26 *	Major Change History:
27 *	      When             Who         What
28 *    	--------------------------------------------------------------
29 *	    2010-06-04         W.Bi       Created
30 *
31 *	Notes:
32 *
33 ******************************************************************************/
34 #include "bt_list.h"
35 
36 //****************************************************************************
37 // Structure
38 //****************************************************************************
39 
40 
41 //****************************************************************************
42 // FUNCTION
43 //****************************************************************************
44 //Initialize a list with its header
ListInitializeHeader(PRT_LIST_HEAD ListHead)45 void ListInitializeHeader(PRT_LIST_HEAD ListHead)
46 {
47     ListHead->Next = ListHead;
48     ListHead->Prev = ListHead;
49 }
50 
51 /**
52     Tell whether the list is empty
53     \param [IN] ListHead          <RT_LIST_ENTRY>                 : List header of which to be test
54 */
ListIsEmpty(PRT_LIST_HEAD ListHead)55 unsigned char ListIsEmpty(PRT_LIST_HEAD ListHead)
56 {
57     return ListHead->Next == ListHead;
58 }
59 
60 /*
61     Insert a new entry between two known consecutive entries.
62     This is only for internal list manipulation where we know the prev&next entries already
63     @New : New element to be added
64     @Prev: previous element in the list
65     @Next: Next element in the list
66 */
67 void
ListAdd(PRT_LIST_ENTRY New,PRT_LIST_ENTRY Prev,PRT_LIST_ENTRY Next)68     ListAdd(
69     PRT_LIST_ENTRY New,
70     PRT_LIST_ENTRY Prev,
71     PRT_LIST_ENTRY Next
72     )
73 {
74     Next->Prev = New;
75     New->Next = Next;
76     New->Prev = Prev;
77     Prev->Next = New;
78 }
79 /**
80     Add a new entry to the list.
81     Insert a new entry after the specified head. This is good for implementing stacks.
82     \param [IN] ListNew            <RT_LIST_ENTRY>                 : new entry to be added
83     \param [IN OUT] ListHead    <RT_LIST_ENTRY>                 : List header after which to add new entry
84 */
85 void
ListAddToHead(PRT_LIST_ENTRY ListNew,PRT_LIST_HEAD ListHead)86 ListAddToHead(
87     PRT_LIST_ENTRY ListNew,
88     PRT_LIST_HEAD ListHead
89     )
90 {
91     ListAdd(ListNew, ListHead, ListHead->Next);
92 }
93 
94 /**
95     Add a new entry to the list.
96     Insert a new entry before the specified head. This is good for implementing queues.
97     \param [IN] ListNew            <RT_LIST_ENTRY>                 : new entry to be added
98     \param [IN OUT] ListHead    <RT_LIST_ENTRY>                 : List header before which to add new entry
99 */
100 void
ListAddToTail(PRT_LIST_ENTRY ListNew,PRT_LIST_HEAD ListHead)101 ListAddToTail(
102     PRT_LIST_ENTRY ListNew,
103     PRT_LIST_HEAD ListHead
104     )
105 {
106     ListAdd(ListNew, ListHead->Prev, ListHead);
107 }
108 
109 RT_LIST_ENTRY*
ListGetTop(PRT_LIST_HEAD ListHead)110 ListGetTop(
111     PRT_LIST_HEAD ListHead
112 )
113 {
114 
115     if (ListIsEmpty(ListHead))
116         return 0;
117 
118     return ListHead->Next;
119 }
120 
121 RT_LIST_ENTRY*
ListGetTail(PRT_LIST_HEAD ListHead)122 ListGetTail(
123     PRT_LIST_HEAD ListHead
124 )
125 {
126     if (ListIsEmpty(ListHead))
127         return 0;
128 
129     return ListHead->Prev;
130 }
131 /**
132     Delete entry from the list
133     Note: ListIsEmpty() on this list entry would not return true, since its state is undefined
134     \param [IN] ListToDelete     <RT_LIST_ENTRY>                 : list entry to be deleted
135 */
ListDeleteNode(PRT_LIST_ENTRY ListToDelete)136 void ListDeleteNode(PRT_LIST_ENTRY ListToDelete)
137 {
138 //    if (ListToDelete->Next != NULL && ListToDelete->Prev != NULL)
139     {
140         ListToDelete->Next->Prev = ListToDelete->Prev;
141         ListToDelete->Prev->Next = ListToDelete->Next;
142         ListToDelete->Next = ListToDelete->Prev = ListToDelete;
143     }
144 }
145