func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
	b.mtx.Lock()
	defer b.mtx.Unlock()
	b.waitUntilNoChunkedWrite()
	if b.buffered() == 0 {
		if w, ok := b.wr.(io.ReaderFrom); ok {
			return w.ReadFrom(r)
		}
	}
	var m int
	for {
		if b.available() == 0 {
			if err1 := b.flush(1); err1 != nil {
				return n, err1
			}
		}
		nr := 0
		for nr < maxConsecutiveEmptyReads {
			m, err = r.Read(b.buf[b.n:])
			if m != 0 || err != nil {
				break
			}
			nr++
		}
		if nr == maxConsecutiveEmptyReads {
			b.maybeAutoFlush()
			return n, io.ErrNoProgress
		}
		b.n += m
		n += int64(m)
		if err != nil {
			break
		}
		if !b.inChunkedWriteMode {
			b.inChunkedWriteMode = true
			defer b.endChunkedWrite()
		}
	}
	if err == io.EOF {
		err = nil
	}
	if err != nil {
		b.maybeAutoFlush()
	}
	return n, err
}
ReadFrom implements io.ReaderFrom.
package concurrent
import (
	"bufio"
	"fmt"
	"io"
	"sync"
	"unicode/utf8"
)
const defaultBufSize = 4096
const maxConsecutiveEmptyReads = 100
type Writer struct {
	mtx *sync.Mutex
	err error
	buf []byte
	n   int
	wr  io.Writer
	inChunkedWriteMode bool
	noChunkedWrite *sync.Cond
	nFlush int
	notFlushing *sync.Cond
	chunkedWriter *sync.Cond
	flushAt int
}
func NewWriterSize(w io.Writer, size int) *Writer {
	b, ok := w.(*Writer)
	if ok && len(b.buf) >= size {
		return b
	}
	if size <= 0 {
		size = defaultBufSize
	}
	if size < utf8.UTFMax {
		size = utf8.UTFMax
	}
	m := new(sync.Mutex)
	return &Writer{
		mtx:            m,
		buf:            make([]byte, size),
		wr:             w,
		noChunkedWrite: sync.NewCond(m),
		notFlushing:    sync.NewCond(m),
		chunkedWriter:  sync.NewCond(m),
		flushAt:        2 * size,
	}
}
func NewWriter(w io.Writer) *Writer {
	return NewWriterSize(w, defaultBufSize)
}
func NewWriterAutoFlush(w io.Writer, size int, flushAt float32) *Writer {
	if flushAt < 0 && flushAt != -1 || flushAt > 1 {
		panic(fmt.Sprintf("flushAt should be -1.0 or a fraction 0.0 <= flushAt <= 1.0, got %f", flushAt))
	}
	_, ok := w.(*Writer)
	if !ok {
		_, ok = w.(*bufio.Writer)
	}
	if ok {
		panic("Will not auto flush on top of a buffered writer")
	}
	b := NewWriterSize(w, size)
	if flushAt != -1 {
		b.flushAt = int(flushAt * float32(size))
	}
	return b
}
func (b *Writer) Reset(w io.Writer) {
	b.mtx.Lock()
	for b.err == nil && (b.nFlush != 0 || b.inChunkedWriteMode) {
		b.notFlushing.Wait()
	}
	b.err = nil
	b.n = 0
	b.wr = w
	b.nFlush = 0
	b.mtx.Unlock()
	b.notFlushing.Signal()
}
func (b *Writer) Flush() error {
	b.mtx.Lock()
	b.waitUntilNoChunkedWrite()
	err := b.flush(0)
	b.mtx.Unlock()
	return err
}
func (b *Writer) flush(need int) error {
	iAmChunked := b.inChunkedWriteMode
	callerNeedMet := func() bool {
		return b.n == 0 || (need > 0 && b.available() >= need)
	}
	waitToFlush := func() bool {
		waited := false
		if iAmChunked {
			for b.nFlush != 0 {
				b.chunkedWriter.Wait()
				waited = true
			}
		} else {
			for b.nFlush != 0 || b.inChunkedWriteMode {
				b.notFlushing.Wait()
				waited = true
			}
		}
		return waited
	}
	for b.err == nil && !callerNeedMet() {
		if waitToFlush() {
			continue
		}
		b.nFlush = b.n
		mtxReleased := false
		if !iAmChunked && b.nFlush != len(b.buf) {
			b.mtx.Unlock()
			mtxReleased = true
		}
		n, err := b.wr.Write(b.buf[0:b.nFlush])
		if n < b.nFlush && err == nil {
			err = io.ErrShortWrite
		}
		if mtxReleased {
			b.mtx.Lock()
		}
		if n > 0 && n < b.n {
			copy(b.buf[0:b.n-n], b.buf[n:b.n])
		}
		b.n -= n
		b.err = err
		b.nFlush = 0
		if mtxReleased && b.inChunkedWriteMode {
			b.chunkedWriter.Signal()
			b.waitUntilNoChunkedWrite()
		}
		if need == 0 {
			break
		}
	}
	b.notFlushing.Signal()
	return b.err
}
func (b *Writer) maybeAutoFlush() {
	if b.n >= b.flushAt && b.nFlush == 0 {
		go b.Flush()
	}
}
func (b *Writer) endChunkedWrite() {
	b.inChunkedWriteMode = false
	b.noChunkedWrite.Signal()
}
func (b *Writer) waitUntilNoChunkedWrite() {
	for b.inChunkedWriteMode {
		b.noChunkedWrite.Wait()
	}
	b.noChunkedWrite.Signal()
}
func (b *Writer) Available() int {
	b.mtx.Lock()
	res := b.available()
	b.mtx.Unlock()
	return res
}
func (b *Writer) available() int { return len(b.buf) - b.n }
func (b *Writer) Buffered() int {
	b.mtx.Lock()
	res := b.buffered()
	b.mtx.Unlock()
	return res
}
func (b *Writer) buffered() int { return b.n }
func (b *Writer) Write(p []byte) (nn int, err error) {
	b.mtx.Lock()
	defer b.mtx.Unlock()
	b.waitUntilNoChunkedWrite()
	for len(p) > b.available() && b.err == nil {
		if !b.inChunkedWriteMode {
			b.inChunkedWriteMode = true
			defer b.endChunkedWrite()
		}
		var n int
		if b.buffered() == 0 {
			n, b.err = b.wr.Write(p)
		} else {
			n = copy(b.buf[b.n:], p)
			b.n += n
			b.flush(1)
		}
		nn += n
		p = p[n:]
	}
	if b.err != nil {
		return nn, b.err
	}
	n := copy(b.buf[b.n:], p)
	b.n += n
	nn += n
	b.maybeAutoFlush()
	return nn, nil
}
func (b *Writer) WriteByte(c byte) error {
	b.mtx.Lock()
	defer b.mtx.Unlock()
	b.waitUntilNoChunkedWrite()
	if b.err != nil {
		return b.err
	}
	if b.available() <= 0 && b.flush(1) != nil {
		return b.err
	}
	b.buf[b.n] = c
	b.n++
	b.maybeAutoFlush()
	return nil
}
func (b *Writer) WriteRune(r rune) (size int, err error) {
	if r < utf8.RuneSelf {
		err = b.WriteByte(byte(r))
		if err != nil {
			return 0, err
		}
		return 1, nil
	}
	var encoded [4]byte
	size = utf8.EncodeRune(encoded[:], r)
	return b.Write(encoded[:size])
}
func (b *Writer) WriteString(s string) (int, error) {
	nn := 0
	b.mtx.Lock()
	defer b.mtx.Unlock()
	b.waitUntilNoChunkedWrite()
	if b.err != nil {
		return 0, b.err
	}
	for len(s) > b.available() {
		n := copy(b.buf[b.n:], s)
		b.n += n
		nn += n
		s = s[n:]
		if !b.inChunkedWriteMode {
			b.inChunkedWriteMode = true
			defer b.endChunkedWrite()
		}
		b.flush(1)
		if b.err != nil {
			return nn, b.err
		}
	}
	n := copy(b.buf[b.n:], s)
	b.n += n
	nn += n
	b.maybeAutoFlush()
	return nn, nil
}