github.com/protolambda/zssz@v0.1.5/types/ssz_bytes_n.go (about) 1 package types 2 3 import ( 4 "fmt" 5 . "github.com/protolambda/zssz/dec" 6 . "github.com/protolambda/zssz/enc" 7 . "github.com/protolambda/zssz/htr" 8 "github.com/protolambda/zssz/merkle" 9 . "github.com/protolambda/zssz/pretty" 10 "github.com/protolambda/zssz/util/ptrutil" 11 "reflect" 12 "unsafe" 13 ) 14 15 type SSZBytesN struct { 16 length uint64 17 } 18 19 func NewSSZBytesN(typ reflect.Type) (*SSZBytesN, error) { 20 if typ.Kind() != reflect.Array { 21 return nil, fmt.Errorf("typ is not a fixed-length bytes array") 22 } 23 if typ.Elem().Kind() != reflect.Uint8 { 24 return nil, fmt.Errorf("typ is not a bytes array") 25 } 26 length := typ.Len() 27 res := &SSZBytesN{length: uint64(length)} 28 return res, nil 29 } 30 31 func (v *SSZBytesN) FuzzMinLen() uint64 { 32 return v.length 33 } 34 35 func (v *SSZBytesN) FuzzMaxLen() uint64 { 36 return v.length 37 } 38 39 func (v *SSZBytesN) MinLen() uint64 { 40 return v.length 41 } 42 43 func (v *SSZBytesN) MaxLen() uint64 { 44 return v.length 45 } 46 47 func (v *SSZBytesN) FixedLen() uint64 { 48 return v.length 49 } 50 51 func (v *SSZBytesN) IsFixed() bool { 52 return true 53 } 54 55 func (v *SSZBytesN) SizeOf(p unsafe.Pointer) uint64 { 56 return v.length 57 } 58 59 func (v *SSZBytesN) Encode(eb *EncodingWriter, p unsafe.Pointer) error { 60 sh := ptrutil.GetSliceHeader(p, v.length) 61 data := *(*[]byte)(unsafe.Pointer(sh)) 62 return eb.Write(data) 63 } 64 65 func (v *SSZBytesN) Decode(dr *DecodingReader, p unsafe.Pointer) error { 66 sh := ptrutil.GetSliceHeader(p, v.length) 67 data := *(*[]byte)(unsafe.Pointer(sh)) 68 _, err := dr.Read(data) 69 return err 70 } 71 72 func (v *SSZBytesN) DryCheck(dr *DecodingReader) error { 73 _, err := dr.Skip(v.length) 74 return err 75 } 76 77 func (v *SSZBytesN) HashTreeRoot(h MerkleFn, p unsafe.Pointer) [32]byte { 78 sh := ptrutil.GetSliceHeader(p, v.length) 79 data := *(*[]byte)(unsafe.Pointer(sh)) 80 leafCount := (v.length + 31) >> 5 81 leaf := func(i uint64) []byte { 82 s := i << 5 83 e := (i + 1) << 5 84 // pad the data 85 if e > v.length { 86 x := [32]byte{} 87 copy(x[:], data[s:v.length]) 88 return x[:] 89 } 90 return data[s:e] 91 } 92 return merkle.Merkleize(h, leafCount, leafCount, leaf) 93 } 94 95 func (v *SSZBytesN) Pretty(indent uint32, w *PrettyWriter, p unsafe.Pointer) { 96 w.WriteIndent(indent) 97 sh := ptrutil.GetSliceHeader(p, v.length) 98 data := *(*[]byte)(unsafe.Pointer(sh)) 99 w.Write(fmt.Sprintf("0x%x", data)) 100 }