public void writeUtf8 ( CharSequence string ) { for ( int i = 0 , len = string . length ( ) ; i < len ; i ++ ) { char ch = string . charAt ( i ) ; if ( ch < 0x80 ) { // 7-bit ASCII character writeByte ( ch ) ; // This could be an ASCII run, or possibly entirely ASCII while ( i < len - 1 ) { ch = string . charAt ( i + 1 ) ; if ( ch >= 0x80 ) break ; i ++ ; writeByte ( ch ) ; // another 7-bit ASCII character } } else if ( ch < 0x800 ) { // 11-bit character writeByte ( 0xc0 | ( ch >> 6 ) ) ; writeByte ( 0x80 | ( ch & 0x3f ) ) ; } else if ( ch < 0xd800 || ch > 0xdfff ) { // 16-bit character writeByte ( 0xe0 | ( ch >> 12 ) ) ; writeByte ( 0x80 | ( ( ch >> 6 ) & 0x3f ) ) ; writeByte ( 0x80 | ( ch & 0x3f ) ) ; } else { // Possibly a 21-bit character if ( ! Character . isHighSurrogate ( ch ) ) { // Malformed or not UTF-8 writeByte ( ' ' ) ; continue ; } if ( i == len - 1 ) { // Truncated or not UTF-8 writeByte ( ' ' ) ; break ; } char low = string . charAt ( ++ i ) ; if ( ! Character . isLowSurrogate ( low ) ) { // Malformed or not UTF-8 writeByte ( ' ' ) ; writeByte ( Character . isHighSurrogate ( low ) ? ' ' : low ) ; continue ; } // Write the 21-bit character using 4 bytes // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G2630 int codePoint = Character . toCodePoint ( ch , low ) ; writeByte ( 0xf0 | ( codePoint >> 18 ) ) ; writeByte ( 0x80 | ( ( codePoint >> 12 ) & 0x3f ) ) ; writeByte ( 0x80 | ( ( codePoint >> 6 ) & 0x3f ) ) ; writeByte ( 0x80 | ( codePoint & 0x3f ) ) ; } } }
This transcodes a UTF - 16 Java String to UTF - 8 bytes .