diff options
Diffstat (limited to 'src/pkg/unicode/utf16')
-rw-r--r-- | src/pkg/unicode/utf16/utf16.go | 2 | ||||
-rw-r--r-- | src/pkg/unicode/utf16/utf16_test.go | 48 |
2 files changed, 49 insertions, 1 deletions
diff --git a/src/pkg/unicode/utf16/utf16.go b/src/pkg/unicode/utf16/utf16.go index 903e4012a..c0e47c535 100644 --- a/src/pkg/unicode/utf16/utf16.go +++ b/src/pkg/unicode/utf16/utf16.go @@ -36,7 +36,7 @@ func IsSurrogate(r rune) bool { // the Unicode replacement code point U+FFFD. func DecodeRune(r1, r2 rune) rune { if surr1 <= r1 && r1 < surr2 && surr2 <= r2 && r2 < surr3 { - return (rune(r1)-surr1)<<10 | (rune(r2) - surr2) + 0x10000 + return (r1-surr1)<<10 | (r2 - surr2) + 0x10000 } return replacementChar } diff --git a/src/pkg/unicode/utf16/utf16_test.go b/src/pkg/unicode/utf16/utf16_test.go index ee16a303d..3dca472bb 100644 --- a/src/pkg/unicode/utf16/utf16_test.go +++ b/src/pkg/unicode/utf16/utf16_test.go @@ -99,3 +99,51 @@ func TestDecode(t *testing.T) { } } } + +var decodeRuneTests = []struct { + r1, r2 rune + want rune +}{ + {0xd800, 0xdc00, 0x10000}, + {0xd800, 0xdc01, 0x10001}, + {0xd808, 0xdf45, 0x12345}, + {0xdbff, 0xdfff, 0x10ffff}, + {0xd800, 'a', 0xfffd}, // illegal, replacement rune substituted +} + +func TestDecodeRune(t *testing.T) { + for i, tt := range decodeRuneTests { + got := DecodeRune(tt.r1, tt.r2) + if got != tt.want { + t.Errorf("%d: DecodeRune(%q, %q) = %v; want %v", i, tt.r1, tt.r2, got, tt.want) + } + } +} + +var surrogateTests = []struct { + r rune + want bool +}{ + // from http://en.wikipedia.org/wiki/UTF-16 + {'\u007A', false}, // LATIN SMALL LETTER Z + {'\u6C34', false}, // CJK UNIFIED IDEOGRAPH-6C34 (water) + {'\uFEFF', false}, // Byte Order Mark + {'\U00010000', false}, // LINEAR B SYLLABLE B008 A (first non-BMP code point) + {'\U0001D11E', false}, // MUSICAL SYMBOL G CLEF + {'\U0010FFFD', false}, // PRIVATE USE CHARACTER-10FFFD (last Unicode code point) + + {rune(0xd7ff), false}, // surr1-1 + {rune(0xd800), true}, // surr1 + {rune(0xdc00), true}, // surr2 + {rune(0xe000), false}, // surr3 + {rune(0xdfff), true}, // surr3-1 +} + +func TestIsSurrogate(t *testing.T) { + for i, tt := range surrogateTests { + got := IsSurrogate(tt.r) + if got != tt.want { + t.Errorf("%d: IsSurrogate(%q) = %v; want %v", i, tt.r, got, tt.want) + } + } +} |