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