1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_DetailList.cpp
4 
5   Copyright (C)2009 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: 12449 $
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 
25   Description:  リスト構造体を初期化します。
26 
27   Arguments:    list:   リスト構造体へのポインタ。
28                 offset: リストに繋げたい構造体の中に存在する、NNSFndLink型の
29                         メンバ変数の構造体内でのオフセットを指定します。
30                         stddef.hで定義されているoffsetofマクロを使用すると、
31                         便利です。
32 
33   Returns:      なし。
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 
49   Description:  最初のオブジェクトをリストに加えます。
50 
51   Arguments:    list:   リスト構造体へのポインタ。
52                 object: リストに繋げたいオブジェクトへのポインタ。
53 
54   Returns:      なし。
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 
76   Description:  オブジェクトをリストの最後に追加します。
77 
78   Arguments:    list:   リスト構造体へのポインタ。
79                 object: リストに繋げたいオブジェクトへのポインタ。
80 
81   Returns:      なし。
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         // リストが空の時。
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 
110   Description:  オブジェクトをリストの先頭に挿入します。
111 
112   Arguments:    list:   リスト構造体へのポインタ。
113                 object: リストに繋げたいオブジェクトへのポインタ。
114 
115   Returns:      なし。
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         // リストが空の時。
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 
144   Description:  オブジェクトを指定された位置に挿入します。オブジェクトは、
145                 targetで指定されたオブジェクトの前に挿入されます。挿入先が指
146                 定されていない場合(targetがNULLの場合)、オブジェクトはリス
147                 トの最後に追加されます。
148 
149   Arguments:    list:   リスト構造体へのポインタ。
150                 target: 挿入したい位置にあるオブジェクトへのポインタ。
151                 object: リストに繋げたいオブジェクトへのポインタ。
152 
153   Returns:      なし。
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         // targetが指定されていない場合は、AppendListObject()と同じ。
164         AppendListObject(list, object);
165     }
166     else if (target == list->headObject)
167     {
168         // targetがリストの先頭である場合はPrependListObject()と同じ。
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 
188   Description:  オブジェクトをリストから削除します。
189 
190   Arguments:    list:   リスト構造体へのポインタ。
191                 object: リストから削除したいオブジェクトへのポインタ。
192 
193   Returns:      なし。
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 
229   Description:  objectで指定されたオブジェクトの次に繋がれているオブジェクト
230                 を返します。objectにNULLが指定されていた場合には、リストの先
231                 頭に繋がれているオブジェクトを返します。
232 
233   Arguments:    list:   リスト構造体へのポインタ。
234                 object: リスト中のオブジェクトへのポインタ。
235 
236   Returns:      指定されたオブジェクトの次のオブジェクトへのポインタを返しま
237                 す。もし、次のオブジェクトが無ければ、NULLを返します。
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 
254   Description:  objectで指定されたオブジェクトの前に繋がれているオブジェクト
255                 を返します。objectにNULLが指定されていた場合には、リストの後
256                 尾に繋がれているオブジェクトを返します。
257 
258   Arguments:    list:   リスト構造体へのポインタ。
259                 object: リスト中のオブジェクトへのポインタ。
260 
261   Returns:      指定されたオブジェクトの前のオブジェクトへのポインタを返しま
262                 す。もし、前のオブジェクトが無ければ、NULLを返します。
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 
279   Description:  リストのN番目に繋がれているオブジェクトへのポインタを返しま
280                 す。先頭から順番にリストをたどる為、リストの後部に繋がれてい
281                 オブジェクト程、時間がかかります。
282 
283   Arguments:    index:  オブジェクトのインデックス。
284 
285   Returns:      オブジェクトへのポインタを返します。もし、指定されたインデッ
286                 クスのオブジェクトが無かった場合には、NULLが返ります。
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