OSDN Git Service

chnlib:CHNLIB_UUID(UUIDv4), メルセンヌ・ツイスターを利用した乱数生成器CHNLIB_RandomGeneratorMTを追加。
[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_GetByteLength(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     //referenceCountは、list中の文字列は2以上になり、listにない文字列は1となる。\r
67     //従って、separatedをreleaseすれば、安全に解放できる。\r
68     //listにない文字列はdata32==False(0)\r
69     //listにある文字列はdata32==tag->data32\r
70     int index, end, end_end, location;\r
71     \r
72     if(s == NULL){\r
73         return 1;\r
74     }\r
75    \r
76     end = 0;\r
77     end_end = CHNLIB_String_GetLength(s);\r
78     for(;;){\r
79         index = CHNLIB_String_Search_UIPArrayStringLocation(s, end, list, &location);\r
80         if(index == CHNLIB_UIPArray_INDEX_NOTFOUND){\r
81             //もうリストの文字列はない\r
82             if(end != end_end){\r
83                 //でもまだ文字列は残っている\r
84                 CHNLIB_UIPArray_AppendLast(separated, False, autorelease(CHNLIB_String_ExtractByLength(s, end, CHNLIB_MAX_STRING_LENGTH)));\r
85             }\r
86             break;\r
87         }\r
88         //リストの文字列が見つかった\r
89         if(location != 0){\r
90             //リストの文字列の前に、リストにない文字列がある\r
91             CHNLIB_UIPArray_AppendLast(separated, False, autorelease(CHNLIB_String_ExtractByLength(s, end, location)));\r
92             end += location;\r
93         }\r
94         CHNLIB_UIPArray_AppendLast(separated, CHNLIB_UIPArray_GetData32ByIndex(list, index), CHNLIB_UIPArray_GetPointerByIndex(list, index));\r
95         end += CHNLIB_String_GetLength(CHNLIB_UIPArray_GetPointerByIndex(list, index));\r
96     }\r
97     return 0;\r
98 }\r
99 \r
100 int CHNLIB_UIPArray_GetSeparatedUTF8Character(CHNLIB_UIPArray **separated, const CHNLIB_String *s)\r
101 {\r
102     //[UTF-8]\r
103     //文字列sを、UTF-8の一文字ごとに分割し、その文字のUnicodeをdata32、その一文字に該当するStringをpointerに格納し、separatedに追加する形で返す。\r
104     //不完全なUTF-8文字列は無視される。\r
105     const char *p, *q, *p_base;\r
106     uint u;\r
107     \r
108     if(separated == NULL || CHNLIB_StructureHeader_GetTypeID(s) != CHNLIB_STRUCT_ID_String){\r
109         return 1;\r
110     }\r
111     \r
112     p_base = CHNLIB_String_GetReferencePointerOfCString(s);;\r
113     p = p_base;\r
114     \r
115     for(;;){\r
116         u = CHNLIB_UTF8_GetNextUnicodeOfCharacter(p, &q);\r
117         if(u == 0){\r
118             //終端文字\r
119             break;\r
120         }\r
121         CHNLIB_UIPArray_AppendLast(separated, u, autorelease(CHNLIB_String_ExtractByLength(s, (int)(p - p_base), (int)(q - p))));\r
122         p = q;\r
123     }\r
124     \r
125     return 0;\r
126 }\r
127 \r
128 CHNLIB_String *CHNLIB_ReadLine(FILE *fp)\r
129 {\r
130     //改行文字を削除して、読み込んだ文字列一行を返す。\r
131     char s[CHNLIB_MAX_STRING_LENGTH];\r
132     \r
133     if(fgets(s, sizeof(s), fp) == NULL){\r
134         return NULL;\r
135     }\r
136     \r
137     CHNLIB_CString_DeleteLastCRLF(s);\r
138     \r
139     return CHNLIB_String_Initialize(s);\r
140 }\r
141 \r
142 CHNLIB_UUID *CHNLIB_GenerateUUIDVersion4WithRandomGeneratorMT(CHNLIB_RandomGeneratorMT *mt)\r
143 {\r
144     //mtが有効でない場合、NullUUIDを返す。\r
145     CHNLIB_UUID *uuid;\r
146     \r
147     uuid = CHNLIB_UUID_Initialise();\r
148     \r
149     if(CHNLIB_StructureHeader_GetTypeID(mt) != CHNLIB_STRUCT_ID_RandomGeneratorMT){\r
150         return uuid;\r
151     }\r
152     \r
153     CHNLIB_UUID_SetValueAsUUIDVersion4CompatibleWithRFC4122(uuid, CHNLIB_RandomGeneratorMT_GetRandomUnsignedInteger32(mt), CHNLIB_RandomGeneratorMT_GetRandomUnsignedInteger32(mt), CHNLIB_RandomGeneratorMT_GetRandomUnsignedInteger32(mt), CHNLIB_RandomGeneratorMT_GetRandomUnsignedInteger32(mt));\r
154     \r
155     return uuid;\r
156 }\r
157 \r