utf8 ucs4

11067 ワード

この質問には答えにくいですが、まずUTF-8符号化はUnicodeの変換にすぎず、ASCIIと互換性があります.したがって、UTF-8符号化がサポートする最大文字符号化は、Unicodeがサポートする最大文字符号化であるべきである.理論上、UTF-8符号化は最大6バイト:00000000-00000007 F 0 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyy 10 yyyyyxxx 10 xxxxxxxxUCS 4は最大2^32文字を表すことができます.しかし、UTF-8は最大2^31文字しか表示できません.現実には、Unicode仕様ではこれほど多くの文字が規定されていません.現在はPlane 16、最大1114111文字まで規定されています.そのため、ネット上ではUTF-8符号化について、多くは4バイトまで:00000000-000007 F 0 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxシステムにインストールされているフォントがどれだけの文字をサポートしているかを見てみましょう.したがって、「utf-8で現在使用されている文字の最大符号化数」という質問の答えは、Unicode仕様のバージョン、具体的なフォントライブラリのサポートに依存します.
 
0 x 00-0 x 7 FはASCIIと同様、他の任意のマルチバイトUTF-8文字の一部として0 xC 0-0 xDFマルチバイトUTF-8文字の先頭バイトとすることは不可能であり、これにより、このUTF-8文字の長さ(バイト数)0 x 80-0 xBFマルチバイトUTF-8文字の追従バイト0 xFE-0 xFFUTF-8が使用されていないと判断できる
>バイト数
ビット数
表示
> 1
7
0bbbbbbb
> 2
11
110bbbbb 10bbbbbb
> 3
16
1110bbbb 10bbbbbb 10bbbbbb
> 4
21
11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
> 5
26
111110bb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
> 6
31
1111110b 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
> 7
36
11111110 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
> 8
42
11111111 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
 
 
 
typedef uint8 utf8;
//typedef    uint16    utf16; // removed typedef to prevent usage, as utf16 is not supported (yet)
typedef    uint32    utf32;



// return number of code units in a null terminated string
    size_type utf_length(const utf8* utf8_str) const
    {
        size_type cnt = 0;
        while (*utf8_str++)
            cnt++;

        return cnt;
    }

    // return number of code units in a null terminated string
    size_type utf_length(const utf32* utf32_str) const
    {
        size_type cnt = 0;
        while (*utf32_str++)
            cnt++;

        return cnt;
    }

上はutf 8が占めるバイト数とutf 32が占めるバイト数を計算する
// return number of utf32 code units required to re-encode given utf8 data as utf32.  len is number of code units in 'buf'.
    size_type encoded_size(const utf8* buf, size_type len) const
    {
        utf8 tcp;
        size_type count = 0;

        while (len--)
        {
            tcp = *buf++;
            ++count;
            size_type size = 0;

            if (tcp < 0x80)
            {
            }
            else if (tcp < 0xE0)
            {
                size = 1;
                ++buf;
            }
            else if (tcp < 0xF0)
            {
                size = 2;
                buf += 2;
            }
            else
            {
                size = 3;
                buf += 3;
            }

            if (len >= size)
                len -= size;
            else 
                break;
        }

        return count;
    }

utf 8の文字数を計算する
// return the number of utf8 code units required to encode the given utf32 code point
    size_type encoded_size(utf32 code_point) const
    {
        if (code_point < 0x80)
            return 1;
        else if (code_point < 0x0800)
            return 2;
        else if (code_point < 0x10000)
            return 3;
        else
            return 4;
    }

ucs 4のutf 8へのバイト数を計算する
 
size_type encode(const utf8* src, utf32* dest, size_type dest_len, size_type src_len = 0) const
    {
        // count length for null terminated source...
        if (src_len == 0)
        {
            src_len = utf_length(src);
        }

        size_type destCapacity = dest_len;

        // while there is data in the source buffer, and space in the dest buffer
        for (uint idx = 0; ((idx < src_len) && (destCapacity > 0));)
        {
            utf32    cp;
            utf8    cu = src[idx++];

            if (cu < 0x80)
            {
                cp = (utf32)(cu);
            }
            else if (cu < 0xE0)
            {
                cp = ((cu & 0x1F) << 6);
                cp |= (src[idx++] & 0x3F);
            }
            else if (cu < 0xF0)
            {
                cp = ((cu & 0x0F) << 12);
                cp |= ((src[idx++] & 0x3F) << 6);
                cp |= (src[idx++] & 0x3F);
            }
            else
            {
                cp = ((cu & 0x07) << 18);
                cp |= ((src[idx++] & 0x3F) << 12);
                cp |= ((src[idx++] & 0x3F) << 6);
                cp |= (src[idx++] & 0x3F);
            }

            *dest++ = cp;
            --destCapacity;
        }

        return dest_len - destCapacity;
    }

utf 8からutf 32すなわちucs 4へ
 
size_type encode(const utf32* src, utf8* dest, size_type dest_len, size_type src_len = 0) const
    {
        // count length for null terminated source...
        if (src_len == 0)
        {
            src_len = utf_length(src);
        }

        size_type destCapacity = dest_len;

        // while there is data in the source buffer,
        for (uint idx = 0; idx < src_len; ++idx)
        {
            utf32    cp = src[idx];

            // check there is enough destination buffer to receive this encoded unit (exit loop & return if not)
            if (destCapacity < encoded_size(cp))
            {
                break;
            }

            if (cp < 0x80)
            {
                *dest++ = (utf8)cp;
                --destCapacity;
            }
            else if (cp < 0x0800)
            {
                *dest++ = (utf8)((cp >> 6) | 0xC0);
                *dest++ = (utf8)((cp & 0x3F) | 0x80);
                destCapacity -= 2;
            }
            else if (cp < 0x10000)
            {
                *dest++ = (utf8)((cp >> 12) | 0xE0);
                *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
                *dest++ = (utf8)((cp & 0x3F) | 0x80);
                destCapacity -= 3;
            }
            else
            {
                *dest++ = (utf8)((cp >> 18) | 0xF0);
                *dest++ = (utf8)(((cp >> 12) & 0x3F) | 0x80);
                *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
                *dest++ = (utf8)((cp & 0x3F) | 0x80);
                destCapacity -= 4;
            }

        }

        return dest_len - destCapacity;
    }

utf 32からutf 8へ