github.com/protolambda/zssz@v0.1.5/zssz.go (about) 1 package zssz 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/pretty" 9 . "github.com/protolambda/zssz/types" 10 "github.com/protolambda/zssz/util/ptrutil" 11 "io" 12 "reflect" 13 "runtime" 14 ) 15 16 const VERSION = "v0.1.5" 17 18 func Decode(r io.Reader, bytesLen uint64, val interface{}, sszTyp SSZ) error { 19 if bytesLen < sszTyp.MinLen() { 20 return fmt.Errorf("expected object length is larger than given bytesLen") 21 } 22 unscoped := NewDecodingReader(r) 23 dr, err := unscoped.Scope(bytesLen) 24 if err != nil { 25 return err 26 } 27 p := ptrutil.IfacePtrToPtr(&val) 28 if err := sszTyp.Decode(dr, p); err != nil { 29 return err 30 } 31 // make sure the data of the object is kept around up to this point. 32 runtime.KeepAlive(&val) 33 if readCount := dr.Index(); readCount != bytesLen { 34 return fmt.Errorf("read total of %d bytes, but expected %d", readCount, bytesLen) 35 } 36 return nil 37 } 38 39 func DryCheck(r io.Reader, bytesLen uint64, sszTyp SSZ) error { 40 if bytesLen < sszTyp.MinLen() { 41 return fmt.Errorf("expected object length is larger than given bytesLen") 42 } 43 unscoped := NewDecodingReader(r) 44 dr, err := unscoped.Scope(bytesLen) 45 if err != nil { 46 return err 47 } 48 if err := sszTyp.DryCheck(dr); err != nil { 49 return err 50 } 51 if readCount := dr.Index(); readCount != bytesLen { 52 return fmt.Errorf("read total of %d bytes, but expected %d", readCount, bytesLen) 53 } 54 return nil 55 } 56 57 // 1: return value is the amount of bytes that were read, to cut the fuzzing input at if necessary. 58 // 2: return an error if data could not be decoded (something is wrong with the reader). 59 func DecodeFuzzBytes(r io.Reader, bytesLen uint64, val interface{}, sszTyp SSZ) (uint64, error) { 60 if bytesLen < sszTyp.FuzzMinLen() { 61 return 0, fmt.Errorf("expected object fuzzing input length is larger than given bytesLen") 62 } 63 unscoped := NewDecodingReader(r) 64 dr, err := unscoped.Scope(bytesLen) 65 if err != nil { 66 return 0, err 67 } 68 dr.EnableFuzzMode() 69 70 p := ptrutil.IfacePtrToPtr(&val) 71 if err := sszTyp.Decode(dr, p); err != nil { 72 return dr.Index(), err 73 } 74 // make sure the data of the object is kept around up to this point. 75 runtime.KeepAlive(&p) 76 return dr.Index(), nil 77 } 78 79 func SizeOf(val interface{}, sszTyp SSZ) uint64 { 80 p := ptrutil.IfacePtrToPtr(&val) 81 out := sszTyp.SizeOf(p) 82 // make sure the data of the object is kept around up to this point. 83 runtime.KeepAlive(&val) 84 return out 85 } 86 87 func Encode(w io.Writer, val interface{}, sszTyp SSZ) (n int, err error) { 88 ew := NewEncodingWriter(w) 89 90 p := ptrutil.IfacePtrToPtr(&val) 91 err = sszTyp.Encode(ew, p) 92 93 // make sure the data of the object is kept around up to this point. 94 runtime.KeepAlive(&val) 95 96 return ew.Written(), err 97 } 98 99 func Pretty(w io.Writer, indent string, val interface{}, sszTyp SSZ) { 100 pw := NewPrettyWriter(w, indent) 101 102 p := ptrutil.IfacePtrToPtr(&val) 103 sszTyp.Pretty(0, pw, p) 104 105 // make sure the data of the object is kept around up to this point. 106 runtime.KeepAlive(&val) 107 } 108 109 func HashTreeRoot(h MerkleFn, val interface{}, sszTyp SSZ) [32]byte { 110 p := ptrutil.IfacePtrToPtr(&val) 111 out := sszTyp.HashTreeRoot(h, p) 112 // make sure the data of the object is kept around up to this point. 113 runtime.KeepAlive(&val) 114 return out 115 } 116 117 func SigningRoot(h MerkleFn, val interface{}, sszTyp SignedSSZ) [32]byte { 118 p := ptrutil.IfacePtrToPtr(&val) 119 out := sszTyp.SigningRoot(h, p) 120 // make sure the data of the object is kept around up to this point. 121 runtime.KeepAlive(&val) 122 return out 123 } 124 125 // Gets a SSZ type structure for the given Go type. 126 // Pass an pointer instance of the type. Can be nil. 127 // Example: GetSSZ((*MyStruct)(nil)) 128 func GetSSZ(ptr interface{}) SSZ { 129 ssz, err := SSZFactory(reflect.TypeOf(ptr).Elem()) 130 if err != nil { 131 panic(err) 132 } 133 return ssz 134 }