1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_DetailList.cpp
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46347 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "./fnd_DetailList.h"
17 
18 namespace nn { namespace fnd { namespace detail {
19 
20 #define OBJ_TO_LINK(list,obj)   ((NNSFndLink*)(((u32)(obj))+(list)->offset))
21 
22 /*---------------------------------------------------------------------------*
23   Name:         InitList
24   Description:  Initializes list structure.
25   Arguments:    list:   Pointer to the list structure.
26                 offset: Specifies the offset in the member variable structure of the NNSFndLink type that exists in the structure to be linked in the list.
27 
28                         This is convenient when using the offsetof macro defined in stddef.h.
29 
30   Returns:      None.
31  *---------------------------------------------------------------------------
32 
33 
34 */
35 void
InitList(NNSFndList * list,u16 offset)36 InitList(NNSFndList* list, u16 offset)
37 {
38     NN_TASSERT_(list);
39 
40     list->headObject = NULL;
41     list->tailObject = NULL;
42     list->numObjects = 0;
43     list->offset     = offset;
44 }
45 
46 /*---------------------------------------------------------------------------*
47   Name:         SetFirstObject                                      [static]
48   Description:  Adds the first object to the list.
49   Arguments:    list:   Pointer to the list structure.
50                 object: Pointer to the object you want to add to the list.
51   Returns:      None.
52  *---------------------------------------------------------------------------
53 
54 
55 */
56 static void
SetFirstObject(NNSFndList * list,void * object)57 SetFirstObject(NNSFndList* list, void* object)
58 {
59     NNSFndLink* link;
60 
61     NN_TASSERT_(list  );
62     NN_TASSERT_(object);
63 
64     link = OBJ_TO_LINK(list, object);
65 
66     link->nextObject = NULL;
67     link->prevObject = NULL;
68     list->headObject = object;
69     list->tailObject = object;
70     list->numObjects++;
71 }
72 
73 /*---------------------------------------------------------------------------*
74   Name:         AppendListObject
75   Description:  Adds an object to the end of the list.
76   Arguments:    list:   Pointer to the list structure.
77                 object: Pointer to the object you want to add to the list.
78   Returns:      None.
79  *---------------------------------------------------------------------------
80 
81 
82 */
83 void
AppendListObject(NNSFndList * list,void * object)84 AppendListObject(NNSFndList* list, void* object)
85 {
86     NN_TASSERT_(list  );
87     NN_TASSERT_(object);
88 
89     if (list->headObject == NULL)
90     {
91         // When the list is empty
92         SetFirstObject(list, object);
93     }
94     else
95     {
96         NNSFndLink* link = OBJ_TO_LINK(list, object);
97 
98         link->prevObject = list->tailObject;
99         link->nextObject = NULL;
100 
101         OBJ_TO_LINK(list, list->tailObject)->nextObject = object;
102         list->tailObject = object;
103         list->numObjects++;
104     }
105 }
106 
107 /*---------------------------------------------------------------------------*
108   Name:         PrependListObject
109   Description:  Inserts object at the head of the list.
110   Arguments:    list:   Pointer to the list structure.
111                 object: Pointer to the object you want to add to the list.
112   Returns:      None.
113  *---------------------------------------------------------------------------
114 
115 
116 */
117 void
PrependListObject(NNSFndList * list,void * object)118 PrependListObject(NNSFndList* list, void* object)
119 {
120     NN_TASSERT_(list  );
121     NN_TASSERT_(object);
122 
123     if (list->headObject == NULL)
124     {
125         // When the list is empty
126         SetFirstObject(list, object);
127     }
128     else
129     {
130         NNSFndLink* link = OBJ_TO_LINK(list, object);
131 
132         link->prevObject = NULL;
133         link->nextObject = list->headObject;
134 
135         OBJ_TO_LINK(list, list->headObject)->prevObject = object;
136         list->headObject = object;
137         list->numObjects++;
138     }
139 }
140 
141 /*---------------------------------------------------------------------------*
142   Name:         InsertListObject
143   Description:  Inserts object in the specified location. Object is inserted before the object specified by "target". If no insert target is specified, ("target" is NULL) the object is added to the end of the list.
144 
145 
146 
147   Arguments:    list:   Pointer to the list structure.
148                 target: Pointer to the object at the position where you want to insert an object.
149                 object: Pointer to the object you want to add to the list.
150   Returns:      None.
151  *---------------------------------------------------------------------------
152 
153 
154 */
155 void
InsertListObject(NNSFndList * list,void * target,void * object)156 InsertListObject(NNSFndList* list, void* target, void* object)
157 {
158     NN_TASSERT_(list  );
159     NN_TASSERT_(object);
160 
161     if (target == NULL)
162     {
163         // When the target is not specified, same as AppendListObject function.
164         AppendListObject(list, object);
165     }
166     else if (target == list->headObject)
167     {
168         // When target is the head of the list, same as the PrependListObject function.
169         PrependListObject(list, object);
170     }
171     else
172     {
173         NNSFndLink* link    = OBJ_TO_LINK(list, object);
174         void*       prevObj = OBJ_TO_LINK(list, target)->prevObject;
175         NNSFndLink* prevLnk = OBJ_TO_LINK(list, prevObj);
176 
177         link->prevObject    = prevObj;
178         link->nextObject    = target;
179         prevLnk->nextObject = object;
180         OBJ_TO_LINK(list, target)->prevObject = object;
181         list->numObjects++;
182     }
183 }
184 
185 /*---------------------------------------------------------------------------*
186   Name:         RemoveListObject
187   Description:  Deletes object from the list.
188   Arguments:    list:   Pointer to the list structure.
189                 object: Pointer to the object you want to delete from the list.
190   Returns:      None.
191  *---------------------------------------------------------------------------
192 
193 
194 */
195 void
RemoveListObject(NNSFndList * list,void * object)196 RemoveListObject(NNSFndList* list, void* object)
197 {
198     NNSFndLink* link;
199 
200     NN_TASSERT_(list  );
201     NN_TASSERT_(object);
202 
203     link = OBJ_TO_LINK(list, object);
204 
205     if (link->prevObject == NULL)
206     {
207         list->headObject = link->nextObject;
208     }
209     else
210     {
211         OBJ_TO_LINK(list, link->prevObject)->nextObject = link->nextObject;
212     }
213     if (link->nextObject == NULL)
214     {
215         list->tailObject = link->prevObject;
216     }
217     else
218     {
219         OBJ_TO_LINK(list, link->nextObject)->prevObject = link->prevObject;
220     }
221     link->prevObject = NULL;
222     link->nextObject = NULL;
223     list->numObjects--;
224 }
225 
226 /*---------------------------------------------------------------------------*
227   Name:         GetNextListObject
228   Description:  Returns the object next in the list after the object specified by 'object.' When NULL is specified for "object", the object at the head of the list is returned.
229 
230 
231   Arguments:    list:   Pointer to the list structure.
232                 object: Pointer to object in list.
233   Returns:      Returns a pointer to the object next in the last after the specified object. If there is no next object, returns NULL.
234 
235  *---------------------------------------------------------------------------
236 
237 
238 */
239 void*
GetNextListObject(const NNSFndList * list,const void * object)240 GetNextListObject(const NNSFndList* list, const void* object)
241 {
242     NN_TASSERT_(list);
243 
244     if (object == NULL)
245     {
246         return list->headObject;
247     }
248     return OBJ_TO_LINK(list, object)->nextObject;
249 }
250 
251 /*---------------------------------------------------------------------------*
252   Name:         GetPrevListObject
253   Description:  Returns the object linked in front of the object specified by 'object.'
254 
255                 When NULL is specified for "object", the object linked to the tail of the list is returned.
256   Arguments:    list:   Pointer to the list structure.
257                 object: Pointer to object in list.
258   Returns:      Returns a pointer to the previous object before the specified object.
259                  If there is no object in front, returns NULL.
260  *---------------------------------------------------------------------------
261 
262 
263 */
264 void*
GetPrevListObject(const NNSFndList * list,const void * object)265 GetPrevListObject(const NNSFndList* list, const void* object)
266 {
267     NN_TASSERT_(list);
268 
269     if (object == NULL)
270     {
271         return list->tailObject;
272     }
273     return OBJ_TO_LINK(list, object)->prevObject;
274 }
275 
276 /*---------------------------------------------------------------------------*
277   Name:         GetNthListObject
278   Description:  Returns a pointer to the object linked nth on the list.
279                 Because the list is traversed in order from the head, objects deeper in the list take more time.
280 
281   Arguments:    index:  Object index.
282   Returns:      Returns pointer to object. If there is no object for the specified index, NULL is returned.
283 
284  *---------------------------------------------------------------------------
285 
286 
287 */
288 void*
GetNthListObject(const NNSFndList * list,u16 index)289 GetNthListObject(const NNSFndList* list, u16 index)
290 {
291     int         count  = 0;
292     NNSFndLink* object = NULL;
293 
294     NN_TASSERT_(list);
295 
296 //    while ((object = GetNextListObject(list, object)) != NULL)
297 //  for Horizon
298     while ((object = reinterpret_cast<NNSFndLink*>(
299                     GetNextListObject(list, object))) != NULL)
300     {
301         if (index == count)
302         {
303             return object;
304         }
305         count++;
306     }
307     return NULL;
308 }
309 
310 }}} // namespace nn::os::fnd
311 
312