reader.mx raw

   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  // The zero value for Reader operates like a Reader of an empty slice.
  18  type Reader struct {
  19  	s        []byte
  20  	i        int64 // current reading index
  21  	prevRune int   // index of previous rune; or < 0
  22  }
  23  
  24  // Len returns the number of bytes of the unread portion of the
  25  // slice.
  26  func (r *Reader) Len() int {
  27  	if r.i >= int64(len(r.s)) {
  28  		return 0
  29  	}
  30  	return int(int64(len(r.s)) - r.i)
  31  }
  32  
  33  // Size returns the original length of the underlying byte slice.
  34  // Size is the number of bytes available for reading via [Reader.ReadAt].
  35  // The result is unaffected by any method calls except [Reader.Reset].
  36  func (r *Reader) Size() int64 { return int64(len(r.s)) }
  37  
  38  // Read implements the [io.Reader] interface.
  39  func (r *Reader) Read(b []byte) (n int, err error) {
  40  	if r.i >= int64(len(r.s)) {
  41  		return 0, io.EOF
  42  	}
  43  	r.prevRune = -1
  44  	n = copy(b, r.s[r.i:])
  45  	r.i += int64(n)
  46  	return
  47  }
  48  
  49  // ReadAt implements the [io.ReaderAt] interface.
  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("bytes.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  // ReadByte implements the [io.ByteReader] interface.
  66  func (r *Reader) ReadByte() (byte, 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 b, nil
  74  }
  75  
  76  // UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface.
  77  func (r *Reader) UnreadByte() error {
  78  	if r.i <= 0 {
  79  		return errors.New("bytes.Reader.UnreadByte: at beginning of slice")
  80  	}
  81  	r.prevRune = -1
  82  	r.i--
  83  	return nil
  84  }
  85  
  86  // ReadRune implements the [io.RuneReader] interface.
  87  func (r *Reader) ReadRune() (ch rune, size int, err error) {
  88  	if r.i >= int64(len(r.s)) {
  89  		r.prevRune = -1
  90  		return 0, 0, io.EOF
  91  	}
  92  	r.prevRune = int(r.i)
  93  	if c := r.s[r.i]; c < utf8.RuneSelf {
  94  		r.i++
  95  		return rune(c), 1, nil
  96  	}
  97  	ch, size = utf8.DecodeRune(r.s[r.i:])
  98  	r.i += int64(size)
  99  	return
 100  }
 101  
 102  // UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface.
 103  func (r *Reader) UnreadRune() error {
 104  	if r.i <= 0 {
 105  		return errors.New("bytes.Reader.UnreadRune: at beginning of slice")
 106  	}
 107  	if r.prevRune < 0 {
 108  		return errors.New("bytes.Reader.UnreadRune: previous operation was not ReadRune")
 109  	}
 110  	r.i = int64(r.prevRune)
 111  	r.prevRune = -1
 112  	return nil
 113  }
 114  
 115  // Seek implements the [io.Seeker] interface.
 116  func (r *Reader) Seek(offset int64, whence int) (int64, error) {
 117  	r.prevRune = -1
 118  	var abs int64
 119  	switch whence {
 120  	case io.SeekStart:
 121  		abs = offset
 122  	case io.SeekCurrent:
 123  		abs = r.i + offset
 124  	case io.SeekEnd:
 125  		abs = int64(len(r.s)) + offset
 126  	default:
 127  		return 0, errors.New("bytes.Reader.Seek: invalid whence")
 128  	}
 129  	if abs < 0 {
 130  		return 0, errors.New("bytes.Reader.Seek: negative position")
 131  	}
 132  	r.i = abs
 133  	return abs, nil
 134  }
 135  
 136  // WriteTo implements the [io.WriterTo] interface.
 137  func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
 138  	r.prevRune = -1
 139  	if r.i >= int64(len(r.s)) {
 140  		return 0, nil
 141  	}
 142  	b := r.s[r.i:]
 143  	m, err := w.Write(b)
 144  	if m > len(b) {
 145  		panic("bytes.Reader.WriteTo: invalid Write count")
 146  	}
 147  	r.i += int64(m)
 148  	n = int64(m)
 149  	if m != len(b) && err == nil {
 150  		err = io.ErrShortWrite
 151  	}
 152  	return
 153  }
 154  
 155  // Reset resets the [Reader] to be reading from b.
 156  func (r *Reader) Reset(b []byte) { *r = Reader{b, 0, -1} }
 157  
 158  // NewReader returns a new [Reader] reading from b.
 159  func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }
 160