From 05018c1caf3fe1eb8c26a43b2c91f8b0ae668a3d Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 30 Mar 2020 16:18:54 +0800 Subject: [PATCH] github.com/qiniu/x/bufiox --- bufiox/bufio.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 bufiox/bufio.go diff --git a/bufiox/bufio.go b/bufiox/bufio.go new file mode 100644 index 0000000..360242c --- /dev/null +++ b/bufiox/bufio.go @@ -0,0 +1,69 @@ +package bufiox + +import ( + "bufio" + "bytes" + "io" + "unsafe" +) + +// ----------------------------------------------------------------------------- + +type nilReaderImpl int + +func (p nilReaderImpl) Read(b []byte) (n int, err error) { + return 0, io.EOF +} + +var nilReader io.Reader = nilReaderImpl(0) + +// ----------------------------------------------------------------------------- + +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 + lastRuneSize int +} + +// NewReaderBuffer returns a new Reader who uses a extern buffer. +func NewReaderBuffer(buf []byte) *bufio.Reader { + r := &reader{ + buf: buf, + rd: nilReader, + w: len(buf), + lastByte: -1, + lastRuneSize: -1, + } + b := new(bufio.Reader) + *b = *(*bufio.Reader)(unsafe.Pointer(r)) + return b +} + +// Buffer is reserved for internal use. +func Buffer(b *bufio.Reader) []byte { + r := (*reader)(unsafe.Pointer(b)) + return r.buf +} + +// IsReaderBuffer returns if this Reader instance is returned by NewReaderBuffer +func IsReaderBuffer(b *bufio.Reader) bool { + r := (*reader)(unsafe.Pointer(b)) + return r.rd == nilReader +} + +// ReadAll reads all data +func ReadAll(b *bufio.Reader) (ret []byte, err error) { + r := (*reader)(unsafe.Pointer(b)) + if r.rd == nilReader { + ret, r.buf = r.buf, nil + return + } + var w bytes.Buffer + _, err1 := b.WriteTo(&w) + return w.Bytes(), err1 +} + +// -----------------------------------------------------------------------------