summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Consalus <consalus@gmail.com>2010-04-20 22:18:26 -0700
committerKyle Consalus <consalus@gmail.com>2010-04-20 22:18:26 -0700
commit242ea6802ef34870bd05659d83eb775a39a39688 (patch)
treeca4905eb1a968af3a77fe885c0a79efa8221d648
parentc3704d5bf7d1e15ebd18d22146b5bc02d5c3aaec (diff)
downloadgolang-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.go27
-rw-r--r--src/pkg/strings/strings_test.go23
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)
+ }
+ }
+}