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 }