go-blockchain/wire/encoder.go

89 lines
2 KiB
Go
Raw Normal View History

// Copyright (c) 2017-2026 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// SPDX-License-Identifier: EUPL-1.2
package wire
import (
"encoding/binary"
"io"
)
// Encoder writes consensus-critical binary data to an io.Writer.
// It uses a sticky error pattern: after the first write error, all
// subsequent writes become no-ops. Call Err() after a complete
// encoding sequence to check for failures.
type Encoder struct {
w io.Writer
err error
buf [10]byte // scratch for LE integers and varints
}
// NewEncoder creates a new Encoder writing to w.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{w: w}
}
// Err returns the first error encountered during encoding.
func (e *Encoder) Err() error { return e.err }
// WriteUint8 writes a single byte.
func (e *Encoder) WriteUint8(v uint8) {
if e.err != nil {
return
}
e.buf[0] = v
_, e.err = e.w.Write(e.buf[:1])
}
// WriteUint64LE writes a uint64 in little-endian byte order.
func (e *Encoder) WriteUint64LE(v uint64) {
if e.err != nil {
return
}
binary.LittleEndian.PutUint64(e.buf[:8], v)
_, e.err = e.w.Write(e.buf[:8])
}
// WriteVarint writes a uint64 as a CryptoNote varint (LEB128).
func (e *Encoder) WriteVarint(v uint64) {
if e.err != nil {
return
}
b := EncodeVarint(v)
_, e.err = e.w.Write(b)
}
// WriteBytes writes raw bytes with no length prefix.
func (e *Encoder) WriteBytes(b []byte) {
if e.err != nil {
return
}
if len(b) == 0 {
return
}
_, e.err = e.w.Write(b)
}
// WriteBlob32 writes a 32-byte fixed-size blob (hash, public key, key image).
func (e *Encoder) WriteBlob32(b *[32]byte) {
if e.err != nil {
return
}
_, e.err = e.w.Write(b[:])
}
// WriteBlob64 writes a 64-byte fixed-size blob (signature).
func (e *Encoder) WriteBlob64(b *[64]byte) {
if e.err != nil {
return
}
_, e.err = e.w.Write(b[:])
}
// WriteVariantTag writes a single-byte variant discriminator.
func (e *Encoder) WriteVariantTag(tag uint8) {
e.WriteUint8(tag)
}