aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strings/reader.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/strings/reader.go')
-rw-r--r--libgo/go/strings/reader.go59
1 files changed, 46 insertions, 13 deletions
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} }