5 // Created by 西田 耀 on 13/02/03.
\r
6 // Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
\r
9 //String関連のうち、このソースファイルで完結する関数群
\r
25 //Define static values
\r
27 char *CHNLIB_String_Intenal_NullCString = "";
\r
30 //Declare internal functions
\r
33 CHNLIB_String *CHNLIB_String_Internal_Allocate(void);
\r
34 void CHNLIB_String_Internal_Destruct(void **structure);
\r
40 struct CHNLIB_STRING {
\r
42 CHNLIB_StructureHeader header;
\r
47 //Functions(CHNLIB_String)
\r
50 CHNLIB_String *CHNLIB_String_Initialize(const char str[])
\r
52 //指定された引数strと等価なStringを確保し返す。
\r
53 //str==NULLの時は、NULLポインタへの参照を持つStringを返す。
\r
54 CHNLIB_String *strtag;
\r
56 strtag = CHNLIB_String_Internal_Allocate();
\r
57 strtag->header.destructor = &CHNLIB_String_Internal_Destruct;
\r
60 CHNLIB_String_SetStringFromCString(strtag, str);
\r
65 void CHNLIB_String_Free(CHNLIB_String *strtag)
\r
68 if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){
\r
72 if(strtag->str != NULL){
\r
73 CHNLIB_System_FreeMemory(strtag->str, CHNLIB_DEBUG_ARGUMENTS);
\r
75 strtag->header.typeid = CHNLIB_STRUCT_ID_Null;
\r
76 strtag->header.signature = 0;
\r
77 CHNLIB_System_FreeMemory(strtag, CHNLIB_DEBUG_ARGUMENTS);
\r
82 int CHNLIB_String_SetStringFromCString(CHNLIB_String *strtag, const char s[])
\r
84 //strtagにsと等価な文字列を代入する。
\r
85 //strtag==Invalid || s==NULLのときは何もしない。
\r
88 if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){
\r
96 size = CHNLIB_CString_GetByteLength(s) + 1;
\r
97 if(strtag->str != NULL){
\r
98 CHNLIB_System_FreeMemory(strtag->str, CHNLIB_DEBUG_ARGUMENTS);
\r
100 strtag->str = CHNLIB_System_AllocateMemory_Strict(size, CHNLIB_DEBUG_ARGUMENTS);
\r
101 for(i = 0; i < size - 1; i++){
\r
102 strtag->str[i] = s[i];
\r
104 strtag->str[i] = '\0';
\r
108 int CHNLIB_String_Print(CHNLIB_String *strtag)
\r
110 //strtagが格納している文字列を標準出力に出力する。
\r
111 if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){
\r
114 if(strtag->str == NULL){
\r
118 return fputs(strtag->str, stdout);
\r
121 const char *CHNLIB_String_GetReferencePointerOfCString(const CHNLIB_String *strtag)
\r
123 //strtagが格納している文字列へのポインタを返す。
\r
124 //strtag->str==NULLの場合、constな空文字へのポインタを返す。
\r
125 if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){
\r
129 if(strtag->str == NULL){
\r
130 return CHNLIB_String_Intenal_NullCString;
\r
133 return (const char *)strtag->str;
\r
136 CHNLIB_String *CHNLIB_String_ExtractByLength(const CHNLIB_String *strtag, int start, int len)
\r
138 //strtagが格納している文字列sについて、
\r
139 //s[start]からs[start + len - 1]の文字を含む文字列と等価なStringを確保し返す。
\r
140 //lenに満たずにsが終端文字を迎えた場合は、sの終端文字直前までの文字列がコピーされる。
\r
141 //(len < 0)のときは、NULLを返す。また、結果として(len < 0)となった時も同様にNULLを返す。
\r
143 CHNLIB_String *retstrtag;
\r
145 retstr = CHNLIB_CString_ExtractByLength(strtag->str, start, len);
\r
147 if(retstr == NULL){
\r
151 retstrtag = CHNLIB_String_Initialize(NULL);
\r
152 retstrtag->str = retstr;
\r
157 int CHNLIB_String_GetLength(const CHNLIB_String *strtag)
\r
159 if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){
\r
163 return CHNLIB_CString_GetByteLength(strtag->str);
\r
166 void CHNLIB_String_DeleteLastCRLF(CHNLIB_String *strtag)
\r
168 if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){
\r
172 CHNLIB_CString_DeleteLastCRLF(strtag->str);
\r
177 int CHNLIB_String_CompareStringWithCString(const CHNLIB_String *s, const char search[])
\r
179 return CHNLIB_CString_CompareString(CHNLIB_String_GetReferencePointerOfCString(s), search);
\r
182 int CHNLIB_String_CompareString_Strict(const CHNLIB_String *s, const CHNLIB_String *search)
\r
184 return CHNLIB_CString_CompareString_Strict(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));
\r
187 uint CHNLIB_String_GetCountOfContain(const CHNLIB_String *s, const CHNLIB_String *search)
\r
189 return CHNLIB_UTF8_GetCountOfContain(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));
\r
193 //Functions(CString(char[]))
\r
196 int CHNLIB_CString_GetByteLength(const char s[])
\r
199 //終端文字を除いた、文字列本体のバイト数を返す。
\r
206 for(i = 0; s[i] != 0x00; i++){
\r
213 void CHNLIB_CString_DeleteLastCRLF(char s[])
\r
215 //末尾のLF, CR/LFを\0に置換する
\r
223 for(i = 0; s[i] != '\0'; i++){
\r
225 if(crlf == -1 || crlf + 1 != i){
\r
230 if(crlf == -1 || crlf + 1 != i){
\r
236 for(i = crlf; s[i] != '\0'; i++){
\r
243 char *CHNLIB_CString_ExtractByLength(const char s[], int start, int len)
\r
245 //s[start]からs[start + len - 1]の文字を含む文字列を、新たにメモリを確保して書き込み、その先頭アドレスを返す。
\r
246 //lenに満たずにsが終端文字を迎えた場合は、sの終端文字直前までの文字列がコピーされる。
\r
247 //(len < 0)のときは、NULLを返す。また、結果として(len < 0)となった時も同様にNULLを返す。
\r
253 CHNLIB_ReportError("Null s[]\n", CHNLIB_DEBUG_ARGUMENTS);
\r
257 i = CHNLIB_CString_GetByteLength(s) + 1;
\r
267 str = CHNLIB_System_AllocateMemory_Strict(i, CHNLIB_DEBUG_ARGUMENTS);
\r
269 for(i = 0; s[i + start] != '\0'; i++){
\r
274 utf8type = CHNLIB_UTF8_GetCharacterType(s[i + start]);
\r
275 if(len < utf8type){
\r
280 str[i] = s[i + start];
\r
287 int CHNLIB_CString_CompareString(const char s[], const char search[])
\r
289 //s[]の先頭からsearch[]と比較し、searchの終端まで一致したらTrue, 一致しなかったらFalseを返す。
\r
290 //終端文字'\0'はカウントしない。
\r
291 //search[]に含まれる文字(終端文字除く)がすべて入っていれば一致とみなす。
\r
294 if(s == NULL || search == NULL){
\r
295 CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);
\r
299 for(i = 0; search[i] != '\0'; i++){
\r
300 if(s[i] != search[i]){
\r
307 int CHNLIB_CString_CompareString_Strict(const char s[], const char search[])
\r
309 //二つの文字列が終端文字までを含めて完全に一致するかどうか調べる。一致していればTrueを返す。
\r
310 //StrictよりExactの方が適する?<関数名
\r
313 if(s == NULL || search == NULL){
\r
314 CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);
\r
318 for(i = 0; search[i] != '\0'; i++){
\r
319 if(s[i] != search[i]){
\r
329 int CHNLIB_CString_CompareString_LeftHand(const char s[], const char search[])
\r
331 //二つの文字列がどの程度一致するか調べる。前方一致。
\r
332 //戻り値は、終端文字を除く、同一だったバイト数。
\r
335 if(s == NULL || search == NULL){
\r
336 CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);
\r
340 for(i = 0; search[i] != '\0'; i++){
\r
341 if(s[i] != search[i]){
\r
350 //Internal functions
\r
353 CHNLIB_String *CHNLIB_String_Internal_Allocate(void)
\r
355 CHNLIB_String *tag;
\r
357 tag = (CHNLIB_String *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_String), CHNLIB_DEBUG_ARGUMENTS);
\r
359 CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_String);
\r
364 void CHNLIB_String_Internal_Destruct(void **structure)
\r
366 //デストラクタ(実際にRelease->freeされる時に呼ばれる)
\r
367 if(structure == NULL){
\r
371 #ifdef DEBUG_MEMORY_REFERENCE_COUNT
\r
372 CHNLIB_Debug("Release(with free)[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure);
\r
375 CHNLIB_String_Free(*structure);
\r