...

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

View as plain text