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  }