Source File
bufio.go
Belonging Package
bufio
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer
// object, creating another object (Reader or Writer) that also implements
// the interface but provides buffering and some help for textual I/O.
package bufio
import (
)
const (
defaultBufSize = 4096
)
var (
ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
ErrBufferFull = errors.New("bufio: buffer full")
ErrNegativeCount = errors.New("bufio: negative count")
)
// Buffered input.
// Reader implements buffering for an io.Reader object.
type Reader struct {
buf []byte
rd io.Reader // reader provided by the client
r, w int // buf read and write positions
err error
lastByte int // last byte read for UnreadByte; -1 means invalid
lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}
const minReadBufferSize = 16
const maxConsecutiveEmptyReads = 100
// NewReaderSize returns a new [Reader] whose buffer has at least the specified
// size. If the argument io.Reader is already a [Reader] with large enough
// size, it returns the underlying [Reader].
func ( io.Reader, int) *Reader {
// Is it already a Reader?
, := .(*Reader)
if && len(.buf) >= {
return
}
:= new(Reader)
.reset(make([]byte, max(, minReadBufferSize)), )
return
}
// NewReader returns a new [Reader] whose buffer has the default size.
func ( io.Reader) *Reader {
return NewReaderSize(, defaultBufSize)
}
// Size returns the size of the underlying buffer in bytes.
func ( *Reader) () int { return len(.buf) }
// Reset discards any buffered data, resets all state, and switches
// the buffered reader to read from r.
// Calling Reset on the zero value of [Reader] initializes the internal buffer
// to the default size.
// Calling b.Reset(b) (that is, resetting a [Reader] to itself) does nothing.
func ( *Reader) ( io.Reader) {
// If a Reader r is passed to NewReader, NewReader will return r.
// Different layers of code may do that, and then later pass r
// to Reset. Avoid infinite recursion in that case.
if == {
return
}
if .buf == nil {
.buf = make([]byte, defaultBufSize)
}
.reset(.buf, )
}
func ( *Reader) ( []byte, io.Reader) {
* = Reader{
buf: ,
rd: ,
lastByte: -1,
lastRuneSize: -1,
}
}
var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
// fill reads a new chunk into the buffer.
func ( *Reader) () {
// Slide existing data to beginning.
if .r > 0 {
copy(.buf, .buf[.r:.w])
.w -= .r
.r = 0
}
if .w >= len(.buf) {
panic("bufio: tried to fill full buffer")
}
// Read new data: try a limited number of times.
for := maxConsecutiveEmptyReads; > 0; -- {
, := .rd.Read(.buf[.w:])
if < 0 {
panic(errNegativeRead)
}
.w +=
if != nil {
.err =
return
}
if > 0 {
return
}
}
.err = io.ErrNoProgress
}
func ( *Reader) () error {
:= .err
.err = nil
return
}
// Peek returns the next n bytes without advancing the reader. The bytes stop
// being valid at the next read call. If Peek returns fewer than n bytes, it
// also returns an error explaining why the read is short. The error is
// [ErrBufferFull] if n is larger than b's buffer size.
//
// Calling Peek prevents a [Reader.UnreadByte] or [Reader.UnreadRune] call from succeeding
// until the next read operation.
func ( *Reader) ( int) ([]byte, error) {
if < 0 {
return nil, ErrNegativeCount
}
.lastByte = -1
.lastRuneSize = -1
for .w-.r < && .w-.r < len(.buf) && .err == nil {
.fill() // b.w-b.r < len(b.buf) => buffer is not full
}
if > len(.buf) {
return .buf[.r:.w], ErrBufferFull
}
// 0 <= n <= len(b.buf)
var error
if := .w - .r; < {
// not enough data in buffer
=
= .readErr()
if == nil {
= ErrBufferFull
}
}
return .buf[.r : .r+],
}
// Discard skips the next n bytes, returning the number of bytes discarded.
//
// If Discard skips fewer than n bytes, it also returns an error.
// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
// reading from the underlying io.Reader.
func ( *Reader) ( int) ( int, error) {
if < 0 {
return 0, ErrNegativeCount
}
if == 0 {
return
}
.lastByte = -1
.lastRuneSize = -1
:=
for {
:= .Buffered()
if == 0 {
.fill()
= .Buffered()
}
if > {
=
}
.r +=
-=
if == 0 {
return , nil
}
if .err != nil {
return - , .readErr()
}
}
}
// Read reads data into p.
// It returns the number of bytes read into p.
// The bytes are taken from at most one Read on the underlying [Reader],
// hence n may be less than len(p).
// To read exactly len(p) bytes, use io.ReadFull(b, p).
// If the underlying [Reader] can return a non-zero count with io.EOF,
// then this Read method can do so as well; see the [io.Reader] docs.
func ( *Reader) ( []byte) ( int, error) {
= len()
if == 0 {
if .Buffered() > 0 {
return 0, nil
}
return 0, .readErr()
}
if .r == .w {
if .err != nil {
return 0, .readErr()
}
if len() >= len(.buf) {
// Large read, empty buffer.
// Read directly into p to avoid copy.
, .err = .rd.Read()
if < 0 {
panic(errNegativeRead)
}
if > 0 {
.lastByte = int([-1])
.lastRuneSize = -1
}
return , .readErr()
}
// One read.
// Do not use b.fill, which will loop.
.r = 0
.w = 0
, .err = .rd.Read(.buf)
if < 0 {
panic(errNegativeRead)
}
if == 0 {
return 0, .readErr()
}
.w +=
}
// copy as much as we can
// Note: if the slice panics here, it is probably because
// the underlying reader returned a bad count. See issue 49795.
= copy(, .buf[.r:.w])
.r +=
.lastByte = int(.buf[.r-1])
.lastRuneSize = -1
return , nil
}
// ReadByte reads and returns a single byte.
// If no byte is available, returns an error.
func ( *Reader) () (byte, error) {
.lastRuneSize = -1
for .r == .w {
if .err != nil {
return 0, .readErr()
}
.fill() // buffer is empty
}
:= .buf[.r]
.r++
.lastByte = int()
return , nil
}
// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
//
// UnreadByte returns an error if the most recent method called on the
// [Reader] was not a read operation. Notably, [Reader.Peek], [Reader.Discard], and [Reader.WriteTo] are not
// considered read operations.
func ( *Reader) () error {
if .lastByte < 0 || .r == 0 && .w > 0 {
return ErrInvalidUnreadByte
}
// b.r > 0 || b.w == 0
if .r > 0 {
.r--
} else {
// b.r == 0 && b.w == 0
.w = 1
}
.buf[.r] = byte(.lastByte)
.lastByte = -1
.lastRuneSize = -1
return nil
}
// ReadRune reads a single UTF-8 encoded Unicode character and returns the
// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
func ( *Reader) () ( rune, int, error) {
for .r+utf8.UTFMax > .w && !utf8.FullRune(.buf[.r:.w]) && .err == nil && .w-.r < len(.buf) {
.fill() // b.w-b.r < len(buf) => buffer is not full
}
.lastRuneSize = -1
if .r == .w {
return 0, 0, .readErr()
}
, = rune(.buf[.r]), 1
if >= utf8.RuneSelf {
, = utf8.DecodeRune(.buf[.r:.w])
}
.r +=
.lastByte = int(.buf[.r-1])
.lastRuneSize =
return , , nil
}
// UnreadRune unreads the last rune. If the most recent method called on
// the [Reader] was not a [Reader.ReadRune], [Reader.UnreadRune] returns an error. (In this
// regard it is stricter than [Reader.UnreadByte], which will unread the last byte
// from any read operation.)
func ( *Reader) () error {
if .lastRuneSize < 0 || .r < .lastRuneSize {
return ErrInvalidUnreadRune
}
.r -= .lastRuneSize
.lastByte = -1
.lastRuneSize = -1
return nil
}
// Buffered returns the number of bytes that can be read from the current buffer.
func ( *Reader) () int { return .w - .r }
// ReadSlice reads until the first occurrence of delim in the input,
// returning a slice pointing at the bytes in the buffer.
// The bytes stop being valid at the next read.
// If ReadSlice encounters an error before finding a delimiter,
// it returns all the data in the buffer and the error itself (often io.EOF).
// ReadSlice fails with error [ErrBufferFull] if the buffer fills without a delim.
// Because the data returned from ReadSlice will be overwritten
// by the next I/O operation, most clients should use
// [Reader.ReadBytes] or ReadString instead.
// ReadSlice returns err != nil if and only if line does not end in delim.
func ( *Reader) ( byte) ( []byte, error) {
:= 0 // search start index
for {
// Search buffer.
if := bytes.IndexByte(.buf[.r+:.w], ); >= 0 {
+=
= .buf[.r : .r++1]
.r += + 1
break
}
// Pending error?
if .err != nil {
= .buf[.r:.w]
.r = .w
= .readErr()
break
}
// Buffer full?
if .Buffered() >= len(.buf) {
.r = .w
= .buf
= ErrBufferFull
break
}
= .w - .r // do not rescan area we scanned before
.fill() // buffer is not full
}
// Handle last byte, if any.
if := len() - 1; >= 0 {
.lastByte = int([])
.lastRuneSize = -1
}
return
}
// ReadLine is a low-level line-reading primitive. Most callers should use
// [Reader.ReadBytes]('\n') or [Reader.ReadString]('\n') instead or use a [Scanner].
//
// ReadLine tries to return a single line, not including the end-of-line bytes.
// If the line was too long for the buffer then isPrefix is set and the
// beginning of the line is returned. The rest of the line will be returned
// from future calls. isPrefix will be false when returning the last fragment
// of the line. The returned buffer is only valid until the next call to
// ReadLine. ReadLine either returns a non-nil line or it returns an error,
// never both.
//
// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
// No indication or error is given if the input ends without a final line end.
// Calling [Reader.UnreadByte] after ReadLine will always unread the last byte read
// (possibly a character belonging to the line end) even if that byte is not
// part of the line returned by ReadLine.
func ( *Reader) () ( []byte, bool, error) {
, = .ReadSlice('\n')
if == ErrBufferFull {
// Handle the case where "\r\n" straddles the buffer.
if len() > 0 && [len()-1] == '\r' {
// Put the '\r' back on buf and drop it from line.
// Let the next call to ReadLine check for "\r\n".
if .r == 0 {
// should be unreachable
panic("bufio: tried to rewind past start of buffer")
}
.r--
= [:len()-1]
}
return , true, nil
}
if len() == 0 {
if != nil {
= nil
}
return
}
= nil
if [len()-1] == '\n' {
:= 1
if len() > 1 && [len()-2] == '\r' {
= 2
}
= [:len()-]
}
return
}
// collectFragments reads until the first occurrence of delim in the input. It
// returns (slice of full buffers, remaining bytes before delim, total number
// of bytes in the combined first two elements, error).
// The complete result is equal to
// `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a
// length of `totalLen`. The result is structured in this way to allow callers
// to minimize allocations and copies.
func ( *Reader) ( byte) ( [][]byte, []byte, int, error) {
var []byte
// Use ReadSlice to look for delim, accumulating full buffers.
for {
var error
, = .ReadSlice()
if == nil { // got final fragment
break
}
if != ErrBufferFull { // unexpected error
=
break
}
// Make a copy of the buffer.
:= bytes.Clone()
= append(, )
+= len()
}
+= len()
return , , ,
}
// ReadBytes reads until the first occurrence of delim in the input,
// returning a slice containing the data up to and including the delimiter.
// If ReadBytes encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often io.EOF).
// ReadBytes returns err != nil if and only if the returned data does not end in
// delim.
// For simple uses, a Scanner may be more convenient.
func ( *Reader) ( byte) ([]byte, error) {
, , , := .collectFragments()
// Allocate new buffer to hold the full pieces and the fragment.
:= make([]byte, )
= 0
// Copy full pieces and fragment in.
for := range {
+= copy([:], [])
}
copy([:], )
return ,
}
// ReadString reads until the first occurrence of delim in the input,
// returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often io.EOF).
// ReadString returns err != nil if and only if the returned data does not end in
// delim.
// For simple uses, a Scanner may be more convenient.
func ( *Reader) ( byte) (string, error) {
, , , := .collectFragments()
// Allocate new buffer to hold the full pieces and the fragment.
var strings.Builder
.Grow()
// Copy full pieces and fragment in.
for , := range {
.Write()
}
.Write()
return .String(),
}
// WriteTo implements io.WriterTo.
// This may make multiple calls to the [Reader.Read] method of the underlying [Reader].
// If the underlying reader supports the [Reader.WriteTo] method,
// this calls the underlying [Reader.WriteTo] without buffering.
func ( *Reader) ( io.Writer) ( int64, error) {
.lastByte = -1
.lastRuneSize = -1
, = .writeBuf()
if != nil {
return
}
if , := .rd.(io.WriterTo); {
, := .WriteTo()
+=
return ,
}
if , := .(io.ReaderFrom); {
, := .ReadFrom(.rd)
+=
return ,
}
if .w-.r < len(.buf) {
.fill() // buffer not full
}
for .r < .w {
// b.r < b.w => buffer is not empty
, := .writeBuf()
+=
if != nil {
return ,
}
.fill() // buffer is empty
}
if .err == io.EOF {
.err = nil
}
return , .readErr()
}
var errNegativeWrite = errors.New("bufio: writer returned negative count from Write")
// writeBuf writes the [Reader]'s buffer to the writer.
func ( *Reader) ( io.Writer) (int64, error) {
, := .Write(.buf[.r:.w])
if < 0 {
panic(errNegativeWrite)
}
.r +=
return int64(),
}
// buffered output
// Writer implements buffering for an [io.Writer] object.
// If an error occurs writing to a [Writer], no more data will be
// accepted and all subsequent writes, and [Writer.Flush], will return the error.
// After all data has been written, the client should call the
// [Writer.Flush] method to guarantee all data has been forwarded to
// the underlying [io.Writer].
type Writer struct {
err error
buf []byte
n int
wr io.Writer
}
// NewWriterSize returns a new [Writer] whose buffer has at least the specified
// size. If the argument io.Writer is already a [Writer] with large enough
// size, it returns the underlying [Writer].
func ( io.Writer, int) *Writer {
// Is it already a Writer?
, := .(*Writer)
if && len(.buf) >= {
return
}
if <= 0 {
= defaultBufSize
}
return &Writer{
buf: make([]byte, ),
wr: ,
}
}
// NewWriter returns a new [Writer] whose buffer has the default size.
// If the argument io.Writer is already a [Writer] with large enough buffer size,
// it returns the underlying [Writer].
func ( io.Writer) *Writer {
return NewWriterSize(, defaultBufSize)
}
// Size returns the size of the underlying buffer in bytes.
func ( *Writer) () int { return len(.buf) }
// Reset discards any unflushed buffered data, clears any error, and
// resets b to write its output to w.
// Calling Reset on the zero value of [Writer] initializes the internal buffer
// to the default size.
// Calling w.Reset(w) (that is, resetting a [Writer] to itself) does nothing.
func ( *Writer) ( io.Writer) {
// If a Writer w is passed to NewWriter, NewWriter will return w.
// Different layers of code may do that, and then later pass w
// to Reset. Avoid infinite recursion in that case.
if == {
return
}
if .buf == nil {
.buf = make([]byte, defaultBufSize)
}
.err = nil
.n = 0
.wr =
}
// Flush writes any buffered data to the underlying [io.Writer].
func ( *Writer) () error {
if .err != nil {
return .err
}
if .n == 0 {
return nil
}
, := .wr.Write(.buf[0:.n])
if < .n && == nil {
= io.ErrShortWrite
}
if != nil {
if > 0 && < .n {
copy(.buf[0:.n-], .buf[:.n])
}
.n -=
.err =
return
}
.n = 0
return nil
}
// Available returns how many bytes are unused in the buffer.
func ( *Writer) () int { return len(.buf) - .n }
// AvailableBuffer returns an empty buffer with b.Available() capacity.
// This buffer is intended to be appended to and
// passed to an immediately succeeding [Writer.Write] call.
// The buffer is only valid until the next write operation on b.
func ( *Writer) () []byte {
return .buf[.n:][:0]
}
// Buffered returns the number of bytes that have been written into the current buffer.
func ( *Writer) () int { return .n }
// Write writes the contents of p into the buffer.
// It returns the number of bytes written.
// If nn < len(p), it also returns an error explaining
// why the write is short.
func ( *Writer) ( []byte) ( int, error) {
for len() > .Available() && .err == nil {
var int
if .Buffered() == 0 {
// Large write, empty buffer.
// Write directly from p to avoid copy.
, .err = .wr.Write()
} else {
= copy(.buf[.n:], )
.n +=
.Flush()
}
+=
= [:]
}
if .err != nil {
return , .err
}
:= copy(.buf[.n:], )
.n +=
+=
return , nil
}
// WriteByte writes a single byte.
func ( *Writer) ( byte) error {
if .err != nil {
return .err
}
if .Available() <= 0 && .Flush() != nil {
return .err
}
.buf[.n] =
.n++
return nil
}
// WriteRune writes a single Unicode code point, returning
// the number of bytes written and any error.
func ( *Writer) ( rune) ( int, error) {
// Compare as uint32 to correctly handle negative runes.
if uint32() < utf8.RuneSelf {
= .WriteByte(byte())
if != nil {
return 0,
}
return 1, nil
}
if .err != nil {
return 0, .err
}
:= .Available()
if < utf8.UTFMax {
if .Flush(); .err != nil {
return 0, .err
}
= .Available()
if < utf8.UTFMax {
// Can only happen if buffer is silly small.
return .WriteString(string())
}
}
= utf8.EncodeRune(.buf[.n:], )
.n +=
return , nil
}
// WriteString writes a string.
// It returns the number of bytes written.
// If the count is less than len(s), it also returns an error explaining
// why the write is short.
func ( *Writer) ( string) (int, error) {
var io.StringWriter
:= true
:= 0
for len() > .Available() && .err == nil {
var int
if .Buffered() == 0 && == nil && {
// Check at most once whether b.wr is a StringWriter.
, = .wr.(io.StringWriter)
}
if .Buffered() == 0 && {
// Large write, empty buffer, and the underlying writer supports
// WriteString: forward the write to the underlying StringWriter.
// This avoids an extra copy.
, .err = .WriteString()
} else {
= copy(.buf[.n:], )
.n +=
.Flush()
}
+=
= [:]
}
if .err != nil {
return , .err
}
:= copy(.buf[.n:], )
.n +=
+=
return , nil
}
// ReadFrom implements [io.ReaderFrom]. If the underlying writer
// supports the ReadFrom method, this calls the underlying ReadFrom.
// If there is buffered data and an underlying ReadFrom, this fills
// the buffer and writes it before calling ReadFrom.
func ( *Writer) ( io.Reader) ( int64, error) {
if .err != nil {
return 0, .err
}
, := .wr.(io.ReaderFrom)
var int
for {
if .Available() == 0 {
if := .Flush(); != nil {
return ,
}
}
if && .Buffered() == 0 {
, := .ReadFrom()
.err =
+=
return ,
}
:= 0
for < maxConsecutiveEmptyReads {
, = .Read(.buf[.n:])
if != 0 || != nil {
break
}
++
}
if == maxConsecutiveEmptyReads {
return , io.ErrNoProgress
}
.n +=
+= int64()
if != nil {
break
}
}
if == io.EOF {
// If we filled the buffer exactly, flush preemptively.
if .Available() == 0 {
= .Flush()
} else {
= nil
}
}
return ,
}
// buffered input and output
// ReadWriter stores pointers to a [Reader] and a [Writer].
// It implements [io.ReadWriter].
type ReadWriter struct {
*Reader
*Writer
}
// NewReadWriter allocates a new [ReadWriter] that dispatches to r and w.
func ( *Reader, *Writer) *ReadWriter {
return &ReadWriter{, }
}
The pages are generated with Golds v0.7.0-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |