github.com/xhebox/bstruct@v0.0.0-20221115052913-86d4d6d98866/lib.go (about) 1 package bstruct 2 3 import ( 4 "encoding/binary" 5 "unsafe" 6 ) 7 8 //go:noescape 9 //go:linkname memmove runtime.memmove 10 func memmove(to, from unsafe.Pointer, n uintptr) 11 12 type Reader struct { 13 data []byte 14 pos int 15 } 16 17 func NewReader(data []byte) *Reader { 18 return &Reader{data: data} 19 } 20 21 func (r *Reader) Data() []byte { 22 return r.data 23 } 24 25 func (r *Reader) Pos() int { 26 return r.pos 27 } 28 29 func (r *Reader) ReadLen() int { 30 l, off := binary.Varint(r.data[r.pos:]) 31 r.pos += off 32 return int(l) 33 } 34 35 func (r *Reader) Copy(ptr unsafe.Pointer, length int) { 36 memmove(ptr, unsafe.Pointer(&r.data[r.pos]), uintptr(length)) 37 r.pos += length 38 } 39 40 func (r *Reader) Read(length int) uintptr { 41 ptr := uintptr(unsafe.Pointer(&r.data[r.pos])) 42 r.pos += length 43 return ptr 44 } 45 46 type Writer struct { 47 data []byte 48 pos int 49 } 50 51 func NewWriter() *Writer { 52 return &Writer{data: make([]byte, 16)} 53 } 54 55 func (w *Writer) grow(length int) { 56 rem := len(w.data) - w.pos 57 if rem >= length { 58 w.data = w.data[:len(w.data)] 59 return 60 } 61 62 w.data = append(w.data, make([]byte, cap(w.data))...) 63 } 64 65 func (w *Writer) Data() []byte { 66 return w.data 67 } 68 69 func (w *Writer) WriteLen(length int) { 70 w.grow(9) 71 w.pos += binary.PutVarint(w.data[w.pos:], int64(length)) 72 } 73 74 func (w *Writer) Copy(ptr unsafe.Pointer, length int) { 75 w.grow(length) 76 memmove(unsafe.Pointer(&w.data[w.pos]), ptr, uintptr(length)) 77 w.pos += length 78 }