diff --git a/codec_test.go b/codec_test.go index 9dde6ff..0d12320 100644 --- a/codec_test.go +++ b/codec_test.go @@ -33,3 +33,29 @@ func TestCompactBigInt(t *testing.T) { require.NoError(t, err) require.EqualValues(t, encoded, rst) } + +func TestLenSize(t *testing.T) { + for _, l := range []uint32{ + 0, + 1, + 16, + 64, + 65, + 1<<14 - 1, + 1 << 14, + 1 << 20, + 1 << 30, + 1 << 31, + 1<<32 - 1, + } { + var b bytes.Buffer + n, err := EncodeLen(NewEncoder(&b), l, 1<<32-1) + require.NoError(t, err) + require.Equal(t, uint32(b.Len()), LenSize(l)) + require.Equal(t, uint32(n), LenSize(l)) + decoded, n, err := DecodeLen(NewDecoder(&b), 1<<32-1) + require.NoError(t, err) + require.Equal(t, l, decoded) + require.Equal(t, uint32(n), LenSize(l)) + } +} diff --git a/encoder.go b/encoder.go index 8c5ab5c..9b8bc48 100644 --- a/encoder.go +++ b/encoder.go @@ -311,3 +311,17 @@ func EncodeStruct[V any, H EncodablePtr[V]](e *Encoder, value V) (int, error) { } return n, nil } + +// LenSize returns the size in bytes required to encode a length value. +func LenSize(v uint32) uint32 { + switch { + case v <= maxUint6: + return 1 + case v <= maxUint14: + return 2 + case v <= maxUint30: + return 4 + default: + return 5 + } +}