// 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 pool

import (
	
	
	
)

type BufReader struct {
	rd io.Reader // reader provided by the client

	buf       []byte
	r, w      int // buf read and write positions
	lastByte  int
	bytesRead int64
	err       error

	available int         // bytes available for reading
	brd       BytesReader // reusable bytes reader
}

func ( int) *BufReader {
	return &BufReader{
		buf:       make([]byte, ),
		available: -1,
	}
}

func ( *BufReader) ( int) *BytesReader {
	if  == -1 {
		 = 0
	}
	 := .buf[.r : .r+]
	.r += 
	.brd.Reset()
	return &.brd
}

func ( *BufReader) ( int) {
	.available = 
}

func ( *BufReader) () int {
	return .available
}

func ( *BufReader) ( int) {
	if .available != -1 {
		.available += 
	}
}

func ( *BufReader) ( io.Reader) {
	.rd = 
	.r, .w = 0, 0
	.err = nil
}

// Buffered returns the number of bytes that can be read from the current buffer.
func ( *BufReader) () int {
	 := .w - .r
	if .available == -1 ||  <= .available {
		return 
	}
	return .available
}

func ( *BufReader) () []byte {
	if .available == -1 {
		return .buf[.r:.w]
	}
	 := .r + .available
	if  > .w {
		 = .w
	}
	return .buf[.r:]
}

func ( *BufReader) () []byte {
	if .available == -1 {
		 := .buf[.r:.w]
		.r = .w
		return 
	}

	 := .r + .available
	if  > .w {
		 = .w
	}
	 := .buf[.r:]
	.r = 
	.changeAvailable(-len())
	return 
}

// fill reads a new chunk into the buffer.
func ( *BufReader) () {
	// 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")
	}
	if .available == 0 {
		.err = io.EOF
		return
	}

	// Read new data: try a limited number of times.
	const  = 100
	for  := ;  > 0; -- {
		,  := .read(.buf[.w:])
		.w += 
		if  != nil {
			.err = 
			return
		}
		if  > 0 {
			return
		}
	}
	.err = io.ErrNoProgress
}

func ( *BufReader) () error {
	 := .err
	.err = nil
	return 
}

func ( *BufReader) ( []byte) ( int,  error) {
	if len() == 0 {
		return 0, .readErr()
	}

	if .available != -1 {
		if .available == 0 {
			return 0, io.EOF
		}
		if len() > .available {
			 = [:.available]
		}
	}

	if .r == .w {
		if .err != nil {
			return 0, .readErr()
		}

		if len() >= len(.buf) {
			// Large read, empty buffer.
			// Read directly into p to avoid copy.
			,  = .read()
			if  > 0 {
				.changeAvailable(-)
				.lastByte = int([-1])
			}
			return , 
		}

		// One read.
		// Do not use b.fill, which will loop.
		.r = 0
		.w = 0
		, .err = .read(.buf)
		if  == 0 {
			return 0, .readErr()
		}
		.w += 
	}

	// copy as much as we can
	 = copy(, .Bytes())
	.r += 
	.changeAvailable(-)
	.lastByte = int(.buf[.r-1])
	return , nil
}

// 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
// ReadBytes or ReadString instead.
// ReadSlice returns err != nil if and only if line does not end in delim.
func ( *BufReader) ( byte) ( []byte,  error) {
	for {
		// Search buffer.
		if  := bytes.IndexByte(.Bytes(), );  >= 0 {
			++
			 = .buf[.r : .r+]
			.r += 
			.changeAvailable(-)
			break
		}

		// Pending error?
		if .err != nil {
			 = .flush()
			 = .readErr()
			break
		}

		 := .Buffered()

		// Out of available.
		if .available != -1 &&  >= .available {
			 = .flush()
			 = io.EOF
			break
		}

		// Buffer full?
		if  >= len(.buf) {
			 = .flush()
			 = bufio.ErrBufferFull
			break
		}

		.fill() // buffer is not full
	}

	// Handle last byte, if any.
	if  := len() - 1;  >= 0 {
		.lastByte = int([])
	}

	return , 
}

func ( *BufReader) ( func(byte) bool) ( []byte,  error) {
	for {
		for ,  := range .Bytes() {
			if !() {
				--
				 = .buf[.r : .r+] //nolint
				.r += 
				.changeAvailable(-)
				break
			}
		}

		// Pending error?
		if .err != nil {
			 = .flush()
			 = .readErr()
			break
		}

		 := .Buffered()

		// Out of available.
		if .available != -1 &&  >= .available {
			 = .flush()
			 = io.EOF
			break
		}

		// Buffer full?
		if  >= len(.buf) {
			 = .flush()
			 = bufio.ErrBufferFull
			break
		}

		.fill() // buffer is not full
	}

	// Handle last byte, if any.
	if  := len() - 1;  >= 0 {
		.lastByte = int([])
	}

	return , 
}

func ( *BufReader) () (byte, error) {
	if .available == 0 {
		return 0, io.EOF
	}
	for .r == .w {
		if .err != nil {
			return 0, .readErr()
		}
		.fill() // buffer is empty
	}
	 := .buf[.r]
	.r++
	.lastByte = int()
	.changeAvailable(-1)
	return , nil
}

func ( *BufReader) () error {
	if .lastByte < 0 || .r == 0 && .w > 0 {
		return bufio.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
	.changeAvailable(+1)
	return nil
}

// 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.BufReader.
func ( *BufReader) ( int) ( int,  error) {
	if  < 0 {
		return 0, bufio.ErrNegativeCount
	}
	if  == 0 {
		return
	}
	 := 
	for {
		 := .Buffered()
		if  == 0 {
			.fill()
			 = .Buffered()
		}
		if  >  {
			 = 
		}
		.r += 
		.changeAvailable(-)
		 -= 
		if  == 0 {
			return , nil
		}
		if .err != nil {
			return  - , .readErr()
		}
	}
}

func ( *BufReader) ( int) ( []byte,  error) {
	if  < 0 {
		return nil, bufio.ErrNegativeCount
	}
	if  == 0 {
		return
	}

	 := 
	if .available != -1 &&  > .available {
		 = .available
	}

	for {
		 := .Buffered()

		if  >=  {
			 = .buf[.r : .r+]
			.r += 
			.changeAvailable(-)
			if  >  {
				 = io.EOF
			}
			break
		}

		// Pending error?
		if .err != nil {
			 = .flush()
			 = .readErr()
			break
		}

		// Buffer full?
		if  >= len(.buf) {
			 = .flush()
			 = bufio.ErrBufferFull
			break
		}

		.fill() // buffer is not full
	}

	// Handle last byte, if any.
	if  := len() - 1;  >= 0 {
		.lastByte = int([])
	}

	return , 
}

func ( *BufReader) () ([]byte, error) {
	if .available == -1 {
		panic("not reached")
	}
	 := make([]byte, .available)
	,  := io.ReadFull(, )
	return , 
}

func ( *BufReader) () ([]byte, error) {
	if .available == -1 {
		panic("not reached")
	}
	if .available <= len(.buf) {
		return .ReadN(.available)
	}
	return .ReadFull()
}

func ( *BufReader) ( []byte) (int, error) {
	,  := .rd.Read()
	.bytesRead += int64()
	return , 
}