OSDN Git Service

459ed8d19e091e2b4e537652002fb43a67d86906
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib02.c
1 //\r
2 //  chnlib02.c\r
3 //  AI003\r
4 //\r
5 //  Created by 西田 耀 on 13/02/09.\r
6 //  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.\r
7 //\r
8 \r
9 //複数の種類の関数に依存する関数群\r
10 \r
11 //\r
12 //Include headers\r
13 //\r
14 \r
15 #include <stdio.h>\r
16 #include "chnlib.h"\r
17 \r
18 //\r
19 //Functions\r
20 //\r
21 \r
22 int CHNLIB_String_Search_UIPArrayStringLocation(const CHNLIB_String *s, int s_start, const CHNLIB_UIPArray *list, int *location)\r
23 {\r
24     //文字列&s[s_start]に含まれている中で最も左側にある、Array内のStringタグの文字列のArrayにおける添字と、その文字列が開始する、文字列&s[s_start]中の添字を返す。\r
25     //locaton!=NULLの時、*locationに、発見された文字列の最初のバイトの&s[s_start]における添字が代入される。\r
26     //Arrayの文字列がすべて見つからなかった場合、AI_ARRAY_INDEX_NOTFOUNDを返す。そのときの*locatonには0が代入される。\r
27     int i, i_max, j, j_max;\r
28     CHNLIB_String *tag;\r
29     const char *cstr_s;\r
30     \r
31     if(s == NULL || list == NULL){\r
32         if(location != NULL){\r
33             *location = 0;\r
34         }\r
35         return CHNLIB_UIPArray_INDEX_NOTFOUND;\r
36     }\r
37     cstr_s = CHNLIB_String_GetReferencePointerOfCString(s);\r
38     i_max = CHNLIB_CString_GetLength(cstr_s);\r
39     \r
40     j_max = CHNLIB_UIPArray_GetNumberOfDatas(list);\r
41     for(i = s_start; i < i_max; i++){\r
42         for(j = 0; j < j_max; j++){\r
43             tag = (CHNLIB_String *)CHNLIB_UIPArray_GetPointerByIndex(list, j);\r
44             if(CHNLIB_StructureHeader_GetTypeID(tag) == CHNLIB_STRUCT_ID_String){\r
45                 if(CHNLIB_CString_CompareString(&cstr_s[i], CHNLIB_String_GetReferencePointerOfCString(tag))){\r
46                     if(location != NULL){\r
47                         *location = i - s_start;\r
48                     }\r
49                     return j;\r
50                 }\r
51             }\r
52         }\r
53     }\r
54     \r
55     if(location != NULL){\r
56         *location = 0;\r
57     }\r
58     return CHNLIB_UIPArray_INDEX_NOTFOUND;\r
59 }\r
60 \r
61 int CHNLIB_UIPArray_GetSeparatedStringByUIPArray(CHNLIB_UIPArray **separated, const CHNLIB_UIPArray *list, const CHNLIB_String *s)\r
62 {\r
63     //listにある文字列でsを分割し、その結果をseparatedに追加する。\r
64     //listに存在する文字列は新しくメモリを確保せず、リスト中のStringタグへのポインタをseparatedに記録する。\r
65     //従ってseparatedを解放する際は、listのdata32をすべてTrueにした上で、CHNLIB_UIPArray_FreeSelectedAllを利用するべきである。\r
66     //listにない文字列はdata32==False(0)\r
67     //listにある文字列はdata32==tag->data32\r
68     int index, end, end_end, location;\r
69     \r
70     if(s == NULL){\r
71         return 1;\r
72     }\r
73    \r
74     end = 0;\r
75     end_end = CHNLIB_String_GetLength(s);\r
76     for(;;){\r
77         index = CHNLIB_String_Search_UIPArrayStringLocation(s, end, list, &location);\r
78         if(index == CHNLIB_UIPArray_INDEX_NOTFOUND){\r
79             //もうリストの文字列はない\r
80             if(end != end_end){\r
81                 //でもまだ文字列は残っている\r
82                 CHNLIB_UIPArray_AppendLast(separated, False, CHNLIB_String_ExtractByLength(s, end, CHNLIB_MAX_STRING_LENGTH));\r
83             }\r
84             break;\r
85         }\r
86         //リストの文字列が見つかった\r
87         if(location != 0){\r
88             //リストの文字列の前に、リストにない文字列がある\r
89             CHNLIB_UIPArray_AppendLast(separated, False, CHNLIB_String_ExtractByLength(s, end, location));\r
90             end += location;\r
91         }\r
92         CHNLIB_UIPArray_AppendLast(separated, CHNLIB_UIPArray_GetData32ByIndex(list, index), CHNLIB_UIPArray_GetPointerByIndex(list, index));\r
93         end += CHNLIB_String_GetLength(CHNLIB_UIPArray_GetPointerByIndex(list, index));\r
94     }\r
95     return 0;\r
96 }\r
97 \r
98 int CHNLIB_UIPArray_GetSeparatedUTF8Character(CHNLIB_UIPArray **separated, const CHNLIB_String *s){\r
99     //文字列sを、UTF-8の一文字ごとに分割し、その文字のUnicodeをdata32、その一文字に該当するStringをpointerに格納し、separatedに追加する形で返す。\r
100     //不完全なUTF-8文字列は無視される。\r
101     const char *refstr;\r
102     int i, i_max, type;\r
103     int phase, start;\r
104     uint unicode;\r
105     \r
106     if(separated == NULL || CHNLIB_StructureHeader_GetTypeID(s) != CHNLIB_STRUCT_ID_String){\r
107         return 1;\r
108     }\r
109     \r
110     refstr = CHNLIB_String_GetReferencePointerOfCString(s);\r
111     i_max = CHNLIB_String_GetLength(s);\r
112     \r
113     phase = 0;\r
114     unicode = 0;\r
115     for(i = 0; i < i_max; i++){\r
116         type = CHNLIB_UTF8_GetCharacterType(refstr[i]);\r
117         switch (type) {\r
118             case 1:\r
119                 CHNLIB_UIPArray_AppendLast(separated, refstr[i], CHNLIB_String_ExtractByLength(s, i, 1));\r
120                 phase = 0;\r
121                 unicode = 0;\r
122                 break;\r
123                 \r
124             case 0:\r
125                 if(phase > 0){\r
126                     unicode <<= 6;\r
127                     unicode |= (refstr[i] & 0x3f);\r
128                     phase--;\r
129                     if(phase == 0){\r
130                         //一文字完成\r
131                         CHNLIB_UIPArray_AppendLast(separated, unicode, CHNLIB_String_ExtractByLength(s, start, i - start + 1));\r
132                     }\r
133                 }\r
134                 break;\r
135                 \r
136             case 2:\r
137             case 3:\r
138             case 4:\r
139                 start = i;\r
140                 unicode = (refstr[i] << (type + 1)) >> (type + 1);\r
141                 phase = type - 1;\r
142                 break;\r
143         }\r
144     }\r
145     \r
146     return 0;\r
147 }\r
148 \r
149 \r
150 CHNLIB_String *CHNLIB_ReadLine(FILE *fp)\r
151 {\r
152     char s[CHNLIB_MAX_STRING_LENGTH];\r
153     \r
154     if(fgets(s, sizeof(s), fp) == NULL){\r
155         return NULL;\r
156     }\r
157     \r
158     CHNLIB_CString_DeleteLastCRLF(s);\r
159     \r
160     return CHNLIB_String_Initialize(s);\r
161 }\r
162 \r
163 \r