...

Source file src/strings/reader.go

Documentation: strings

		 1  // Copyright 2009 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package strings
		 6  
		 7  import (
		 8  	"errors"
		 9  	"io"
		10  	"unicode/utf8"
		11  )
		12  
		13  // A Reader implements the io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner,
		14  // io.RuneReader, io.RuneScanner, io.Seeker, and io.WriterTo interfaces by reading
		15  // from a string.
		16  // The zero value for Reader operates like a Reader of an empty string.
		17  type Reader struct {
		18  	s				string
		19  	i				int64 // current reading index
		20  	prevRune int	 // index of previous rune; or < 0
		21  }
		22  
		23  // Len returns the number of bytes of the unread portion of the
		24  // string.
		25  func (r *Reader) Len() int {
		26  	if r.i >= int64(len(r.s)) {
		27  		return 0
		28  	}
		29  	return int(int64(len(r.s)) - r.i)
		30  }
		31  
		32  // Size returns the original length of the underlying string.
		33  // Size is the number of bytes available for reading via ReadAt.
		34  // The returned value is always the same and is not affected by calls
		35  // to any other method.
		36  func (r *Reader) Size() int64 { return int64(len(r.s)) }
		37  
		38  // Read implements the io.Reader interface.
		39  func (r *Reader) Read(b []byte) (n int, err error) {
		40  	if r.i >= int64(len(r.s)) {
		41  		return 0, io.EOF
		42  	}
		43  	r.prevRune = -1
		44  	n = copy(b, r.s[r.i:])
		45  	r.i += int64(n)
		46  	return
		47  }
		48  
		49  // ReadAt implements the io.ReaderAt interface.
		50  func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
		51  	// cannot modify state - see io.ReaderAt
		52  	if off < 0 {
		53  		return 0, errors.New("strings.Reader.ReadAt: negative offset")
		54  	}
		55  	if off >= int64(len(r.s)) {
		56  		return 0, io.EOF
		57  	}
		58  	n = copy(b, r.s[off:])
		59  	if n < len(b) {
		60  		err = io.EOF
		61  	}
		62  	return
		63  }
		64  
		65  // ReadByte implements the io.ByteReader interface.
		66  func (r *Reader) ReadByte() (byte, error) {
		67  	r.prevRune = -1
		68  	if r.i >= int64(len(r.s)) {
		69  		return 0, io.EOF
		70  	}
		71  	b := r.s[r.i]
		72  	r.i++
		73  	return b, nil
		74  }
		75  
		76  // UnreadByte implements the io.ByteScanner interface.
		77  func (r *Reader) UnreadByte() error {
		78  	if r.i <= 0 {
		79  		return errors.New("strings.Reader.UnreadByte: at beginning of string")
		80  	}
		81  	r.prevRune = -1
		82  	r.i--
		83  	return nil
		84  }
		85  
		86  // ReadRune implements the io.RuneReader interface.
		87  func (r *Reader) ReadRune() (ch rune, size int, err error) {
		88  	if r.i >= int64(len(r.s)) {
		89  		r.prevRune = -1
		90  		return 0, 0, io.EOF
		91  	}
		92  	r.prevRune = int(r.i)
		93  	if c := r.s[r.i]; c < utf8.RuneSelf {
		94  		r.i++
		95  		return rune(c), 1, nil
		96  	}
		97  	ch, size = utf8.DecodeRuneInString(r.s[r.i:])
		98  	r.i += int64(size)
		99  	return
	 100  }
	 101  
	 102  // UnreadRune implements the io.RuneScanner interface.
	 103  func (r *Reader) UnreadRune() error {
	 104  	if r.i <= 0 {
	 105  		return errors.New("strings.Reader.UnreadRune: at beginning of string")
	 106  	}
	 107  	if r.prevRune < 0 {
	 108  		return errors.New("strings.Reader.UnreadRune: previous operation was not ReadRune")
	 109  	}
	 110  	r.i = int64(r.prevRune)
	 111  	r.prevRune = -1
	 112  	return nil
	 113  }
	 114  
	 115  // Seek implements the io.Seeker interface.
	 116  func (r *Reader) Seek(offset int64, whence int) (int64, error) {
	 117  	r.prevRune = -1
	 118  	var abs int64
	 119  	switch whence {
	 120  	case io.SeekStart:
	 121  		abs = offset
	 122  	case io.SeekCurrent:
	 123  		abs = r.i + offset
	 124  	case io.SeekEnd:
	 125  		abs = int64(len(r.s)) + offset
	 126  	default:
	 127  		return 0, errors.New("strings.Reader.Seek: invalid whence")
	 128  	}
	 129  	if abs < 0 {
	 130  		return 0, errors.New("strings.Reader.Seek: negative position")
	 131  	}
	 132  	r.i = abs
	 133  	return abs, nil
	 134  }
	 135  
	 136  // WriteTo implements the io.WriterTo interface.
	 137  func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
	 138  	r.prevRune = -1
	 139  	if r.i >= int64(len(r.s)) {
	 140  		return 0, nil
	 141  	}
	 142  	s := r.s[r.i:]
	 143  	m, err := io.WriteString(w, s)
	 144  	if m > len(s) {
	 145  		panic("strings.Reader.WriteTo: invalid WriteString count")
	 146  	}
	 147  	r.i += int64(m)
	 148  	n = int64(m)
	 149  	if m != len(s) && err == nil {
	 150  		err = io.ErrShortWrite
	 151  	}
	 152  	return
	 153  }
	 154  
	 155  // Reset resets the Reader to be reading from s.
	 156  func (r *Reader) Reset(s string) { *r = Reader{s, 0, -1} }
	 157  
	 158  // NewReader returns a new Reader reading from s.
	 159  // It is similar to bytes.NewBufferString but more efficient and read-only.
	 160  func NewReader(s string) *Reader { return &Reader{s, 0, -1} }
	 161  

View as plain text