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