forked from trezor/blockbook
-
Notifications
You must be signed in to change notification settings - Fork 7
/
codec.go
96 lines (83 loc) · 2.19 KB
/
codec.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package btc
import (
"encoding/json"
"errors"
"reflect"
)
// RPCMarshaler is used for marshalling requests to Bitcoin Type RPC interfaces
type RPCMarshaler interface {
Marshal(v interface{}) ([]byte, error)
}
// JSONMarshalerV2 is used for marshalling requests to newer Bitcoin Type RPC interfaces
type JSONMarshalerV2 struct{}
// Marshal converts struct passed by parameter to JSON
func (JSONMarshalerV2) Marshal(v interface{}) ([]byte, error) {
d, err := json.Marshal(v)
if err != nil {
return nil, err
}
return d, nil
}
// ErrInvalidValue is error returned by JSONMarshalerV1.Marshal if the passed structure contains invalid value
var ErrInvalidValue = errors.New("Invalid value to marshal")
// JSONMarshalerV1 is used for marshalling requests to legacy Bitcoin Type RPC interfaces
type JSONMarshalerV1 struct{}
// Marshal converts struct passed by parameter to JSON
func (JSONMarshalerV1) Marshal(v interface{}) ([]byte, error) {
u := cmdUntypedParams{}
switch v := v.(type) {
case *CmdGetBlock:
var t bool
if v.Params.Verbosity > 0 {
t = true
}
u.Method = v.Method
u.Params = append(u.Params, v.Params.BlockHash)
u.Params = append(u.Params, t)
case *CmdGetRawTransaction:
var n int
if v.Params.Verbose {
n = 1
}
u.Method = v.Method
u.Params = append(u.Params, v.Params.Txid)
u.Params = append(u.Params, n)
default:
{
v := reflect.ValueOf(v).Elem()
f := v.FieldByName("Method")
if !f.IsValid() || f.Kind() != reflect.String {
return nil, ErrInvalidValue
}
u.Method = f.String()
f = v.FieldByName("Params")
if f.IsValid() {
var arr []interface{}
switch f.Kind() {
case reflect.Slice:
arr = make([]interface{}, f.Len())
for i := 0; i < f.Len(); i++ {
arr[i] = f.Index(i).Interface()
}
case reflect.Struct:
arr = make([]interface{}, f.NumField())
for i := 0; i < f.NumField(); i++ {
arr[i] = f.Field(i).Interface()
}
default:
return nil, ErrInvalidValue
}
u.Params = arr
}
}
}
d, err := json.Marshal(u)
if err != nil {
return nil, err
}
return d, nil
}
type cmdUntypedParams struct {
Method string `json:"method"`
Params []interface{} `json:"params,omitempty"`
}