Run Format

Source file src/pkg/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        int // 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 >= len(r.s) {
    26			return 0
    27		}
    28		return len(r.s) - r.i
    29	}
    30	
    31	func (r *Reader) Read(b []byte) (n int, err error) {
    32		if len(b) == 0 {
    33			return 0, nil
    34		}
    35		if r.i >= len(r.s) {
    36			return 0, io.EOF
    37		}
    38		n = copy(b, r.s[r.i:])
    39		r.i += n
    40		r.prevRune = -1
    41		return
    42	}
    43	
    44	func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
    45		if off < 0 {
    46			return 0, errors.New("strings: invalid offset")
    47		}
    48		if off >= int64(len(r.s)) {
    49			return 0, io.EOF
    50		}
    51		n = copy(b, r.s[int(off):])
    52		if n < len(b) {
    53			err = io.EOF
    54		}
    55		return
    56	}
    57	
    58	func (r *Reader) ReadByte() (b byte, err error) {
    59		if r.i >= len(r.s) {
    60			return 0, io.EOF
    61		}
    62		b = r.s[r.i]
    63		r.i++
    64		r.prevRune = -1
    65		return
    66	}
    67	
    68	func (r *Reader) UnreadByte() error {
    69		if r.i <= 0 {
    70			return errors.New("strings.Reader: at beginning of string")
    71		}
    72		r.i--
    73		r.prevRune = -1
    74		return nil
    75	}
    76	
    77	func (r *Reader) ReadRune() (ch rune, size int, err error) {
    78		if r.i >= len(r.s) {
    79			return 0, 0, io.EOF
    80		}
    81		r.prevRune = r.i
    82		if c := r.s[r.i]; c < utf8.RuneSelf {
    83			r.i++
    84			return rune(c), 1, nil
    85		}
    86		ch, size = utf8.DecodeRuneInString(r.s[r.i:])
    87		r.i += size
    88		return
    89	}
    90	
    91	func (r *Reader) UnreadRune() error {
    92		if r.prevRune < 0 {
    93			return errors.New("strings.Reader: previous operation was not ReadRune")
    94		}
    95		r.i = r.prevRune
    96		r.prevRune = -1
    97		return nil
    98	}
    99	
   100	// Seek implements the io.Seeker interface.
   101	func (r *Reader) Seek(offset int64, whence int) (int64, error) {
   102		var abs int64
   103		switch whence {
   104		case 0:
   105			abs = offset
   106		case 1:
   107			abs = int64(r.i) + offset
   108		case 2:
   109			abs = int64(len(r.s)) + offset
   110		default:
   111			return 0, errors.New("strings: invalid whence")
   112		}
   113		if abs < 0 {
   114			return 0, errors.New("strings: negative position")
   115		}
   116		if abs >= 1<<31 {
   117			return 0, errors.New("strings: position out of range")
   118		}
   119		r.i = int(abs)
   120		return abs, nil
   121	}
   122	
   123	// WriteTo implements the io.WriterTo interface.
   124	func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
   125		r.prevRune = -1
   126		if r.i >= len(r.s) {
   127			return 0, nil
   128		}
   129		s := r.s[r.i:]
   130		m, err := io.WriteString(w, s)
   131		if m > len(s) {
   132			panic("strings.Reader.WriteTo: invalid WriteString count")
   133		}
   134		r.i += m
   135		n = int64(m)
   136		if m != len(s) && err == nil {
   137			err = io.ErrShortWrite
   138		}
   139		return
   140	}
   141	
   142	// NewReader returns a new Reader reading from s.
   143	// It is similar to bytes.NewBufferString but more efficient and read-only.
   144	func NewReader(s string) *Reader { return &Reader{s, 0, -1} }

View as plain text