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  }