github.com/aychain/blockbook@v0.1.1-0.20181121092459-6d1fc7e07c5b/bchain/coins/btc/codec.go (about)

     1  package btc
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"reflect"
     7  )
     8  
     9  type RPCMarshaler interface {
    10  	Marshal(v interface{}) ([]byte, error)
    11  }
    12  
    13  type JSONMarshalerV2 struct{}
    14  
    15  func (JSONMarshalerV2) Marshal(v interface{}) ([]byte, error) {
    16  	d, err := json.Marshal(v)
    17  	if err != nil {
    18  		return nil, err
    19  	}
    20  	return d, nil
    21  }
    22  
    23  var InvalidValue = errors.New("Invalid value to marshal")
    24  
    25  type JSONMarshalerV1 struct{}
    26  
    27  func (JSONMarshalerV1) Marshal(v interface{}) ([]byte, error) {
    28  	u := cmdUntypedParams{}
    29  
    30  	switch v := v.(type) {
    31  	case *CmdGetBlock:
    32  		var t bool
    33  		if v.Params.Verbosity > 0 {
    34  			t = true
    35  		}
    36  		u.Method = v.Method
    37  		u.Params = append(u.Params, v.Params.BlockHash)
    38  		u.Params = append(u.Params, t)
    39  	case *CmdGetRawTransaction:
    40  		var n int
    41  		if v.Params.Verbose {
    42  			n = 1
    43  		}
    44  		u.Method = v.Method
    45  		u.Params = append(u.Params, v.Params.Txid)
    46  		u.Params = append(u.Params, n)
    47  	default:
    48  		{
    49  			v := reflect.ValueOf(v).Elem()
    50  
    51  			f := v.FieldByName("Method")
    52  			if !f.IsValid() || f.Kind() != reflect.String {
    53  				return nil, InvalidValue
    54  			}
    55  			u.Method = f.String()
    56  
    57  			f = v.FieldByName("Params")
    58  			if f.IsValid() {
    59  				var arr []interface{}
    60  				switch f.Kind() {
    61  				case reflect.Slice:
    62  					arr = make([]interface{}, f.Len())
    63  					for i := 0; i < f.Len(); i++ {
    64  						arr[i] = f.Index(i).Interface()
    65  					}
    66  				case reflect.Struct:
    67  					arr = make([]interface{}, f.NumField())
    68  					for i := 0; i < f.NumField(); i++ {
    69  						arr[i] = f.Field(i).Interface()
    70  					}
    71  				default:
    72  					return nil, InvalidValue
    73  				}
    74  				u.Params = arr
    75  			}
    76  		}
    77  	}
    78  
    79  	d, err := json.Marshal(u)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	return d, nil
    85  }
    86  
    87  type cmdUntypedParams struct {
    88  	Method string        `json:"method"`
    89  	Params []interface{} `json:"params,omitempty"`
    90  }