github.com/protolambda/zssz@v0.1.5/types/ssz_ptr.go (about) 1 package types 2 3 import ( 4 "errors" 5 "fmt" 6 . "github.com/protolambda/zssz/dec" 7 . "github.com/protolambda/zssz/enc" 8 . "github.com/protolambda/zssz/htr" 9 . "github.com/protolambda/zssz/pretty" 10 "github.com/protolambda/zssz/util/ptrutil" 11 "reflect" 12 "unsafe" 13 ) 14 15 // proxies SSZ behavior to the SSZ type of the object being pointed to. 16 type SSZPtr struct { 17 elemSSZ SSZ 18 alloc ptrutil.AllocationFn 19 } 20 21 func NewSSZPtr(factory SSZFactoryFn, typ reflect.Type) (*SSZPtr, error) { 22 if typ.Kind() != reflect.Ptr { 23 return nil, fmt.Errorf("typ is not a pointer") 24 } 25 elemTyp := typ.Elem() 26 elemSSZ, err := factory(elemTyp) 27 if err != nil { 28 return nil, err 29 } 30 alloc := func(p unsafe.Pointer) unsafe.Pointer { 31 return ptrutil.AllocateSpace(p, elemTyp) 32 } 33 return &SSZPtr{elemSSZ: elemSSZ, alloc: alloc}, nil 34 } 35 36 func (v *SSZPtr) FuzzMinLen() uint64 { 37 return v.elemSSZ.FuzzMinLen() 38 } 39 40 func (v *SSZPtr) FuzzMaxLen() uint64 { 41 return v.elemSSZ.FuzzMaxLen() 42 } 43 44 func (v *SSZPtr) MinLen() uint64 { 45 return v.elemSSZ.MinLen() 46 } 47 48 func (v *SSZPtr) MaxLen() uint64 { 49 return v.elemSSZ.MaxLen() 50 } 51 52 func (v *SSZPtr) FixedLen() uint64 { 53 return v.elemSSZ.FixedLen() 54 } 55 56 func (v *SSZPtr) IsFixed() bool { 57 return v.elemSSZ.IsFixed() 58 } 59 60 func (v *SSZPtr) SizeOf(p unsafe.Pointer) uint64 { 61 innerPtr := unsafe.Pointer(*(*uintptr)(p)) 62 return v.elemSSZ.SizeOf(innerPtr) 63 } 64 65 func (v *SSZPtr) Encode(eb *EncodingWriter, p unsafe.Pointer) error { 66 innerPtr := unsafe.Pointer(*(*uintptr)(p)) 67 return v.elemSSZ.Encode(eb, innerPtr) 68 } 69 70 func (v *SSZPtr) Decode(dr *DecodingReader, p unsafe.Pointer) error { 71 if p == unsafe.Pointer(nil) { 72 return errors.New("cannot decode into nil pointer") 73 } 74 if *(*uintptr)(p) == uintptr(0) { 75 contentsPtr := v.alloc(p) 76 return v.elemSSZ.Decode(dr, contentsPtr) 77 } else { 78 return v.elemSSZ.Decode(dr, unsafe.Pointer(*(*uintptr)(p))) 79 } 80 } 81 82 func (v *SSZPtr) DryCheck(dr *DecodingReader) error { 83 return v.elemSSZ.DryCheck(dr) 84 } 85 86 func (v *SSZPtr) HashTreeRoot(h MerkleFn, p unsafe.Pointer) [32]byte { 87 innerPtr := unsafe.Pointer(*(*uintptr)(p)) 88 return v.elemSSZ.HashTreeRoot(h, innerPtr) 89 } 90 91 func (v *SSZPtr) Pretty(indent uint32, w *PrettyWriter, p unsafe.Pointer) { 92 innerPtr := unsafe.Pointer(*(*uintptr)(p)) 93 if innerPtr == nil { 94 w.WriteIndent(indent) 95 w.Write("null") 96 } else { 97 v.elemSSZ.Pretty(indent, w, innerPtr) 98 } 99 }