OSDN Git Service

AI003:AI_Think_SlideLookUpWordByHistoryを修正中。
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib04.c
index 9500088..417d1d8 100644 (file)
 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
@@ -48,8 +53,208 @@ int CHNLIB_UTF8_GetCharacterType(char c)
         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