OSDN Git Service

debug系関数の引数の一部マクロ化。
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib00.c
1 //\r
2 //  chnlib00.c\r
3 //  AI003\r
4 //\r
5 //  Created by 西田 耀 on 13/01/28.\r
6 //  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.\r
7 //\r
8 \r
9 //UIPArray関連のうち、このソースファイルで完結する関数群\r
10 \r
11 //\r
12 //Include headers\r
13 //\r
14 \r
15 #include <stdio.h>\r
16 #include <stdlib.h>\r
17 #include <string.h>\r
18 #include "chnlib.h"\r
19 \r
20 //\r
21 //Define values\r
22 //\r
23 #define CHNLIB_UIPArray_INTERNAL_PACKDATAS   7\r
24 \r
25 //\r
26 //Declare internal functions\r
27 //\r
28 CHNLIB_UIPArray *CHNLIB_UIPArray_Internal_Allocate(void);\r
29 \r
30 //\r
31 //Define types\r
32 //\r
33 typedef struct CHNLIB_UIPARRAY_INTERNAL_TAG CHNLIB_UIPArray_Internal_Tag;\r
34 struct CHNLIB_UIPARRAY_INTERNAL_TAG {\r
35     //UIPArrayの一つの添字に対応するデータを格納する構造体\r
36     uint data32;\r
37     void *pointer;\r
38 };\r
39 \r
40 struct CHNLIB_UIPARRAY {\r
41     //UnsignedIntとPointerを格納するArray構造体\r
42     CHNLIB_StructureHeader header;\r
43     \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
47 };\r
48 \r
49 //\r
50 //Functions\r
51 //\r
52 CHNLIB_UIPArray *CHNLIB_UIPArray_Initialize(void)\r
53 {\r
54     //ポインタを初期化する(NULLを返す)。\r
55     return NULL;\r
56 }\r
57 \r
58 int CHNLIB_UIPArray_AppendLast(CHNLIB_UIPArray **array, uint data32, void *pointer)\r
59 {\r
60     //Arrayの末尾にデータを追加する。\r
61     int index;\r
62     \r
63     index = 0;\r
64     for(; *array != NULL && (*array)->using_tags == CHNLIB_UIPArray_INTERNAL_PACKDATAS; array = &((*array)->next)){\r
65         index += CHNLIB_UIPArray_INTERNAL_PACKDATAS;\r
66     }\r
67     \r
68     if(*array == NULL){\r
69         *array = CHNLIB_UIPArray_Internal_Allocate();\r
70     }\r
71     (*array)->tag[(*array)->using_tags].data32 = data32;\r
72     (*array)->tag[(*array)->using_tags].pointer = pointer;\r
73     (*array)->using_tags++;\r
74     \r
75     return index + (*array)->using_tags - 1;\r
76 }\r
77 \r
78 int CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(CHNLIB_UIPArray **array, uint data32, void *pointer, int (*IsDuplicated)(const void *listtag, const void *newtag))\r
79 {\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
84     int i, i_max;\r
85     \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
89             return False;\r
90         }\r
91     }\r
92     \r
93     CHNLIB_UIPArray_AppendLast(array, data32, pointer);\r
94     \r
95     return True;\r
96 }\r
97 \r
98 void CHNLIB_UIPArray_FreeOnlyArray(CHNLIB_UIPArray **array)\r
99 {\r
100     //ArrayそのものをFreeする。\r
101     //Pointerの参照先については関知しない。\r
102     CHNLIB_UIPArray *now, *next;\r
103     \r
104     now = *array;\r
105     *array = NULL;\r
106     \r
107     for(; now != NULL; ){\r
108         next = now->next;\r
109         free(now);\r
110         now = next;\r
111     }\r
112     return;\r
113 }\r
114 \r
115 void CHNLIB_UIPArray_FreeOnlyAllPointer(CHNLIB_UIPArray *array)\r
116 {\r
117     //Pointerの参照先をすべてFree.\r
118     //Array自体はFreeしない。\r
119     int i;\r
120     \r
121     for(; array != NULL; array = array->next){\r
122         for(i = 0; i < array->using_tags; i++){\r
123             if(array->tag[i].pointer != NULL){\r
124                 free(array->tag[i].pointer);\r
125                 array->tag[i].pointer = NULL;\r
126             }\r
127         }\r
128     }\r
129     return;\r
130 }\r
131 \r
132 void CHNLIB_UIPArray_FreeOnlySelectedPointer(CHNLIB_UIPArray *array)\r
133 {\r
134     //Pointerの参照先で、data32==FalseのものをFree.\r
135     //Array自体はFreeしない。\r
136     int i;\r
137     \r
138     for(; array != NULL; array = array->next){\r
139         for(i = 0; i < array->using_tags; i++){\r
140             if(array->tag[i].pointer != NULL && !array->tag[i].data32){\r
141                 free(array->tag[i].pointer);\r
142                 array->tag[i].pointer = NULL;\r
143             }\r
144         }\r
145     }\r
146     return;\r
147 }\r
148 \r
149 void CHNLIB_UIPArray_FreeAll(CHNLIB_UIPArray **array)\r
150 {\r
151     //Array及びすべてのPointerをFree.\r
152     CHNLIB_UIPArray_FreeOnlyAllPointer(*array);\r
153     CHNLIB_UIPArray_FreeOnlyArray(array);\r
154     return;\r
155 }\r
156 \r
157 void CHNLIB_UIPArray_FreeSelectedAll(CHNLIB_UIPArray **array)\r
158 {\r
159     //Array及びdata32==TrueのPointerをFree.\r
160     CHNLIB_UIPArray_FreeOnlySelectedPointer(*array);\r
161     CHNLIB_UIPArray_FreeOnlyArray(array);\r
162     return;\r
163 }\r
164 \r
165 int CHNLIB_UIPArray_GetNumberOfDatas(const CHNLIB_UIPArray *array)\r
166 {\r
167     //Arrayで現在使用中のデータの個数を返す。\r
168     int tags;\r
169     \r
170     tags = 0;\r
171     \r
172     for(; array != NULL; array = array->next){\r
173         tags += array->using_tags;\r
174     }\r
175     return tags;\r
176 }\r
177 \r
178 uint CHNLIB_UIPArray_GetData32ByIndex(const CHNLIB_UIPArray *array, int index)\r
179 {\r
180     //retv:array[index]->data32\r
181     for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){\r
182         if(array == NULL){\r
183             return 0;\r
184         }\r
185         array = array->next;\r
186     }\r
187     if(array == NULL){\r
188         return 0;\r
189     }\r
190     return array->tag[index].data32;\r
191 }\r
192 \r
193 uint CHNLIB_UIPArray_SetData32ByIndex(CHNLIB_UIPArray *array, int index, uint data32)\r
194 {\r
195     //retv = old data32\r
196     \r
197     uint olddata;\r
198     \r
199     for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){\r
200         if(array == NULL){\r
201             return 0;\r
202         }\r
203         array = array->next;\r
204     }\r
205     if(array == NULL){\r
206         return 0;\r
207     }\r
208     olddata = array->tag[index].data32;\r
209     array->tag[index].data32 = data32;\r
210     return olddata;\r
211 }\r
212 \r
213 void *CHNLIB_UIPArray_GetPointerByIndex(const CHNLIB_UIPArray *array, int index)\r
214 {\r
215     //retv:array[index]->pointer\r
216     for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){\r
217         if(array == NULL){\r
218             return NULL;\r
219         }\r
220         array = array->next;\r
221     }\r
222     if(array == NULL){\r
223         return NULL;\r
224     }\r
225     return array->tag[index].pointer;\r
226 }\r
227 \r
228 int CHNLIB_UIPArray_GetIndexByData32(const CHNLIB_UIPArray *array, uint data32)\r
229 {\r
230     //指定されたdata32を持つ最小のIndexを返す。\r
231     int i, i_max;\r
232     \r
233     i_max = CHNLIB_UIPArray_GetNumberOfDatas(array);\r
234     for(i = 0; i < i_max; i++){\r
235         if(CHNLIB_UIPArray_GetData32ByIndex(array, i) == data32){\r
236             return i;\r
237         }\r
238     }\r
239     return CHNLIB_UIPArray_INDEX_NOTFOUND;\r
240 }\r
241 \r
242 void *CHNLIB_UIPArray_GetPointerByData32(const CHNLIB_UIPArray *array, uint data32)\r
243 {\r
244     //指定されたdata32を持つindexのデータのPointerを返す。\r
245     return CHNLIB_UIPArray_GetPointerByIndex(array, CHNLIB_UIPArray_GetIndexByData32(array, data32));\r
246 }\r
247 \r
248 //\r
249 //Internal functions\r
250 //\r
251 CHNLIB_UIPArray *CHNLIB_UIPArray_Internal_Allocate(void)\r
252 {\r
253     //Arrayの実体を確保する。\r
254     //このソース以外から呼び出してはならない。\r
255     CHNLIB_UIPArray *tag;\r
256     \r
257     tag = (CHNLIB_UIPArray *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_UIPArray), CHNLIB_DEBUG_ARGUMENTS);\r
258     \r
259     CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_UIPArray);\r
260     \r
261     return tag;\r
262 \r
263 }\r
264 \r