github.com/qiniu/x@v1.11.9/bufiox/bufio.go (about)

     1  package bufiox
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"errors"
     7  	"io"
     8  	"unsafe"
     9  )
    10  
    11  // -----------------------------------------------------------------------------
    12  
    13  type nilReaderImpl int
    14  
    15  func (p nilReaderImpl) Read(b []byte) (n int, err error) {
    16  	return 0, io.EOF
    17  }
    18  
    19  var nilReader io.Reader = nilReaderImpl(0)
    20  
    21  // -----------------------------------------------------------------------------
    22  
    23  type reader struct {
    24  	buf          []byte
    25  	rd           io.Reader // reader provided by the client
    26  	r, w         int       // buf read and write positions
    27  	err          error
    28  	lastByte     int
    29  	lastRuneSize int
    30  }
    31  
    32  // NewReaderBuffer returns a new Reader who uses a extern buffer.
    33  func NewReaderBuffer(buf []byte) *bufio.Reader {
    34  	r := &reader{
    35  		buf:          buf,
    36  		rd:           nilReader,
    37  		w:            len(buf),
    38  		lastByte:     -1,
    39  		lastRuneSize: -1,
    40  	}
    41  	b := new(bufio.Reader)
    42  	*b = *(*bufio.Reader)(unsafe.Pointer(r))
    43  	return b
    44  }
    45  
    46  // Buffer is reserved for internal use.
    47  func Buffer(b *bufio.Reader) []byte {
    48  	r := (*reader)(unsafe.Pointer(b))
    49  	return r.buf
    50  }
    51  
    52  // IsReaderBuffer returns if this Reader instance is returned by NewReaderBuffer
    53  func IsReaderBuffer(b *bufio.Reader) bool {
    54  	r := (*reader)(unsafe.Pointer(b))
    55  	return r.rd == nilReader
    56  }
    57  
    58  // ReadAll reads all data
    59  func ReadAll(b *bufio.Reader) (ret []byte, err error) {
    60  	r := (*reader)(unsafe.Pointer(b))
    61  	if r.rd == nilReader {
    62  		ret, r.buf = r.buf, nil
    63  		return
    64  	}
    65  	var w bytes.Buffer
    66  	_, err1 := b.WriteTo(&w)
    67  	return w.Bytes(), err1
    68  }
    69  
    70  // -----------------------------------------------------------------------------
    71  
    72  func getUnderlyingReader(b *bufio.Reader) io.Reader {
    73  	r := (*reader)(unsafe.Pointer(b))
    74  	return r.rd
    75  }
    76  
    77  // ErrSeekUnsupported error.
    78  var ErrSeekUnsupported = errors.New("bufio: the underlying reader doesn't support seek")
    79  
    80  // Seek sets the offset for the next Read or Write to offset, interpreted
    81  // according to whence: SeekStart means relative to the start of the file,
    82  // SeekCurrent means relative to the current offset, and SeekEnd means
    83  // relative to the end. Seek returns the new offset relative to the start
    84  // of the file and an error, if any.
    85  //
    86  func Seek(b *bufio.Reader, offset int64, whence int) (int64, error) {
    87  	r := getUnderlyingReader(b)
    88  	if seeker, ok := r.(io.Seeker); ok {
    89  		newoff, err := seeker.Seek(offset, whence)
    90  		if err == nil {
    91  			b.Reset(r)
    92  		}
    93  		return newoff, err
    94  	}
    95  	return 0, ErrSeekUnsupported
    96  }
    97  
    98  // ReadAtLeast reads from r into buf until it has read at least min bytes.
    99  // It returns the number of bytes copied and an error if fewer bytes were read.
   100  // The error is EOF only if no bytes were read.
   101  // If an EOF happens after reading fewer than min bytes,
   102  // ReadAtLeast returns ErrUnexpectedEOF.
   103  // If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
   104  // On return, n >= min if and only if err == nil.
   105  // If r returns an error having read at least min bytes, the error is dropped.
   106  func ReadAtLeast(r *bufio.Reader, buf []byte, min int) (n int, err error) {
   107  	if len(buf) < min {
   108  		return 0, io.ErrShortBuffer
   109  	}
   110  	for n < min && err == nil {
   111  		var nn int
   112  		nn, err = r.Read(buf[n:])
   113  		n += nn
   114  	}
   115  	if n >= min {
   116  		err = nil
   117  	} else if n > 0 && err == io.EOF {
   118  		err = io.ErrUnexpectedEOF
   119  	}
   120  	return
   121  }
   122  
   123  // ReadFull reads exactly len(buf) bytes from r into buf.
   124  // It returns the number of bytes copied and an error if fewer bytes were read.
   125  // The error is EOF only if no bytes were read.
   126  // If an EOF happens after reading some but not all the bytes,
   127  // ReadFull returns ErrUnexpectedEOF.
   128  // On return, n == len(buf) if and only if err == nil.
   129  // If r returns an error having read at least len(buf) bytes, the error is dropped.
   130  func ReadFull(r *bufio.Reader, buf []byte) (n int, err error) {
   131  	return ReadAtLeast(r, buf, len(buf))
   132  }
   133  
   134  // -----------------------------------------------------------------------------