mirror of
https://github.com/golang/go
synced 2024-11-12 08:10:21 -07:00
bytes: Change IndexAny to look for UTF-8 encoded characters.
Also improve the implementations of Equals and Compare. R=rsc CC=golang-dev https://golang.org/cl/969047
This commit is contained in:
parent
249c49ed3c
commit
e1d20d0a51
@ -14,11 +14,16 @@ import (
|
|||||||
// Compare returns an integer comparing the two byte arrays lexicographically.
|
// Compare returns an integer comparing the two byte arrays lexicographically.
|
||||||
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b
|
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b
|
||||||
func Compare(a, b []byte) int {
|
func Compare(a, b []byte) int {
|
||||||
for i := 0; i < len(a) && i < len(b); i++ {
|
m := len(a)
|
||||||
|
if m > len(b) {
|
||||||
|
m = len(b)
|
||||||
|
}
|
||||||
|
for i, ac := range a[0:m] {
|
||||||
|
bc := b[i]
|
||||||
switch {
|
switch {
|
||||||
case a[i] > b[i]:
|
case ac > bc:
|
||||||
return 1
|
return 1
|
||||||
case a[i] < b[i]:
|
case ac < bc:
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,8 +41,8 @@ func Equal(a, b []byte) bool {
|
|||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for i := 0; i < len(a); i++ {
|
for i, c := range a {
|
||||||
if a[i] != b[i] {
|
if c != b[i] {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,13 +130,22 @@ func LastIndex(s, sep []byte) int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexAny returns the index of the first instance of any byte
|
// IndexAny interprets s as a sequence of UTF-8 encoded Unicode code points.
|
||||||
// from bytes in s, or -1 if no byte from bytes is present in s.
|
// It returns the byte index of the first occurrence in s of any of the Unicode
|
||||||
func IndexAny(s, bytes []byte) int {
|
// code points in chars. It returns -1 if chars is empty or if there is no code
|
||||||
if len(bytes) > 0 {
|
// point in common.
|
||||||
for i, b := range s {
|
func IndexAny(s []byte, chars string) int {
|
||||||
for _, m := range bytes {
|
if len(chars) > 0 {
|
||||||
if b == m {
|
var rune, width int
|
||||||
|
for i := 0; i < len(s); i += width {
|
||||||
|
rune = int(s[i])
|
||||||
|
if rune < utf8.RuneSelf {
|
||||||
|
width = 1
|
||||||
|
} else {
|
||||||
|
rune, width = utf8.DecodeRune(s[i:])
|
||||||
|
}
|
||||||
|
for _, r := range chars {
|
||||||
|
if rune == r {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,7 +275,8 @@ func HasSuffix(s, suffix []byte) bool {
|
|||||||
|
|
||||||
// Map returns a copy of the byte array s with all its characters modified
|
// Map returns a copy of the byte array s with all its characters modified
|
||||||
// according to the mapping function. If mapping returns a negative value, the character is
|
// according to the mapping function. If mapping returns a negative value, the character is
|
||||||
// dropped from the string with no replacement.
|
// dropped from the string with no replacement. The characters in s and the
|
||||||
|
// output are interpreted as UTF-8 encoded Unicode code points.
|
||||||
func Map(mapping func(rune int) int, s []byte) []byte {
|
func Map(mapping func(rune int) int, s []byte) []byte {
|
||||||
// In the worst case, the array can grow when mapped, making
|
// In the worst case, the array can grow when mapped, making
|
||||||
// things unpleasant. But it's so rare we barge in assuming it's
|
// things unpleasant. But it's so rare we barge in assuming it's
|
||||||
@ -293,7 +308,7 @@ func Map(mapping func(rune int) int, s []byte) []byte {
|
|||||||
return b[0:nbytes]
|
return b[0:nbytes]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repeat returns a new byte array consisting of count copies of b.
|
// Repeat returns a new byte slice consisting of count copies of b.
|
||||||
func Repeat(b []byte, count int) []byte {
|
func Repeat(b []byte, count int) []byte {
|
||||||
nb := make([]byte, len(b)*count)
|
nb := make([]byte, len(b)*count)
|
||||||
bp := 0
|
bp := 0
|
||||||
@ -316,7 +331,8 @@ func ToLower(s []byte) []byte { return Map(unicode.ToLower, s) }
|
|||||||
func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
|
func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
|
||||||
|
|
||||||
// Trim returns a slice of the string s, with all leading and trailing white space
|
// Trim returns a slice of the string s, with all leading and trailing white space
|
||||||
// removed, as defined by Unicode.
|
// removed, as defined by Unicode. The slice is is interpreted as UTF-8 encoded
|
||||||
|
// Unicode code points.
|
||||||
func TrimSpace(s []byte) []byte {
|
func TrimSpace(s []byte) []byte {
|
||||||
start, end := 0, len(s)
|
start, end := 0, len(s)
|
||||||
for start < end {
|
for start < end {
|
||||||
|
@ -119,6 +119,7 @@ var indexAnyTests = []BinOpTest{
|
|||||||
BinOpTest{"aaa", "a", 0},
|
BinOpTest{"aaa", "a", 0},
|
||||||
BinOpTest{"abc", "xyz", -1},
|
BinOpTest{"abc", "xyz", -1},
|
||||||
BinOpTest{"abc", "xcz", 2},
|
BinOpTest{"abc", "xcz", 2},
|
||||||
|
BinOpTest{"ab☺c", "x☺yz", 2},
|
||||||
BinOpTest{"aRegExp*", ".(|)*+?^$[]", 7},
|
BinOpTest{"aRegExp*", ".(|)*+?^$[]", 7},
|
||||||
BinOpTest{dots + dots + dots, " ", -1},
|
BinOpTest{dots + dots + dots, " ", -1},
|
||||||
}
|
}
|
||||||
@ -138,7 +139,15 @@ func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, tes
|
|||||||
|
|
||||||
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
||||||
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
||||||
func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
|
func TestIndexAny(t *testing.T) {
|
||||||
|
for _, test := range indexAnyTests {
|
||||||
|
a := []byte(test.a)
|
||||||
|
actual := IndexAny(a, test.b)
|
||||||
|
if actual != test.i {
|
||||||
|
t.Errorf("IndexAny(%q,%q) = %v; want %v", a, test.b, actual, test.i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIndexByte(t *testing.T) {
|
func TestIndexByte(t *testing.T) {
|
||||||
for _, tt := range indexTests {
|
for _, tt := range indexTests {
|
||||||
|
Loading…
Reference in New Issue
Block a user