5 // Created by 西田 耀 on 13/01/28.
\r
6 // Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
\r
9 //UIPArray関連のうち、このソースファイルで完結する関数群
\r
23 #define CHNLIB_UIPArray_INTERNAL_PACKDATAS 7
\r
26 //Declare internal functions
\r
28 CHNLIB_UIPArray *CHNLIB_UIPArray_Internal_Allocate(void);
\r
33 typedef struct CHNLIB_UIPARRAY_INTERNAL_TAG CHNLIB_UIPArray_Internal_Tag;
\r
34 struct CHNLIB_UIPARRAY_INTERNAL_TAG {
\r
35 //UIPArrayの一つの添字に対応するデータを格納する構造体
\r
40 struct CHNLIB_UIPARRAY {
\r
41 //UnsignedIntとPointerを格納するArray構造体
\r
42 CHNLIB_StructureHeader header;
\r
44 int using_tags; //Number of using tags in this pack.
\r
45 CHNLIB_UIPArray_Internal_Tag tag[CHNLIB_UIPArray_INTERNAL_PACKDATAS];
\r
46 CHNLIB_UIPArray *next;
\r
52 CHNLIB_UIPArray *CHNLIB_UIPArray_Initialize(void)
\r
54 //ポインタを初期化する(NULLを返す)。
\r
58 int CHNLIB_UIPArray_AppendLast(CHNLIB_UIPArray **array, uint data32, void *pointer)
\r
60 //Arrayの末尾にデータを追加する。
\r
64 for(; *array != NULL && (*array)->using_tags == CHNLIB_UIPArray_INTERNAL_PACKDATAS; array = &((*array)->next)){
\r
65 index += CHNLIB_UIPArray_INTERNAL_PACKDATAS;
\r
69 *array = CHNLIB_UIPArray_Internal_Allocate();
\r
71 (*array)->tag[(*array)->using_tags].data32 = data32;
\r
72 (*array)->tag[(*array)->using_tags].pointer = pointer;
\r
73 (*array)->using_tags++;
\r
75 return index + (*array)->using_tags - 1;
\r
78 int CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(CHNLIB_UIPArray **array, uint data32, void *pointer, int (*IsDuplicated)(const void *listtag, const void *newtag))
\r
80 //戻り値:IsAdded(True/False)
\r
81 //int (*IsDuplicated)(void *listtag, void *newtag)は、重複を確認する関数へのポインタ。
\r
82 //listtagにarrayのすべてのpointerを与え、すべてがFalseだった場合追加してFalseを返す。
\r
83 //Trueが返った時点で、追加をせずTrueを返す。
\r
86 i_max = CHNLIB_UIPArray_GetNumberOfDatas(*array);
\r
87 for(i = 0; i < i_max; i++){
\r
88 if(IsDuplicated(CHNLIB_UIPArray_GetPointerByIndex(*array, i), pointer)){
\r
93 CHNLIB_UIPArray_AppendLast(array, data32, pointer);
\r
98 int CHNLIB_UIPArray_RemoveByIndex(CHNLIB_UIPArray **array, int index)
\r
100 //戻り値:削除が成功したか(0:成功,-1:指定された添字の要素は存在しない)
\r
101 //indexが指し示す要素を削除し、後続の要素は前へつめる。
\r
102 //削除された要素に格納されていたデータに関しては関知しない。
\r
105 for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){
\r
106 if(*array == NULL){
\r
109 array = &(*array)->next;
\r
111 if(*array == NULL){
\r
114 if(index >= (*array)->using_tags){
\r
117 for(i = index; i < (*array)->using_tags - 1; i++){
\r
118 (*array)->tag[i] = (*array)->tag[i + 1];
\r
121 if((*array)->next != NULL){
\r
122 if((*array)->using_tags != CHNLIB_UIPArray_INTERNAL_PACKDATAS || (*array)->next->using_tags == 0){
\r
123 //タグ数とリンクの関係があわない。以下の状態になっている。
\r
124 //次のパックがあるのに、間のパックが使い切られていない。
\r
125 //次のパックがあるのに、次のパックに一つもデータがない。
\r
126 CHNLIB_ReportError("Internal data error.", CHNLIB_DEBUG_ARGUMENTS);
\r
128 (*array)->tag[CHNLIB_UIPArray_INTERNAL_PACKDATAS - 1] = (*array)->next->tag[0];
\r
129 array = &(*array)->next;
\r
130 for(i = 0; i < (*array)->using_tags - 1; i++){
\r
131 (*array)->tag[i] = (*array)->tag[i + 1];
\r
134 (*array)->using_tags--;
\r
135 if((*array)->using_tags == 0){
\r
136 //もうこのパックにはデータが存在しないので、パックを削除。
\r
137 CHNLIB_System_FreeMemory(*array, CHNLIB_DEBUG_ARGUMENTS);
\r
146 void CHNLIB_UIPArray_FreeOnlyArray(CHNLIB_UIPArray **array)
\r
148 //ArrayそのものをFreeする。
\r
149 //Pointerの参照先については関知しない。
\r
150 CHNLIB_UIPArray *now, *next;
\r
155 for(; now != NULL; ){
\r
158 CHNLIB_System_FreeMemory(now, CHNLIB_DEBUG_ARGUMENTS);
\r
164 void CHNLIB_UIPArray_FreeOnlyAllPointer(CHNLIB_UIPArray *array)
\r
166 //Pointerの参照先をすべてFree.
\r
170 for(; array != NULL; array = array->next){
\r
171 for(i = 0; i < array->using_tags; i++){
\r
172 if(array->tag[i].pointer != NULL){
\r
173 //free(array->tag[i].pointer);
\r
174 CHNLIB_System_FreeMemory(array->tag[i].pointer, CHNLIB_DEBUG_ARGUMENTS);
\r
175 array->tag[i].pointer = NULL;
\r
182 void CHNLIB_UIPArray_FreeOnlySelectedPointer(CHNLIB_UIPArray *array)
\r
184 //Pointerの参照先で、data32==FalseのものをFree.
\r
188 for(; array != NULL; array = array->next){
\r
189 for(i = 0; i < array->using_tags; i++){
\r
190 if(array->tag[i].pointer != NULL && !array->tag[i].data32){
\r
191 //free(array->tag[i].pointer);
\r
192 CHNLIB_System_FreeMemory(array->tag[i].pointer, CHNLIB_DEBUG_ARGUMENTS);
\r
193 array->tag[i].pointer = NULL;
\r
200 void CHNLIB_UIPArray_FreeAll(CHNLIB_UIPArray **array)
\r
202 //Array及びすべてのPointerをFree.
\r
203 CHNLIB_UIPArray_FreeOnlyAllPointer(*array);
\r
204 CHNLIB_UIPArray_FreeOnlyArray(array);
\r
208 void CHNLIB_UIPArray_FreeSelectedAll(CHNLIB_UIPArray **array)
\r
210 //Array及びdata32==TrueのPointerをFree.
\r
211 CHNLIB_UIPArray_FreeOnlySelectedPointer(*array);
\r
212 CHNLIB_UIPArray_FreeOnlyArray(array);
\r
216 int CHNLIB_UIPArray_GetNumberOfDatas(const CHNLIB_UIPArray *array)
\r
218 //Arrayで現在使用中のデータの個数を返す。
\r
223 for(; array != NULL; array = array->next){
\r
224 tags += array->using_tags;
\r
229 uint CHNLIB_UIPArray_GetData32ByIndex(const CHNLIB_UIPArray *array, int index)
\r
231 //retv:array[index]->data32
\r
232 for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){
\r
236 array = array->next;
\r
241 return array->tag[index].data32;
\r
244 uint CHNLIB_UIPArray_SetData32ByIndex(CHNLIB_UIPArray *array, int index, uint data32)
\r
246 //retv = old data32
\r
250 for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){
\r
254 array = array->next;
\r
259 olddata = array->tag[index].data32;
\r
260 array->tag[index].data32 = data32;
\r
264 void *CHNLIB_UIPArray_GetPointerByIndex(const CHNLIB_UIPArray *array, int index)
\r
266 //retv:array[index]->pointer
\r
267 for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){
\r
271 array = array->next;
\r
276 return array->tag[index].pointer;
\r
279 int CHNLIB_UIPArray_GetIndexByData32(const CHNLIB_UIPArray *array, uint data32)
\r
281 //指定されたdata32を持つ最小のIndexを返す。
\r
284 i_max = CHNLIB_UIPArray_GetNumberOfDatas(array);
\r
285 for(i = 0; i < i_max; i++){
\r
286 if(CHNLIB_UIPArray_GetData32ByIndex(array, i) == data32){
\r
290 return CHNLIB_UIPArray_INDEX_NOTFOUND;
\r
293 void *CHNLIB_UIPArray_GetPointerByData32(const CHNLIB_UIPArray *array, uint data32)
\r
295 //指定されたdata32を持つindexのデータのPointerを返す。
\r
296 return CHNLIB_UIPArray_GetPointerByIndex(array, CHNLIB_UIPArray_GetIndexByData32(array, data32));
\r
300 //Internal functions
\r
302 CHNLIB_UIPArray *CHNLIB_UIPArray_Internal_Allocate(void)
\r
305 //このソース以外から呼び出してはならない。
\r
306 CHNLIB_UIPArray *tag;
\r
308 tag = (CHNLIB_UIPArray *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_UIPArray), CHNLIB_DEBUG_ARGUMENTS);
\r
310 CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_UIPArray);
\r