package pool

import (
	
	
	
)

const WriterBufferSize = 4096

var bufioWriterPool = sync.Pool{
	New: func() interface{} {
		return bufio.NewWriterSize(nil, WriterBufferSize)
	},
}

// Writer is a buffered writer that returns its internal buffer in a pool when
// not in use.
type Writer struct {
	W    io.Writer
	bufw *bufio.Writer
}

func ( *Writer) () {
	if .bufw == nil {
		.bufw = bufioWriterPool.Get().(*bufio.Writer)
		.bufw.Reset(.W)
	}
}

// Write writes the given byte slice to the underlying connection.
//
// Note: Write won't return the write buffer to the pool even if it ends up
// being empty after the write. You must call Flush() to do that.
func ( *Writer) ( []byte) (int, error) {
	if .bufw == nil {
		if len() >= WriterBufferSize {
			return .W.Write()
		}
		.bufw = bufioWriterPool.Get().(*bufio.Writer)
		.bufw.Reset(.W)
	}
	return .bufw.Write()
}

// Size returns the size of the underlying buffer.
func ( *Writer) () int {
	return WriterBufferSize
}

// Available returns the amount buffer space available.
func ( *Writer) () int {
	if .bufw != nil {
		return .bufw.Available()
	}
	return WriterBufferSize
}

// Buffered returns the amount of data buffered.
func ( *Writer) () int {
	if .bufw != nil {
		return .bufw.Buffered()
	}
	return 0
}

// WriteByte writes a single byte.
func ( *Writer) ( byte) error {
	.ensureBuffer()
	return .bufw.WriteByte()
}

// WriteRune writes a single rune, returning the number of bytes written.
func ( *Writer) ( rune) (int, error) {
	.ensureBuffer()
	return .bufw.WriteRune()
}

// WriteString writes a string, returning the number of bytes written.
func ( *Writer) ( string) (int, error) {
	.ensureBuffer()
	return .bufw.WriteString()
}

// Flush flushes the write buffer, if any, and returns it to the pool.
func ( *Writer) () error {
	if .bufw == nil {
		return nil
	}
	if  := .bufw.Flush();  != nil {
		return 
	}
	.bufw.Reset(nil)
	bufioWriterPool.Put(.bufw)
	.bufw = nil
	return nil
}

// Close flushes the underlying writer and closes it if it implements the
// io.Closer interface.
//
// Note: Close() closes the writer even if Flush() fails to avoid leaking system
// resources. If you want to make sure Flush() succeeds, call it first.
func ( *Writer) () error {
	var (
		,  error
	)
	 = .Flush()

	// always close even if flush fails.
	if ,  := .W.(io.Closer);  {
		 = .Close()
	}

	if  != nil {
		return 
	}
	return 
}