int CHNLIB_UTF8_GetCharacterType(char c)\r
{\r
//UTF-8文字列中の1バイトcが、UTF-8文字列中でどのような役割を持つのかを返す。\r
+ //0:マルチバイト文字の後続バイト\r
+ //1:1バイト文字\r
+ //2以上の数値n:nバイト文字の最初のバイト。後続のn個のマルチバイト後続バイトと組み合わせて一つの文字を示す。\r
+ //判断不能な場合は-1を返す。\r
+ //[UTF-8]\r
if(((c >> 6) & 3) == 2){\r
//マルチバイト後続バイト\r
//10xxxxxx\r
return 4;\r
}\r
\r
+ return -1;\r
+}\r
+\r
+int CHNLIB_UTF8_GetStringLengthByCharacter(const char s[])\r
+{\r
+ //sをUTF-8文字列として解釈し、文字としては何文字で構成された文字列かを返す。\r
+ //無効な(マルチバイトの一部が欠けているような)文字はカウントしない。\r
+ //[UTF-8]\r
+ int i, mbsize, n;\r
+ int count;\r
+ \r
+ if(s == NULL){\r
+ return 0;\r
+ }\r
+ \r
+ count = 0;\r
+ mbsize = 0;\r
+ for(i = 0; s[i] != '\0'; i++){\r
+ n = CHNLIB_UTF8_GetCharacterType(s[i]);\r
+ switch(n){\r
+ case -1:\r
+ //無効なバイト\r
+ mbsize = 0;\r
+ break;\r
+ case 0:\r
+ //マルチバイト後続バイト\r
+ if(mbsize > 0){\r
+ mbsize--;\r
+ if(mbsize == 0){\r
+ count++;\r
+ }\r
+ }\r
+ break;\r
+ case 1:\r
+ //1バイト文字\r
+ count++;\r
+ if(mbsize > 0){\r
+ mbsize = 0;\r
+ }\r
+ break;\r
+ default:\r
+ //nバイト文字の最初のバイト\r
+ mbsize = n - 1;\r
+ break;\r
+ }\r
+ }\r
+ return count;\r
+}\r
+\r
+uint CHNLIB_UTF8_GetNextUnicodeOfCharacter(const char s[], const char **next)\r
+{\r
+ //sをUTF-8文字列として解釈し、その文字列の最初の文字のUnicodeを返す。\r
+ //また、nextがNULLでないとき、*nextに、この文字列中で次の文字にあたる部分へのポインタを格納する。\r
+ //s==NULLの時、*nextの値は変更されない。\r
+ //次の文字が存在しない場合は、*nextはs中の終端文字へのポインタとなる。また、戻り値は0となる。\r
+ //無効な(マルチバイトの一部が欠けているような)文字は無視する。\r
+ //[UTF-8]\r
+ int i, n, mbsize;\r
+ uint unicode;\r
+ \r
+ if(s == NULL){\r
+ return 0;\r
+ }\r
+ \r
+ unicode = 0;\r
+ for(i = 0; s[i] != '\0'; i++){\r
+ n = CHNLIB_UTF8_GetCharacterType(s[i]);\r
+ switch(n){\r
+ case -1:\r
+ //無効なバイト\r
+ mbsize = 0;\r
+ break;\r
+ case 0:\r
+ //マルチバイト後続バイト\r
+ if(mbsize > 0){\r
+ mbsize--;\r
+ unicode <<= 6;\r
+ unicode |= (0x3f & s[i]);\r
+ if(mbsize == 0){\r
+ return unicode;\r
+ }\r
+ }\r
+ break;\r
+ case 1:\r
+ //1バイト文字\r
+ if(next != NULL){\r
+ *next = (char *)(s + 1);\r
+ }\r
+ return s[i];\r
+ default:\r
+ //nバイト文字の最初のバイト\r
+ unicode = (((s[i]) << (n + 1)) >> n + 1);\r
+ mbsize = n - 1;\r
+ if(next != NULL){\r
+ *next = (char *)(s + n);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ if(next != NULL){\r
+ *next = &s[i];\r
+ }\r
return 0;\r
}\r
\r
+int CHNLIB_UTF8_CompareString(const char s[], const char search[])\r
+{\r
+ //s,searchをUTF-8文字列として解釈し、s[]の先頭からsearch[]と比較し、searchの終端まで一致したらTrue, 一致しなかったらFalseを返す。\r
+ //終端文字は比較せず、search[]に含まれる文字(終端文字除く)がすべて入っていれば一致とみなす。\r
+ //ただし、searchの先頭文字が終端文字、つまり空文字列だった場合は、常にFalseを返す。\r
+ //[UTF-8]\r
+ int i, i_max;\r
+ \r
+ if(s == NULL || search == NULL){\r
+ CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
+ return False;\r
+ }\r
+ if(search[0] == '\0'){\r
+ //空文字はいかなる文字列とも一致しない。\r
+ return False;\r
+ }\r
+ \r
+ i_max = CHNLIB_UTF8_GetStringLengthByCharacter(search);\r
+ for(i = 0; i < i_max; i++){\r
+ if(CHNLIB_UTF8_GetNextUnicodeOfCharacter(s, &s) != CHNLIB_UTF8_GetNextUnicodeOfCharacter(search, &search)){\r
+ return False;\r
+ }\r
+ }\r
+ return True;\r
+}\r
+\r
+int CHNLIB_UTF8_CompareString_LeftHand(const char s[], const char search[])\r
+{\r
+ //s,searchをUTF-8文字列として解釈し、二つの文字列がどの程度一致するか調べる。前方一致。\r
+ //戻り値は、終端文字を除く、同一だった文字数。\r
+ //[UTF-8]\r
+ int i, i_max;\r
+ \r
+ if(s == NULL || search == NULL){\r
+ CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
+ return 0;\r
+ }\r
+ \r
+ i_max = CHNLIB_UTF8_GetStringLengthByCharacter(search);\r
+ for(i = 0; i < i_max; i++){\r
+ if(CHNLIB_UTF8_GetNextUnicodeOfCharacter(s, &s) != CHNLIB_UTF8_GetNextUnicodeOfCharacter(search, &search)){\r
+ break;\r
+ }\r
+ }\r
+ return i;\r
+}\r
\r
+int CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(const char s[], int start, int end)\r
+{\r
+ //sをUTF-8文字列として解釈し、start番目の文字からend番目の文字までの占めるバイト数を返す。\r
+ //start番目の文字が終端文字以降の文字を指している場合は0を返す。\r
+ //end番目の文字が\r
+ //[UTF-8]\r
+ int i;\r
+ const char *p;\r
+ \r
+ if(s == NULL){\r
+ CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
+ return 0;\r
+ }\r
+ if(end < start){\r
+ CHNLIB_ReportError("Invalid index.\n", CHNLIB_DEBUG_ARGUMENTS);\r
+ return 0;\r
+ }\r
+ \r
+ for(i = 0; i < start; i++){\r
+ if(CHNLIB_UTF8_GetNextUnicodeOfCharacter(s, &s) == 0){\r
+ return 0;\r
+ }\r
+ }\r
+ p = s;\r
+ for(; i <= end; i++){\r
+ CHNLIB_UTF8_GetNextUnicodeOfCharacter(p, &p);\r
+ }\r
+ \r
+ return (int)(p - s);\r
+}\r
\r
+uint CHNLIB_UTF8_GetCountOfContain(const char s[], const char search[])\r
+{\r
+ //文字列s中に、文字列searchがいくつ含まれているかを返す。\r
+ //[UTF-8]\r
+ uint count;\r
+ \r
+ if(s == NULL || search == NULL){\r
+ CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
+ return 0;\r
+ }\r
+ \r
+ count = 0;\r
+ for(;;){\r
+ if(CHNLIB_UTF8_CompareString(s, search)){\r
+ count++;\r
+ }\r
+ if(CHNLIB_UTF8_GetNextUnicodeOfCharacter(s, &s) == 0){\r
+ break;\r
+ }\r
+ }\r
+ return count;\r
+}\r