github.com/protolambda/zssz@v0.1.5/enc/encoder.go (about) 1 package enc 2 3 import ( 4 "encoding/binary" 5 "io" 6 "unsafe" 7 ) 8 9 type SizeFn func(pointer unsafe.Pointer) uint64 10 11 type EncoderFn func(eb *EncodingWriter, pointer unsafe.Pointer) error 12 13 type EncodingWriter struct { 14 w io.Writer 15 wfn func(p []byte) (n int, err error) 16 n int 17 Scratch [32]byte 18 } 19 20 func NewEncodingWriter(w io.Writer) *EncodingWriter { 21 return &EncodingWriter{w: w, wfn: w.Write, n: 0} 22 } 23 24 // How many bytes were written to the underlying io.Writer before ending encoding (for handling errors) 25 func (ew *EncodingWriter) Written() int { 26 return ew.n 27 } 28 29 // Write writes len(p) bytes from p to the underlying accumulated buffer. 30 func (ew *EncodingWriter) Write(p []byte) error { 31 n, err := ew.wfn(p) 32 ew.n += n 33 return err 34 } 35 36 // Write a single byte to the buffer. 37 func (ew *EncodingWriter) WriteByte(v byte) error { 38 ew.Scratch[0] = v 39 return ew.Write(ew.Scratch[0:1]) 40 } 41 42 // Writes an offset for an element 43 func (ew *EncodingWriter) WriteOffset(prevOffset uint64, elemLen uint64) (offset uint64, err error) { 44 if prevOffset >= (uint64(1) << 32) { 45 panic("cannot write offset with invalid previous offset") 46 } 47 if elemLen >= (uint64(1) << 32) { 48 panic("cannot write offset with invalid element size") 49 } 50 offset = prevOffset + elemLen 51 if offset >= (uint64(1) << 32) { 52 panic("offset too large, not uint32") 53 } 54 binary.LittleEndian.PutUint32(ew.Scratch[0:4], uint32(offset)) 55 err = ew.Write(ew.Scratch[0:4]) 56 return 57 }