diff --git a/README.md b/README.md index 524c21c..7175a16 100644 --- a/README.md +++ b/README.md @@ -552,6 +552,7 @@ The table below is a summary of the methods available for `SizeSSZ` and `DefineS | `bool` | `1 byte` | [`DefineBool`](https://pkg.go.dev/github.com/karalabe/ssz#DefineBool) | [`EncodeBool`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeBool) | [`DecodeBool`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeBool) | [`HashBool`](https://pkg.go.dev/github.com/karalabe/ssz#HashBool) | | `uint8` | `1 bytes` | [`DefineUint8`](https://pkg.go.dev/github.com/karalabe/ssz#DefineUint8) | [`EncodeUint8`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeUint8) | [`DecodeUint8`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeUint8) | [`HashUint8`](https://pkg.go.dev/github.com/karalabe/ssz#HashUint8) | | `uint16` | `2 bytes` | [`DefineUint16`](https://pkg.go.dev/github.com/karalabe/ssz#DefineUint16) | [`EncodeUint16`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeUint16) | [`DecodeUint16`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeUint16) | [`HashUint16`](https://pkg.go.dev/github.com/karalabe/ssz#HashUint16) | +| `uint32` | `4 bytes` | [`DefineUint32`](https://pkg.go.dev/github.com/karalabe/ssz#DefineUint32) | [`EncodeUint32`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeUint32) | [`DecodeUint32`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeUint32) | [`HashUint32`](https://pkg.go.dev/github.com/karalabe/ssz#HashUint32) | | `uint64` | `8 bytes` | [`DefineUint64`](https://pkg.go.dev/github.com/karalabe/ssz#DefineUint64) | [`EncodeUint64`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeUint64) | [`DecodeUint64`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeUint64) | [`HashUint64`](https://pkg.go.dev/github.com/karalabe/ssz#HashUint64) | | `[N]byte` as `bitvector[N]` | `N bytes` | [`DefineArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#DefineArrayOfBits) | [`EncodeArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeArrayOfBits) | [`DecodeArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeArrayOfBits) | [`HashArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#HashArrayOfBits) | | `bitfield.Bitlist`² | [`SizeSliceOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#SizeSliceOfBits) | [`DefineSliceOfBitsOffset`](https://pkg.go.dev/github.com/karalabe/ssz#DefineSliceOfBitsOffset) [`DefineSliceOfBitsContent`](https://pkg.go.dev/github.com/karalabe/ssz#DefineSliceOfBitsContent) | [`EncodeSliceOfBitsOffset`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeSliceOfBitsOffset) [`EncodeSliceOfBitsContent`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeSliceOfBitsContent) | [`DecodeSliceOfBitsOffset`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeSliceOfBitsOffset) [`DecodeSliceOfBitsContent`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeSliceOfBitsContent) | [`HashSliceOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#HashSliceOfBits) | diff --git a/cmd/sszgen/opset.go b/cmd/sszgen/opset.go index 27aa999..eb0aeca 100644 --- a/cmd/sszgen/opset.go +++ b/cmd/sszgen/opset.go @@ -83,6 +83,16 @@ func (p *parseContext) resolveBasicOpset(typ *types.Basic, tags *sizeTag) (opset "DecodeUint16({{.Codec}}, &{{.Field}})", []int{2}, }, nil + case types.Uint32: + if tags != nil && tags.size[0] != 4 { + return nil, fmt.Errorf("byte basic type requires ssz-size=4: have %d", tags.size[0]) + } + return &opsetStatic{ + "DefineUint32({{.Codec}}, &{{.Field}})", + "EncodeUint32({{.Codec}}, &{{.Field}})", + "DecodeUint32({{.Codec}}, &{{.Field}})", + []int{4}, + }, nil case types.Uint64: if tags != nil && tags.size[0] != 8 { return nil, fmt.Errorf("uint64 basic type requires ssz-size=8: have %d", tags.size[0]) diff --git a/codec.go b/codec.go index 481d0b5..3b36736 100644 --- a/codec.go +++ b/codec.go @@ -92,6 +92,19 @@ func DefineUint16[T ~uint16](c *Codec, n *T) { HashUint16(c.has, *n) } +// DefineUint16 defines the next field as a uint16. +func DefineUint32[T ~uint32](c *Codec, n *T) { + if c.enc != nil { + EncodeUint32(c.enc, *n) + return + } + if c.dec != nil { + DecodeUint32(c.dec, n) + return + } + HashUint32(c.has, *n) +} + // DefineUint64 defines the next field as a uint64. func DefineUint64[T ~uint64](c *Codec, n *T) { if c.enc != nil { diff --git a/decoder.go b/decoder.go index 9e0b32b..26f469d 100644 --- a/decoder.go +++ b/decoder.go @@ -147,6 +147,25 @@ func DecodeUint16[T ~uint16](dec *Decoder, n *T) { } } +// DecodeUint32 parses a uint32. +func DecodeUint32[T ~uint32](dec *Decoder, n *T) { + if dec.err != nil { + return + } + if dec.inReader != nil { + _, dec.err = io.ReadFull(dec.inReader, dec.buf[:4]) + *n = T(binary.LittleEndian.Uint32(dec.buf[:4])) + dec.inRead += 4 + } else { + if len(dec.inBuffer) < 4 { + dec.err = io.ErrUnexpectedEOF + return + } + *n = T(binary.LittleEndian.Uint32(dec.inBuffer)) + dec.inBuffer = dec.inBuffer[4:] + } +} + // DecodeUint64 parses a uint64. func DecodeUint64[T ~uint64](dec *Decoder, n *T) { if dec.err != nil { diff --git a/encoder.go b/encoder.go index 8ea42ed..2f262e1 100644 --- a/encoder.go +++ b/encoder.go @@ -127,6 +127,20 @@ func EncodeUint16[T ~uint16](enc *Encoder, n T) { } } +// EncodeUint32 serializes a uint32. +func EncodeUint32[T ~uint32](enc *Encoder, n T) { + if enc.outWriter != nil { + if enc.err != nil { + return + } + binary.LittleEndian.PutUint32(enc.buf[:4], (uint32)(n)) + _, enc.err = enc.outWriter.Write(enc.buf[:4]) + } else { + binary.LittleEndian.PutUint32(enc.outBuffer, (uint32)(n)) + enc.outBuffer = enc.outBuffer[4:] + } +} + // EncodeUint64 serializes a uint64. func EncodeUint64[T ~uint64](enc *Encoder, n T) { // Nope, dive into actual encoding diff --git a/hasher.go b/hasher.go index f946398..51fb530 100644 --- a/hasher.go +++ b/hasher.go @@ -87,6 +87,13 @@ func HashUint16[T ~uint16](h *Hasher, n T) { h.insertChunk(buffer, 0) } +// HashUint32 hashes a uint32. +func HashUint32[T ~uint32](h *Hasher, n T) { + var buffer [32]byte + binary.LittleEndian.PutUint32(buffer[:], uint32(n)) + h.insertChunk(buffer, 0) +} + // HashUint64 hashes a uint64. func HashUint64[T ~uint64](h *Hasher, n T) { var buffer [32]byte