github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/bytes/reader.go (about) 1 // Copyright 2012 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 bytes 6 7 import ( 8 "errors" 9 "io" 10 "unicode/utf8" 11 ) 12 13 // A Reader implements the io.Reader, io.ReaderAt, io.WriterTo, io.Seeker, 14 // io.ByteScanner, and io.RuneScanner interfaces by reading from 15 // a byte slice. 16 // Unlike a Buffer, a Reader is read-only and supports seeking. 17 type Reader struct { 18 s []byte 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 // slice. 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 byte slice. 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 func (r *Reader) Read(b []byte) (n int, err error) { 39 if len(b) == 0 { 40 return 0, nil 41 } 42 if r.i >= int64(len(r.s)) { 43 return 0, io.EOF 44 } 45 r.prevRune = -1 46 n = copy(b, r.s[r.i:]) 47 r.i += int64(n) 48 return 49 } 50 51 func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) { 52 // cannot modify state - see io.ReaderAt 53 if off < 0 { 54 return 0, errors.New("bytes.Reader.ReadAt: negative offset") 55 } 56 if off >= int64(len(r.s)) { 57 return 0, io.EOF 58 } 59 n = copy(b, r.s[off:]) 60 if n < len(b) { 61 err = io.EOF 62 } 63 return 64 } 65 66 func (r *Reader) ReadByte() (b byte, err 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 74 } 75 76 func (r *Reader) UnreadByte() error { 77 r.prevRune = -1 78 if r.i <= 0 { 79 return errors.New("bytes.Reader.UnreadByte: at beginning of slice") 80 } 81 r.i-- 82 return nil 83 } 84 85 func (r *Reader) ReadRune() (ch rune, size int, err error) { 86 if r.i >= int64(len(r.s)) { 87 r.prevRune = -1 88 return 0, 0, io.EOF 89 } 90 r.prevRune = int(r.i) 91 if c := r.s[r.i]; c < utf8.RuneSelf { 92 r.i++ 93 return rune(c), 1, nil 94 } 95 ch, size = utf8.DecodeRune(r.s[r.i:]) 96 r.i += int64(size) 97 return 98 } 99 100 func (r *Reader) UnreadRune() error { 101 if r.prevRune < 0 { 102 return errors.New("bytes.Reader.UnreadRune: previous operation was not ReadRune") 103 } 104 r.i = int64(r.prevRune) 105 r.prevRune = -1 106 return nil 107 } 108 109 // Seek implements the io.Seeker interface. 110 func (r *Reader) Seek(offset int64, whence int) (int64, error) { 111 r.prevRune = -1 112 var abs int64 113 switch whence { 114 case 0: 115 abs = offset 116 case 1: 117 abs = int64(r.i) + offset 118 case 2: 119 abs = int64(len(r.s)) + offset 120 default: 121 return 0, errors.New("bytes.Reader.Seek: invalid whence") 122 } 123 if abs < 0 { 124 return 0, errors.New("bytes.Reader.Seek: negative position") 125 } 126 r.i = abs 127 return abs, nil 128 } 129 130 // WriteTo implements the io.WriterTo interface. 131 func (r *Reader) WriteTo(w io.Writer) (n int64, err error) { 132 r.prevRune = -1 133 if r.i >= int64(len(r.s)) { 134 return 0, nil 135 } 136 b := r.s[r.i:] 137 m, err := w.Write(b) 138 if m > len(b) { 139 panic("bytes.Reader.WriteTo: invalid Write count") 140 } 141 r.i += int64(m) 142 n = int64(m) 143 if m != len(b) && err == nil { 144 err = io.ErrShortWrite 145 } 146 return 147 } 148 149 // NewReader returns a new Reader reading from b. 150 func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }