Avoid is_constant calls in vectorizable_bswap
[official-gcc.git] / libgo / go / strings / reader.go
blob6c1a5064c0d5ef25dce3a54d8bb7a1f312d7df56
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.
5 package strings
7 import (
8 "errors"
9 "io"
10 "unicode/utf8"
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
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
28 return int(int64(len(r.s)) - r.i)
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)) }
37 func (r *Reader) Read(b []byte) (n int, err error) {
38 if r.i >= int64(len(r.s)) {
39 return 0, io.EOF
41 r.prevRune = -1
42 n = copy(b, r.s[r.i:])
43 r.i += int64(n)
44 return
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")
52 if off >= int64(len(r.s)) {
53 return 0, io.EOF
55 n = copy(b, r.s[off:])
56 if n < len(b) {
57 err = io.EOF
59 return
62 func (r *Reader) ReadByte() (byte, error) {
63 r.prevRune = -1
64 if r.i >= int64(len(r.s)) {
65 return 0, io.EOF
67 b := r.s[r.i]
68 r.i++
69 return b, nil
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")
77 r.i--
78 return nil
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
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
91 ch, size = utf8.DecodeRuneInString(r.s[r.i:])
92 r.i += int64(size)
93 return
96 func (r *Reader) UnreadRune() error {
97 if r.prevRune < 0 {
98 return errors.New("strings.Reader.UnreadRune: previous operation was not ReadRune")
100 r.i = int64(r.prevRune)
101 r.prevRune = -1
102 return nil
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")
119 if abs < 0 {
120 return 0, errors.New("strings.Reader.Seek: negative position")
122 r.i = abs
123 return abs, nil
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
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")
137 r.i += int64(m)
138 n = int64(m)
139 if m != len(s) && err == nil {
140 err = io.ErrShortWrite
142 return
145 // Reset resets the Reader to be reading from s.
146 func (r *Reader) Reset(s string) { *r = Reader{s, 0, -1} }
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} }