github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/poller/buffer.go (about) 1 package poller 2 3 import ( 4 "io" 5 "syscall" 6 ) 7 8 // Buffer Read buffer, one read buffer for each tcp long connection 9 type Buffer struct { 10 // todo: use bytes.Buffer -> buffer pool 11 // buff bytes.Buffer 12 buf []byte // In-application cache 13 start int // The start position of a valid byte 14 end int // End position of a valid byte 15 } 16 17 // NewBuffer Creates a buffer 18 func NewBuffer(bytes []byte) *Buffer { 19 return &Buffer{buf: bytes, start: 0, end: 0} 20 } 21 22 func (b *Buffer) Len() int { 23 return b.end - b.start 24 } 25 26 // reset Reset cache (moves useful bytes forward) 27 func (b *Buffer) reset() { 28 if b.start == 0 { 29 return 30 } 31 end := b.end 32 if b.end > len(b.buf) { 33 end = len(b.buf) 34 } 35 copy(b.buf, b.buf[b.start:end]) 36 end -= b.start 37 b.start = 0 38 b.end = end 39 } 40 41 // ReadFromFD reads data from the file descriptor 42 func (b *Buffer) ReadFromFD(fd int) error { 43 b.reset() 44 n, err := syscall.Read(fd, b.buf[b.end:]) 45 if err != nil { 46 return err 47 } 48 if n == 0 { 49 return syscall.EAGAIN 50 } 51 b.end += n 52 return nil 53 } 54 55 // AsyncReadFromFD 56 // async block read event from fd to buf 57 func (b *Buffer) AsyncReadFromFD(fd int, uring *ioUring, cb EventCallBack) error { 58 b.reset() 59 uring.addRecvSqe(func(info *eventInfo) error { 60 n := info.cqe.Res 61 if n < 0 { 62 return ErrIOUringReadFail 63 } 64 if n == 0 { 65 return syscall.EAGAIN 66 } 67 b.end += int(n) 68 //log.Infof("cb %+v buff start %d end %d n %d buff %s", cb, b.start, b.end, n, b.buf[b.start:b.end]) 69 err := cb(info) 70 return err 71 }, fd, b.buf[b.end:], len(b.buf[b.end:]), 0) 72 73 return nil 74 } 75 76 // ReadFromReader reads data from the reader. If the reader blocks, it will block 77 func (b *Buffer) ReadFromReader(reader io.Reader) (int, error) { 78 b.reset() 79 n, err := reader.Read(b.buf[b.end:]) 80 if err != nil { 81 return n, err 82 } 83 b.end += n 84 return n, nil 85 } 86 87 // Seek returns n bytes without a shift, or an error if there are not enough bytes 88 func (b *Buffer) Seek(len int) ([]byte, error) { 89 if b.end-b.start >= len { 90 buf := b.buf[b.start : b.start+len] 91 return buf, nil 92 } 93 return nil, ErrBufferNotEnough 94 } 95 96 // Read Discard offset fields and read n fields. If there are not enough bytes, an error is returned 97 func (b *Buffer) Read(offset, limit int) ([]byte, error) { 98 if b.Len() < offset+limit { 99 return nil, ErrBufferNotEnough 100 } 101 b.start += offset 102 buf := b.buf[b.start : b.start+limit] 103 b.start += limit 104 return buf, nil 105 } 106 107 // ReadAll Reads all bytes 108 func (b *Buffer) ReadAll() []byte { 109 buf, _ := b.Read(b.start, b.end) 110 return buf 111 }