...
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 len(b) == 0 {
    39			return 0, nil
    40		}
    41		if r.i >= int64(len(r.s)) {
    42			return 0, io.EOF
    43		}
    44		r.prevRune = -1
    45		n = copy(b, r.s[r.i:])
    46		r.i += int64(n)
    47		return
    48	}
    49	
    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	func (r *Reader) ReadByte() (b byte, err error) {
    66		r.prevRune = -1
    67		if r.i >= int64(len(r.s)) {
    68			return 0, io.EOF
    69		}
    70		b = r.s[r.i]
    71		r.i++
    72		return
    73	}
    74	
    75	func (r *Reader) UnreadByte() error {
    76		r.prevRune = -1
    77		if r.i <= 0 {
    78			return errors.New("strings.Reader.UnreadByte: at beginning of string")
    79		}
    80		r.i--
    81		return nil
    82	}
    83	
    84	func (r *Reader) ReadRune() (ch rune, size int, err error) {
    85		if r.i >= int64(len(r.s)) {
    86			r.prevRune = -1
    87			return 0, 0, io.EOF
    88		}
    89		r.prevRune = int(r.i)
    90		if c := r.s[r.i]; c < utf8.RuneSelf {
    91			r.i++
    92			return rune(c), 1, nil
    93		}
    94		ch, size = utf8.DecodeRuneInString(r.s[r.i:])
    95		r.i += int64(size)
    96		return
    97	}
    98	
    99	func (r *Reader) UnreadRune() error {
   100		if r.prevRune < 0 {
   101			return errors.New("strings.Reader.UnreadRune: previous operation was not ReadRune")
   102		}
   103		r.i = int64(r.prevRune)
   104		r.prevRune = -1
   105		return nil
   106	}
   107	
   108	// Seek implements the io.Seeker interface.
   109	func (r *Reader) Seek(offset int64, whence int) (int64, error) {
   110		r.prevRune = -1
   111		var abs int64
   112		switch whence {
   113		case 0:
   114			abs = offset
   115		case 1:
   116			abs = int64(r.i) + offset
   117		case 2:
   118			abs = int64(len(r.s)) + offset
   119		default:
   120			return 0, errors.New("strings.Reader.Seek: invalid whence")
   121		}
   122		if abs < 0 {
   123			return 0, errors.New("strings.Reader.Seek: negative position")
   124		}
   125		r.i = abs
   126		return abs, nil
   127	}
   128	
   129	// WriteTo implements the io.WriterTo interface.
   130	func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
   131		r.prevRune = -1
   132		if r.i >= int64(len(r.s)) {
   133			return 0, nil
   134		}
   135		s := r.s[r.i:]
   136		m, err := io.WriteString(w, s)
   137		if m > len(s) {
   138			panic("strings.Reader.WriteTo: invalid WriteString count")
   139		}
   140		r.i += int64(m)
   141		n = int64(m)
   142		if m != len(s) && err == nil {
   143			err = io.ErrShortWrite
   144		}
   145		return
   146	}
   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