OSDN Git Service

Update Go library to r60.
[pf3gnuchains/gcc-fork.git] / libgo / go / strings / reader.go
index 914faa0..eb515de 100644 (file)
@@ -9,53 +9,83 @@ import (
        "utf8"
 )
 
-// A Reader satisfies calls to Read, ReadByte, and ReadRune by
-// reading from a string.
-type Reader string
+// A Reader implements the io.Reader, io.ByteScanner, and
+// io.RuneScanner interfaces by reading from a string.
+type Reader struct {
+       s        string
+       i        int // current reading index
+       prevRune int // index of previous rune; or < 0
+}
+
+// Len returns the number of bytes of the unread portion of the
+// string.
+func (r *Reader) Len() int {
+       return len(r.s) - r.i
+}
 
 func (r *Reader) Read(b []byte) (n int, err os.Error) {
-       s := *r
-       if len(s) == 0 {
+       if r.i >= len(r.s) {
                return 0, os.EOF
        }
-       for n < len(s) && n < len(b) {
-               b[n] = s[n]
-               n++
-       }
-       *r = s[n:]
+       n = copy(b, r.s[r.i:])
+       r.i += n
+       r.prevRune = -1
        return
 }
 
 func (r *Reader) ReadByte() (b byte, err os.Error) {
-       s := *r
-       if len(s) == 0 {
+       if r.i >= len(r.s) {
                return 0, os.EOF
        }
-       b = s[0]
-       *r = s[1:]
+       b = r.s[r.i]
+       r.i++
+       r.prevRune = -1
        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() os.Error {
+       if r.i <= 0 {
+               return os.NewError("strings.Reader: at beginning of string")
+       }
+       r.i--
+       r.prevRune = -1
+       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 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 {
+       if r.i >= len(r.s) {
                return 0, 0, os.EOF
        }
-       c := s[0]
-       if c < utf8.RuneSelf {
-               *r = s[1:]
+       r.prevRune = r.i
+       if c := r.s[r.i]; c < utf8.RuneSelf {
+               r.i++
                return int(c), 1, nil
        }
-       rune, size = utf8.DecodeRuneInString(string(s))
-       *r = s[size:]
+       rune, size = utf8.DecodeRuneInString(r.s[r.i:])
+       r.i += size
        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() os.Error {
+       if r.prevRune < 0 {
+               return os.NewError("strings.Reader: previous operation was not ReadRune")
+       }
+       r.i = r.prevRune
+       r.prevRune = -1
+       return 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) }
+func NewReader(s string) *Reader { return &Reader{s, 0, -1} }