The Go Programming Language

Source file src/pkg/strings/reader.go

     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.
     4	
     5	package strings
     6	
     7	import (
     8		"os"
     9		"utf8"
    10	)
    11	
    12	// A Reader implements the io.Reader, io.ByteScanner, and
    13	// io.RuneScanner interfaces by reading from a string.
    14	type Reader struct {
    15		s        string
    16		i        int // current reading index
    17		prevRune int // index of previous rune; or < 0
    18	}
    19	
    20	// Len returns the number of bytes of the unread portion of the
    21	// string.
    22	func (r *Reader) Len() int {
    23		return len(r.s) - r.i
    24	}
    25	
    26	func (r *Reader) Read(b []byte) (n int, err os.Error) {
    27		if r.i >= len(r.s) {
    28			return 0, os.EOF
    29		}
    30		n = copy(b, r.s[r.i:])
    31		r.i += n
    32		r.prevRune = -1
    33		return
    34	}
    35	
    36	func (r *Reader) ReadByte() (b byte, err os.Error) {
    37		if r.i >= len(r.s) {
    38			return 0, os.EOF
    39		}
    40		b = r.s[r.i]
    41		r.i++
    42		r.prevRune = -1
    43		return
    44	}
    45	
    46	// UnreadByte moves the reading position back by one byte.
    47	// It is an error to call UnreadByte if nothing has been
    48	// read yet.
    49	func (r *Reader) UnreadByte() os.Error {
    50		if r.i <= 0 {
    51			return os.NewError("strings.Reader: at beginning of string")
    52		}
    53		r.i--
    54		r.prevRune = -1
    55		return nil
    56	}
    57	
    58	// ReadRune reads and returns the next UTF-8-encoded
    59	// Unicode code point from the buffer.
    60	// If no bytes are available, the error returned is os.EOF.
    61	// If the bytes are an erroneous UTF-8 encoding, it
    62	// consumes one byte and returns U+FFFD, 1.
    63	func (r *Reader) ReadRune() (rune int, size int, err os.Error) {
    64		if r.i >= len(r.s) {
    65			return 0, 0, os.EOF
    66		}
    67		r.prevRune = r.i
    68		if c := r.s[r.i]; c < utf8.RuneSelf {
    69			r.i++
    70			return int(c), 1, nil
    71		}
    72		rune, size = utf8.DecodeRuneInString(r.s[r.i:])
    73		r.i += size
    74		return
    75	}
    76	
    77	// UnreadRune causes the next call to ReadRune to return the same rune
    78	// as the previous call to ReadRune.
    79	// The last method called on r must have been ReadRune.
    80	func (r *Reader) UnreadRune() os.Error {
    81		if r.prevRune < 0 {
    82			return os.NewError("strings.Reader: previous operation was not ReadRune")
    83		}
    84		r.i = r.prevRune
    85		r.prevRune = -1
    86		return nil
    87	}
    88	
    89	// NewReader returns a new Reader reading from s.
    90	// It is similar to bytes.NewBufferString but more efficient and read-only.
    91	func NewReader(s string) *Reader { return &Reader{s, 0, -1} }

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.