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 bufioimport ()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.// A new Reader is created by calling [NewReader] or [NewReaderSize];// alternatively the zero value of a Reader may be used after calling [Reset]// on it.type Reader struct {buf []byterd io.Reader // reader provided by the clientr, w int // buf read and write positionserr errorlastByte int // last byte read for UnreadByte; -1 means invalidlastRuneSize int // size of last rune read for UnreadRune; -1 means invalid}const minReadBufferSize = 16const 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 = nilreturn}// Peek returns the next n bytes without advancing the reader. The bytes stop// being valid at the next read call. If necessary, Peek will read more bytes// into the buffer in order to make n bytes available. 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 = -1for .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 errorif := .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 = -1return , nil}// ReadByte reads and returns a single byte.// If no byte is available, returns an error.func ( *Reader) () (byte, error) {.lastRuneSize = -1for .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 == 0if .r > 0 {.r--} else {// b.r == 0 && b.w == 0.w = 1}.buf[.r] = byte(.lastByte).lastByte = -1.lastRuneSize = -1return 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 = -1if .r == .w {return 0, 0, .readErr()}, = 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 = -1return 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 indexfor {// Search buffer.if := bytes.IndexByte(.buf[.r+:.w], ); >= 0 {+== .buf[.r : .r++1].r += + 1break}// Pending error?if .err != nil {= .buf[.r:.w].r = .w= .readErr()break}// Buffer full?if .Buffered() >= len(.buf) {.r = .w= .buf= ErrBufferFullbreak}= .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 unreachablepanic("bufio: tried to rewind past start of buffer")}.r--= [:len()-1]}return , true, nil}if len() == 0 {if != nil {= nil}return}= nilif [len()-1] == '\n' {:= 1if 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 fragmentbreak}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 = -1if .r < .w {, = .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 errorbuf []byten intwr 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 = 0return 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 intif .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:= 0for len() > .Available() && .err == nil {var intif .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 intfor {if .Available() == 0 {if := .Flush(); != nil {return ,}}if && .Buffered() == 0 {, := .ReadFrom().err =+=return ,}:= 0for < 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.8.4. (GOOS=linux GOARCH=amd64)