diff options
Diffstat (limited to 'libgo/go/strings')
-rw-r--r-- | libgo/go/strings/example_test.go | 157 | ||||
-rw-r--r-- | libgo/go/strings/reader.go | 59 | ||||
-rw-r--r-- | libgo/go/strings/reader_test.go | 88 |
3 files changed, 291 insertions, 13 deletions
diff --git a/libgo/go/strings/example_test.go b/libgo/go/strings/example_test.go index 16e53678b20..5ef0b93d15e 100644 --- a/libgo/go/strings/example_test.go +++ b/libgo/go/strings/example_test.go @@ -13,3 +13,160 @@ import ( func ExampleFields() { fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) } + +// true +// false +// true +// true +func ExampleContains() { + fmt.Println(strings.Contains("seafood", "foo")) + fmt.Println(strings.Contains("seafood", "bar")) + fmt.Println(strings.Contains("seafood", "")) + fmt.Println(strings.Contains("", "")) +} + +// false +// true +// false +// false +func ExampleContainsAny() { + fmt.Println(strings.ContainsAny("team", "i")) + fmt.Println(strings.ContainsAny("failure", "u & i")) + fmt.Println(strings.ContainsAny("foo", "")) + fmt.Println(strings.ContainsAny("", "")) + +} + +// 3 +// 5 +func ExampleCount() { + fmt.Println(strings.Count("cheese", "e")) + fmt.Println(strings.Count("five", "")) // before & after each rune +} + +// true +func ExampleEqualFold() { + fmt.Println(strings.EqualFold("Go", "go")) +} + +// 4 +// -1 +func ExampleIndex() { + fmt.Println(strings.Index("chicken", "ken")) + fmt.Println(strings.Index("chicken", "dmr")) +} + +// 4 +// -1 +func ExampleRune() { + fmt.Println(strings.IndexRune("chicken", 'k')) + fmt.Println(strings.IndexRune("chicken", 'd')) +} + +// 0 +// 3 +// -1 +func ExampleLastIndex() { + fmt.Println(strings.Index("go gopher", "go")) + fmt.Println(strings.LastIndex("go gopher", "go")) + fmt.Println(strings.LastIndex("go gopher", "rodent")) +} + +// foo, bar, baz +func ExampleJoin() { + s := []string{"foo", "bar", "baz"} + fmt.Println(strings.Join(s, ", ")) +} + +// banana +func ExampleRepeat() { + fmt.Println("ba" + strings.Repeat("na", 2)) +} + +// oinky oinky oink +// moo moo moo +func ExampleReplace() { + fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2)) + fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1)) +} + +// ["a" "b" "c"] +// ["" "man " "plan " "canal panama"] +// [" " "x" "y" "z" " "] +// [""] +func ExampleSplit() { + fmt.Printf("%q\n", strings.Split("a,b,c", ",")) + fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a ")) + fmt.Printf("%q\n", strings.Split(" xyz ", "")) + fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins")) +} + +// ["a" "b,c"] +// [] (nil = true) +func ExampleSplitN() { + fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2)) + z := strings.SplitN("a,b,c", ",", 0) + fmt.Printf("%q (nil = %v)\n", z, z == nil) +} + +// ["a," "b," "c"] +func ExampleSplitAfter() { + fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ",")) +} + +// ["a," "b,c"] +func ExampleSplitAfterN() { + fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2)) +} + +// Her Royal Highness +func ExampleTitle() { + fmt.Println(strings.Title("her royal highness")) +} + +// LOUD NOISES +// ХЛЕБ +func ExampleToTitle() { + fmt.Println(strings.ToTitle("loud noises")) + fmt.Println(strings.ToTitle("хлеб")) +} + +// [Achtung] +func ExampleTrim() { + fmt.Printf("[%s]", strings.Trim(" !!! Achtung !!! ", "! ")) +} + +// 'Gjnf oevyyvt naq gur fyvgul tbcure... +func ExampleMap() { + rot13 := func(r rune) rune { + switch { + case r >= 'A' && r <= 'Z': + return 'A' + (r-'A'+13)%26 + case r >= 'a' && r <= 'z': + return 'a' + (r-'a'+13)%26 + } + return r + } + fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher...")) +} + +// a lone gopher +func ExampleTrimSpace() { + fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n")) +} + +// This is <b>HTML</b>! +func ExampleNewReplacer() { + r := strings.NewReplacer("<", "<", ">", ">") + fmt.Println(r.Replace("This is <b>HTML</b>!")) +} + +// GOPHER +func ExampleToUpper() { + fmt.Println(strings.ToUpper("Gopher")) +} + +// gopher +func ExampleToLower() { + fmt.Println(strings.ToLower("Gopher")) +} diff --git a/libgo/go/strings/reader.go b/libgo/go/strings/reader.go index 8ff851f36a8..8569805552d 100644 --- a/libgo/go/strings/reader.go +++ b/libgo/go/strings/reader.go @@ -10,8 +10,9 @@ import ( "unicode/utf8" ) -// A Reader implements the io.Reader, io.ByteScanner, and -// io.RuneScanner interfaces by reading from a string. +// A Reader implements the io.Reader, io.ReaderAt, io.Seeker, +// io.ByteScanner, and io.RuneScanner interfaces by reading +// from a string. type Reader struct { s string i int // current reading index @@ -21,10 +22,16 @@ type Reader struct { // Len returns the number of bytes of the unread portion of the // string. func (r *Reader) Len() int { + if r.i >= len(r.s) { + return 0 + } return len(r.s) - r.i } func (r *Reader) Read(b []byte) (n int, err error) { + if len(b) == 0 { + return 0, nil + } if r.i >= len(r.s) { return 0, io.EOF } @@ -34,6 +41,20 @@ func (r *Reader) Read(b []byte) (n int, err error) { return } +func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) { + if off < 0 { + return 0, errors.New("strings: invalid offset") + } + if off >= int64(len(r.s)) { + return 0, io.EOF + } + n = copy(b, r.s[int(off):]) + if n < len(b) { + err = io.EOF + } + return +} + func (r *Reader) ReadByte() (b byte, err error) { if r.i >= len(r.s) { return 0, io.EOF @@ -44,9 +65,6 @@ func (r *Reader) ReadByte() (b byte, err error) { return } -// UnreadByte moves the reading position back by one byte. -// It is an error to call UnreadByte if nothing has been -// read yet. func (r *Reader) UnreadByte() error { if r.i <= 0 { return errors.New("strings.Reader: at beginning of string") @@ -56,11 +74,6 @@ func (r *Reader) UnreadByte() error { return nil } -// ReadRune reads and returns the next UTF-8-encoded -// Unicode code point from the buffer. -// If no bytes are available, the error returned is io.EOF. -// If the bytes are an erroneous UTF-8 encoding, it -// consumes one byte and returns U+FFFD, 1. func (r *Reader) ReadRune() (ch rune, size int, err error) { if r.i >= len(r.s) { return 0, 0, io.EOF @@ -75,9 +88,6 @@ func (r *Reader) ReadRune() (ch rune, size int, err error) { return } -// UnreadRune causes the next call to ReadRune to return the same rune -// as the previous call to ReadRune. -// The last method called on r must have been ReadRune. func (r *Reader) UnreadRune() error { if r.prevRune < 0 { return errors.New("strings.Reader: previous operation was not ReadRune") @@ -87,6 +97,29 @@ func (r *Reader) UnreadRune() error { return nil } +// Seek implements the io.Seeker interface. +func (r *Reader) Seek(offset int64, whence int) (int64, error) { + var abs int64 + switch whence { + case 0: + abs = offset + case 1: + abs = int64(r.i) + offset + case 2: + abs = int64(len(r.s)) + offset + default: + return 0, errors.New("strings: invalid whence") + } + if abs < 0 { + return 0, errors.New("strings: negative position") + } + if abs >= 1<<31 { + return 0, errors.New("strings: position out of range") + } + r.i = int(abs) + return abs, nil +} + // NewReader returns a new Reader reading from s. // It is similar to bytes.NewBufferString but more efficient and read-only. func NewReader(s string) *Reader { return &Reader{s, 0, -1} } diff --git a/libgo/go/strings/reader_test.go b/libgo/go/strings/reader_test.go new file mode 100644 index 00000000000..a99ae2a0ea6 --- /dev/null +++ b/libgo/go/strings/reader_test.go @@ -0,0 +1,88 @@ +// Copyright 2012 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 strings_test + +import ( + "fmt" + "io" + "os" + "strings" + "testing" +) + +func TestReader(t *testing.T) { + r := strings.NewReader("0123456789") + tests := []struct { + off int64 + seek int + n int + want string + wantpos int64 + seekerr string + }{ + {seek: os.SEEK_SET, off: 0, n: 20, want: "0123456789"}, + {seek: os.SEEK_SET, off: 1, n: 1, want: "1"}, + {seek: os.SEEK_CUR, off: 1, wantpos: 3, n: 2, want: "34"}, + {seek: os.SEEK_SET, off: -1, seekerr: "strings: negative position"}, + {seek: os.SEEK_SET, off: 1<<31 - 1}, + {seek: os.SEEK_CUR, off: 1, seekerr: "strings: position out of range"}, + {seek: os.SEEK_SET, n: 5, want: "01234"}, + {seek: os.SEEK_CUR, n: 5, want: "56789"}, + {seek: os.SEEK_END, off: -1, n: 1, wantpos: 9, want: "9"}, + } + + for i, tt := range tests { + pos, err := r.Seek(tt.off, tt.seek) + if err == nil && tt.seekerr != "" { + t.Errorf("%d. want seek error %q", i, tt.seekerr) + continue + } + if err != nil && err.Error() != tt.seekerr { + t.Errorf("%d. seek error = %q; want %q", i, err.Error(), tt.seekerr) + continue + } + if tt.wantpos != 0 && tt.wantpos != pos { + t.Errorf("%d. pos = %d, want %d", i, pos, tt.wantpos) + } + buf := make([]byte, tt.n) + n, err := r.Read(buf) + if err != nil { + t.Errorf("%d. read = %v", i, err) + continue + } + got := string(buf[:n]) + if got != tt.want { + t.Errorf("%d. got %q; want %q", i, got, tt.want) + } + } +} + +func TestReaderAt(t *testing.T) { + r := strings.NewReader("0123456789") + tests := []struct { + off int64 + n int + want string + wanterr interface{} + }{ + {0, 10, "0123456789", nil}, + {1, 10, "123456789", io.EOF}, + {1, 9, "123456789", nil}, + {11, 10, "", io.EOF}, + {0, 0, "", nil}, + {-1, 0, "", "strings: invalid offset"}, + } + for i, tt := range tests { + b := make([]byte, tt.n) + rn, err := r.ReadAt(b, tt.off) + got := string(b[:rn]) + if got != tt.want { + t.Errorf("%d. got %q; want %q", i, got, tt.want) + } + if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) { + t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr) + } + } +} |