diff options
author | Kyle Consalus <consalus@gmail.com> | 2010-04-20 22:18:26 -0700 |
---|---|---|
committer | Kyle Consalus <consalus@gmail.com> | 2010-04-20 22:18:26 -0700 |
commit | 242ea6802ef34870bd05659d83eb775a39a39688 (patch) | |
tree | ca4905eb1a968af3a77fe885c0a79efa8221d648 | |
parent | c3704d5bf7d1e15ebd18d22146b5bc02d5c3aaec (diff) | |
download | golang-242ea6802ef34870bd05659d83eb775a39a39688.tar.gz |
strings: add ReadRune to Reader
R=rsc
CC=golang-dev
http://codereview.appspot.com/940041
Committer: Russ Cox <rsc@golang.org>
-rw-r--r-- | src/pkg/strings/reader.go | 27 | ||||
-rw-r--r-- | src/pkg/strings/strings_test.go | 23 |
2 files changed, 48 insertions, 2 deletions
diff --git a/src/pkg/strings/reader.go b/src/pkg/strings/reader.go index 7cefbd24b..914faa003 100644 --- a/src/pkg/strings/reader.go +++ b/src/pkg/strings/reader.go @@ -4,9 +4,12 @@ package strings -import "os" +import ( + "os" + "utf8" +) -// A Reader satisfies calls to Read and ReadByte by +// A Reader satisfies calls to Read, ReadByte, and ReadRune by // reading from a string. type Reader string @@ -33,6 +36,26 @@ func (r *Reader) ReadByte() (b byte, err os.Error) { return } +// ReadRune reads and returns the next UTF-8-encoded +// Unicode code point from the buffer. +// If no bytes are available, the error returned is os.EOF. +// If the bytes are an erroneous UTF-8 encoding, it +// consumes one byte and returns U+FFFD, 1. +func (r *Reader) ReadRune() (rune int, size int, err os.Error) { + s := *r + if len(s) == 0 { + return 0, 0, os.EOF + } + c := s[0] + if c < utf8.RuneSelf { + *r = s[1:] + return int(c), 1, nil + } + rune, size = utf8.DecodeRuneInString(string(s)) + *r = s[size:] + return +} + // 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) } diff --git a/src/pkg/strings/strings_test.go b/src/pkg/strings/strings_test.go index 3c9dc5847..2c99a6ec3 100644 --- a/src/pkg/strings/strings_test.go +++ b/src/pkg/strings/strings_test.go @@ -5,6 +5,7 @@ package strings_test import ( + "os" . "strings" "testing" "unicode" @@ -576,3 +577,25 @@ func TestRunes(t *testing.T) { } } } + +func TestReadRune(t *testing.T) { + testStrings := []string{"", abcd, faces, commas} + for _, s := range testStrings { + reader := NewReader(s) + res := "" + for { + r, _, e := reader.ReadRune() + if e == os.EOF { + break + } + if e != nil { + t.Errorf("Reading %q: %s", s, e) + break + } + res += string(r) + } + if res != s { + t.Errorf("Reader(%q).ReadRune() produced %q", s, res) + } + } +} |