...
Run Format

Source file src/strings/reader.go

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

View as plain text