private int writeUTF8Slow ( final CharSequence chars , int off , int len ) { int octets = 0 ; while ( len > 0 ) { final char ch = chars . charAt ( off ) ; if ( ch >= LOW_SURROGATE_FIRST && ch <= LOW_SURROGATE_LAST ) { throw new IllegalArgumentException ( "Unpaired low surrogate: " + ( int ) ch ) ; } if ( ( ch >= HIGH_SURROGATE_FIRST && ch <= HIGH_SURROGATE_LAST ) ) { // we need to look ahead in this case off ++ ; len -- ; if ( len == 0 ) { throw new IllegalArgumentException ( "Unpaired low surrogate at end of character sequence: " + ch ) ; } final int ch2 = chars . charAt ( off ) ; if ( ch2 < LOW_SURROGATE_FIRST || ch2 > LOW_SURROGATE_LAST ) { throw new IllegalArgumentException ( "Low surrogate with unpaired high surrogate: " + ch + " + " + ch2 ) ; } // at this point we have a high and low surrogate final int codepoint = ( ( ( ch - HIGH_SURROGATE_FIRST ) << BITS_PER_SURROGATE ) | ( ch2 - LOW_SURROGATE_FIRST ) ) + SURROGATE_BASE ; writeByte ( ( byte ) ( UTF8_4_OCTET_PREFIX_MASK | ( codepoint >> UTF8_4_OCTET_SHIFT ) ) ) ; writeByte ( ( byte ) ( UTF8_FOLLOW_PREFIX_MASK | ( ( codepoint >> UTF8_3_OCTET_SHIFT ) & UTF8_FOLLOW_MASK ) ) ) ; writeByte ( ( byte ) ( UTF8_FOLLOW_PREFIX_MASK | ( ( codepoint >> UTF8_2_OCTET_SHIFT ) & UTF8_FOLLOW_MASK ) ) ) ; writeByte ( ( byte ) ( UTF8_FOLLOW_PREFIX_MASK | ( codepoint & UTF8_FOLLOW_MASK ) ) ) ; octets += 4 ; } else if ( ch < UTF8_2_OCTET_MIN_VALUE ) { writeByte ( ( byte ) ch ) ; octets ++ ; } else if ( ch < UTF8_3_OCTET_MIN_VALUE ) { writeByte ( ( byte ) ( UTF8_2_OCTET_PREFIX_MASK | ( ch >> UTF8_2_OCTET_SHIFT ) ) ) ; writeByte ( ( byte ) ( UTF8_FOLLOW_PREFIX_MASK | ( ch & UTF8_FOLLOW_MASK ) ) ) ; octets += 2 ; } else { writeByte ( ( byte ) ( UTF8_3_OCTET_PREFIX_MASK | ( ch >> UTF8_3_OCTET_SHIFT ) ) ) ; writeByte ( ( byte ) ( UTF8_FOLLOW_PREFIX_MASK | ( ( ch >> UTF8_2_OCTET_SHIFT ) & UTF8_FOLLOW_MASK ) ) ) ; writeByte ( ( byte ) ( UTF8_FOLLOW_PREFIX_MASK | ( ch & UTF8_FOLLOW_MASK ) ) ) ; octets += 3 ; } off ++ ; len -- ; } return octets ; }
slow in the sense that we deal with any kind of UTF - 8 sequence and block boundaries