-
Notifications
You must be signed in to change notification settings - Fork 11
/
codecs.go
92 lines (77 loc) · 1.95 KB
/
codecs.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
package jsonrpc2
import (
"encoding/json"
"io"
"github.com/vipnode/vipnode/internal/pretty"
)
type rwc struct {
io.Reader
io.Writer
io.Closer
}
// Codec is an straction for receiving and sending JSONRPC messages.
type Codec interface {
ReadMessage() (*Message, error)
WriteMessage(*Message) error
Close() error
RemoteAddr() string
}
var _ Codec = &jsonCodec{}
// IOCodec returns a Codec that wraps JSON encoding and decoding over IO.
func IOCodec(rwc io.ReadWriteCloser) *jsonCodec {
return &jsonCodec{
rwc: rwc,
}
}
type jsonCodec struct {
rwc io.ReadWriteCloser
remoteAddr string
}
func (codec *jsonCodec) RemoteAddr() string {
return codec.remoteAddr
}
func (codec *jsonCodec) ReadMessage() (*Message, error) {
var msg Message
err := json.NewDecoder(codec.rwc).Decode(&msg)
return &msg, err
}
func (codec *jsonCodec) WriteMessage(msg *Message) error {
return json.NewEncoder(codec.rwc).Encode(msg)
}
func (codec *jsonCodec) Close() error {
return codec.rwc.Close()
}
// DebugCodec logs each incoming and outgoing message with a given label prefix
// (use something like the IP address or user ID).
func DebugCodec(labelPrefix string, codec Codec) *debugCodec {
return &debugCodec{
Codec: codec,
Label: labelPrefix,
}
}
type debugCodec struct {
Codec
Label string
}
func (codec *debugCodec) ReadMessage() (*Message, error) {
msg, err := codec.Codec.ReadMessage()
dump, _ := json.Marshal(msg)
out := pretty.Abbrev(string(dump), 100)
if err != nil {
logger.Printf("%s <- Error(%q) - %s\n", codec.Label, err.Error(), out)
} else {
logger.Printf("%s <- %s\n", codec.Label, out)
}
return msg, err
}
func (codec *debugCodec) WriteMessage(msg *Message) error {
err := codec.Codec.WriteMessage(msg)
dump, _ := json.Marshal(msg)
out := pretty.Abbrev(string(dump), 100)
if err != nil {
logger.Printf("%s -> Error(%q) - %s\n", codec.Label, err.Error(), out)
} else {
logger.Printf("%s -> %s\n", codec.Label, out)
}
return err
}