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  }