OSDN Git Service

76df8849ff9e1949f342ec19f87bde84586b9b14
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib01.c
1 //\r
2 //  chnlib01.c\r
3 //  AI003\r
4 //\r
5 //  Created by 西田 耀 on 13/02/03.\r
6 //  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.\r
7 //\r
8 \r
9 //String関連のうち、このソースファイルで完結する関数群\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 \r
24 //\r
25 //Declare internal functions\r
26 //\r
27 \r
28 CHNLIB_String *CHNLIB_String_Internal_Allocate(void);\r
29 \r
30 //\r
31 //Define types\r
32 //\r
33 \r
34 struct CHNLIB_STRING {\r
35     //文字列を保持する\r
36     CHNLIB_StructureHeader header;\r
37     char *str;\r
38 };\r
39 \r
40 //\r
41 //Functions(CHNLIB_String)\r
42 //\r
43 \r
44 CHNLIB_String *CHNLIB_String_Initialize(const char str[])\r
45 {\r
46     //指定された引数strと等価なStringを確保し返す。\r
47     //str==NULLの時は、NULLポインタへの参照を持つStringを返す。\r
48     CHNLIB_String *strtag;\r
49     \r
50     strtag = CHNLIB_String_Internal_Allocate();\r
51     \r
52     if(str != NULL){\r
53         CHNLIB_String_SetStringFromCString(strtag, str);\r
54     }\r
55     return strtag;\r
56 }\r
57 \r
58 void CHNLIB_String_Free(CHNLIB_String *strtag)\r
59 {\r
60     //strtagを解放する。\r
61     \r
62     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
63         return;\r
64     }\r
65     \r
66     if(strtag->str != NULL){\r
67         CHNLIB_System_FreeMemory(strtag->str, CHNLIB_DEBUG_ARGUMENTS);\r
68     }\r
69     strtag->header.typeid = CHNLIB_STRUCT_ID_Null;\r
70     strtag->header.signature = 0;\r
71     CHNLIB_System_FreeMemory(strtag, CHNLIB_DEBUG_ARGUMENTS);\r
72     \r
73     return;\r
74 }\r
75 \r
76 int CHNLIB_String_SetStringFromCString(CHNLIB_String *strtag, const char s[])\r
77 {\r
78     //strtagにsと等価な文字列を代入する。\r
79     //strtag==Invalid || s==NULLのときは何もしない。\r
80     int i, size;\r
81     \r
82     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
83         return 0;\r
84     }\r
85     \r
86     if(s == NULL){\r
87         return 0;\r
88     }\r
89     \r
90     size = CHNLIB_CString_GetLength(s) + 1;\r
91     if(strtag->str != NULL){\r
92         CHNLIB_System_FreeMemory(strtag->str, CHNLIB_DEBUG_ARGUMENTS);\r
93     }\r
94     strtag->str = CHNLIB_System_AllocateMemory_Strict(size, CHNLIB_DEBUG_ARGUMENTS);\r
95     for(i = 0; i < size - 1; i++){\r
96         strtag->str[i] = s[i];\r
97     }\r
98     strtag->str[i] = '\0';\r
99     return size;\r
100 }\r
101 \r
102 int CHNLIB_String_Print(CHNLIB_String *strtag)\r
103 {\r
104     //strtagが格納している文字列を標準出力に出力する。\r
105     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
106         return 0;\r
107     }\r
108     if(strtag->str == NULL){\r
109         return 0;\r
110     }\r
111     \r
112     return fputs(strtag->str, stdout);\r
113 }\r
114 \r
115 const char *CHNLIB_String_GetReferencePointerOfCString(const CHNLIB_String *strtag)\r
116 {\r
117     //strtagが格納している文字列へのポインタを返す。\r
118     //strtag==Invalidの場合、NULLを返す。\r
119     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
120         return NULL;\r
121     }\r
122     \r
123     return (const char *)strtag->str;\r
124 }\r
125 \r
126 CHNLIB_String *CHNLIB_String_ExtractByLength(const CHNLIB_String *strtag, int start, int len)\r
127 {\r
128     //strtagが格納している文字列sについて、\r
129     //s[start]からs[start + len - 1]の文字を含む文字列と等価なStringを確保し返す。\r
130     //lenに満たずにsが終端文字を迎えた場合は、sの終端文字直前までの文字列がコピーされる。\r
131     //(len < 0)のときは、NULLを返す。また、結果として(len < 0)となった時も同様にNULLを返す。\r
132     char *retstr;\r
133     CHNLIB_String *retstrtag;\r
134     \r
135     retstr = CHNLIB_CString_ExtractByLength(strtag->str, start, len);\r
136     \r
137     if(retstr == NULL){\r
138         return NULL;\r
139     }\r
140     \r
141     retstrtag = CHNLIB_String_Initialize(NULL);\r
142     retstrtag->str = retstr;\r
143     \r
144     return retstrtag;\r
145 }\r
146 \r
147 int CHNLIB_String_GetLength(const CHNLIB_String *strtag)\r
148 {\r
149     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
150         return 0;\r
151     }\r
152     \r
153     return CHNLIB_CString_GetLength(strtag->str);\r
154 }\r
155 \r
156 void CHNLIB_String_DeleteLastCRLF(CHNLIB_String *strtag)\r
157 {\r
158     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
159         return;\r
160     }\r
161     \r
162     CHNLIB_CString_DeleteLastCRLF(strtag->str);\r
163     \r
164     return;\r
165 }\r
166 \r
167 int CHNLIB_String_CompareStringWithCString(const CHNLIB_String *s, const char search[])\r
168 {\r
169     return CHNLIB_CString_CompareString(CHNLIB_String_GetReferencePointerOfCString(s), search);\r
170 }\r
171 \r
172 int CHNLIB_String_CompareString_Strict(const CHNLIB_String *s, const CHNLIB_String *search)\r
173 {\r
174     return CHNLIB_CString_CompareString_Strict(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));\r
175 }\r
176 \r
177 uint CHNLIB_String_GetCountOfContain(const CHNLIB_String *s, const CHNLIB_String *search)\r
178 {\r
179     return CHNLIB_CString_GetCountOfContain(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));\r
180 }\r
181 \r
182 //\r
183 //Functions(CString(char[]))\r
184 //\r
185 \r
186 int CHNLIB_CString_GetLength(const char s[])\r
187 {\r
188     //終端文字を含めない時の、文字列のバイト数を返す。\r
189     int i;\r
190     \r
191     if(s == NULL){\r
192         return 0;\r
193     }\r
194     \r
195     for(i = 0; s[i] != 0x00; i++){\r
196         \r
197     }\r
198     \r
199     return i;\r
200 }\r
201 \r
202 void CHNLIB_CString_DeleteLastCRLF(char s[])\r
203 {\r
204     //末尾のLF, CR/LFを\0に置換する\r
205     int i, crlf;\r
206     \r
207     if(s == NULL){\r
208         return;\r
209     }\r
210     \r
211     crlf = -1;\r
212     for(i = 0; s[i] != '\0'; i++){\r
213         if(s[i] == '\n'){\r
214             if(crlf == -1 || crlf + 1 != i){\r
215                 crlf = i;\r
216             }\r
217         }\r
218         if(s[i] == '\r'){\r
219             if(crlf == -1 || crlf + 1 != i){\r
220                 crlf = i;\r
221             }\r
222         }\r
223     }\r
224     if(crlf != -1){\r
225         for(i = crlf; s[i] != '\0'; i++){\r
226             s[i] = '\0';\r
227         }\r
228     }\r
229     return;\r
230 }\r
231 \r
232 char *CHNLIB_CString_ExtractByLength(const char s[], int start, int len)\r
233 {\r
234     //s[start]からs[start + len - 1]の文字を含む文字列を、新たにメモリを確保して書き込み、その先頭アドレスを返す。\r
235     //lenに満たずにsが終端文字を迎えた場合は、sの終端文字直前までの文字列がコピーされる。\r
236     //(len < 0)のときは、NULLを返す。また、結果として(len < 0)となった時も同様にNULLを返す。\r
237     char *str;\r
238     int i;\r
239     int utf8type;\r
240     \r
241     if(s == NULL){\r
242         CHNLIB_ReportError("Null s[]\n", CHNLIB_DEBUG_ARGUMENTS);\r
243         return NULL;\r
244     }\r
245     \r
246     i = CHNLIB_CString_GetLength(s) + 1;\r
247     \r
248     if(i > (len + 1)){\r
249         i = len + 1;\r
250     }\r
251     \r
252     if(len == 0){\r
253         return NULL;\r
254     }\r
255     \r
256     str = CHNLIB_System_AllocateMemory_Strict(i, CHNLIB_DEBUG_ARGUMENTS);\r
257 \r
258     for(i = 0; s[i + start] != '\0'; i++){\r
259         if(len <= 0){\r
260             break;\r
261         }\r
262         //**UTF-8\r
263         utf8type = CHNLIB_UTF8_GetCharacterType(s[i + start]);\r
264         if(len < utf8type){\r
265             break;\r
266         }\r
267         //****\r
268         len--;\r
269         str[i] = s[i + start];\r
270     }\r
271     str[i] = '\0';\r
272     \r
273     return str;\r
274 }\r
275 \r
276 int CHNLIB_CString_CompareString(const char s[], const char search[])\r
277 {\r
278     //s[]の先頭からsearch[]と比較し、searchの終端まで一致したらTrue, 一致しなかったらFalseを返す。\r
279     //終端文字'\0'はカウントしない。\r
280     //search[]に含まれる文字(終端文字除く)がすべて入っていれば一致とみなす。\r
281     int i;\r
282     \r
283     if(s == NULL || search == NULL){\r
284         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
285         return False;\r
286     }\r
287     \r
288     for(i = 0; search[i] != '\0'; i++){\r
289         if(s[i] != search[i]){\r
290             return False;\r
291         }\r
292     }\r
293     return True;\r
294 }\r
295 \r
296 int CHNLIB_CString_CompareString_Strict(const char s[], const char search[])\r
297 {\r
298     //二つの文字列が終端文字までを含めて完全に一致するかどうか調べる。一致していればTrueを返す。\r
299     //StrictよりExactの方が適する?<関数名\r
300     int i;\r
301     \r
302     if(s == NULL || search == NULL){\r
303         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
304         return False;\r
305     }\r
306     \r
307     for(i = 0; search[i] != '\0'; i++){\r
308         if(s[i] != search[i]){\r
309             return False;\r
310         }\r
311     }\r
312     if(s[i] != '\0'){\r
313         return False;\r
314     }\r
315     return True;\r
316 }\r
317 \r
318 int CHNLIB_CString_CompareString_LeftHand(const char s[], const char search[])\r
319 {\r
320     //二つの文字列がどの程度一致するか調べる。前方一致。\r
321     //戻り値は、終端文字を除く、同一だったバイト数。\r
322     int i;\r
323     \r
324     if(s == NULL || search == NULL){\r
325         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
326         return 0;\r
327     }\r
328     \r
329     for(i = 0; search[i] != '\0'; i++){\r
330         if(s[i] != search[i]){\r
331             break;\r
332         }\r
333     }\r
334 \r
335     return i;\r
336 }\r
337 \r
338 uint CHNLIB_CString_GetCountOfContain(const char s[], const char search[])\r
339 {\r
340     //[Not implemented]\r
341     uint count;\r
342     int i;\r
343     \r
344     if(s == NULL || search == NULL){\r
345         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
346         return 0;\r
347     }\r
348     \r
349     count = 0;\r
350     for(i = 0; s[i] != '\0'; i++){\r
351         if(CHNLIB_CString_CompareString(&s[i], search)){\r
352             count++;\r
353         }\r
354     }\r
355     return count;\r
356 }\r
357     \r
358 //\r
359 //Internal functions\r
360 //\r
361 \r
362 CHNLIB_String *CHNLIB_String_Internal_Allocate(void)\r
363 {\r
364     CHNLIB_String *tag;\r
365     \r
366     tag = (CHNLIB_String *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_String), CHNLIB_DEBUG_ARGUMENTS);\r
367     \r
368     CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_String);\r
369     \r
370     return tag;\r
371 }