// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package utf16 implements encoding and decoding of UTF-16 sequences.
package utf16 // The conditions replacementChar==unicode.ReplacementChar and // maxRune==unicode.MaxRune are verified in the tests. // Defining them locally avoids this package depending on package unicode. const ( replacementChar = '\uFFFD' // Unicode replacement character maxRune = '\U0010FFFF' // Maximum valid Unicode code point. ) const ( // 0xd800-0xdc00 encodes the high 10 bits of a pair. // 0xdc00-0xe000 encodes the low 10 bits of a pair. // the value is those 20 bits plus 0x10000. surr1 = 0xd800 surr2 = 0xdc00 surr3 = 0xe000 surrSelf = 0x10000 ) // IsSurrogate reports whether the specified Unicode code point // can appear in a surrogate pair. func ( rune) bool { return surr1 <= && < surr3 } // DecodeRune returns the UTF-16 decoding of a surrogate pair. // If the pair is not a valid UTF-16 surrogate pair, DecodeRune returns // the Unicode replacement code point U+FFFD. func (, rune) rune { if surr1 <= && < surr2 && surr2 <= && < surr3 { return (-surr1)<<10 | ( - surr2) + surrSelf } return replacementChar } // EncodeRune returns the UTF-16 surrogate pair r1, r2 for the given rune. // If the rune is not a valid Unicode code point or does not need encoding, // EncodeRune returns U+FFFD, U+FFFD. func ( rune) (, rune) { if < surrSelf || > maxRune { return replacementChar, replacementChar } -= surrSelf return surr1 + (>>10)&0x3ff, surr2 + &0x3ff } // Encode returns the UTF-16 encoding of the Unicode code point sequence s. func ( []rune) []uint16 { := len() for , := range { if >= surrSelf { ++ } } := make([]uint16, ) = 0 for , := range { switch { case 0 <= && < surr1, surr3 <= && < surrSelf: // normal rune [] = uint16() ++ case surrSelf <= && <= maxRune: // needs surrogate sequence , := EncodeRune() [] = uint16() [+1] = uint16() += 2 default: [] = uint16(replacementChar) ++ } } return [:] } // AppendRune appends the UTF-16 encoding of the Unicode code point r // to the end of p and returns the extended buffer. If the rune is not // a valid Unicode code point, it appends the encoding of U+FFFD. func ( []uint16, rune) []uint16 { // This function is inlineable for fast handling of ASCII. switch { case 0 <= && < surr1, surr3 <= && < surrSelf: // normal rune return append(, uint16()) case surrSelf <= && <= maxRune: // needs surrogate sequence , := EncodeRune() return append(, uint16(), uint16()) } return append(, replacementChar) } // Decode returns the Unicode code point sequence represented // by the UTF-16 encoding s. func ( []uint16) []rune { // Preallocate capacity to hold up to 64 runes. // Decode inlines, so the allocation can live on the stack. := make([]rune, 0, 64) return decode(, ) } // decode appends to buf the Unicode code point sequence represented // by the UTF-16 encoding s and return the extended buffer. func decode( []uint16, []rune) []rune { for := 0; < len(); ++ { var rune switch := []; { case < surr1, surr3 <= : // normal rune = rune() case surr1 <= && < surr2 && +1 < len() && surr2 <= [+1] && [+1] < surr3: // valid surrogate sequence = DecodeRune(rune(), rune([+1])) ++ default: // invalid surrogate sequence = replacementChar } = append(, ) } return }