encoding.go
1package sync
2
3import "errors"
4
5const (
6 MessageSync uint8 = 0
7 MessageAwareness uint8 = 1
8 MessageAuth uint8 = 2
9 MessageAwarenessQuery uint8 = 3
10)
11
12const (
13 SyncStep1 uint8 = 0
14 SyncStep2 uint8 = 1
15 Update uint8 = 2
16)
17
18func writeVarUint(b []byte, v uint64) int {
19 i := 0
20 for {
21 b[i] = byte(v & 0x7f)
22 v >>= 7
23 if v == 0 {
24 i++
25 break
26 }
27 b[i] |= 0x80
28 i++
29 }
30 return i
31}
32
33func readVarUint(b []byte) (uint64, int, error) {
34 if len(b) == 0 {
35 return 0, 0, errors.New("unexpected end of input")
36 }
37 var result uint64
38 var shift uint
39 i := 0
40 for {
41 if i >= len(b) {
42 return 0, 0, errors.New("unexpected end of input")
43 }
44 chunk := uint64(b[i])
45 result |= (chunk & 0x7f) << shift
46 i++
47 if chunk&0x80 == 0 {
48 break
49 }
50 shift += 7
51 if shift > 63 {
52 return 0, 0, errors.New("varint overflow")
53 }
54 }
55 return result, i, nil
56}
57
58func encodeVarByteArray(data []byte) []byte {
59 encoded := make([]byte, 0, 10+len(data))
60 encoded = appendVarUint(encoded, uint64(len(data)))
61 encoded = append(encoded, data...)
62 return encoded
63}
64
65func encodeMessage(msgType uint8, payload []byte) []byte {
66 msg := make([]byte, 0, 2+len(payload))
67 msg = appendVarUint(msg, uint64(msgType))
68 msg = appendVarByteArray(msg, payload)
69 return msg
70}
71
72func encodeSyncMessage(innerType uint8, payload []byte) []byte {
73 msg := make([]byte, 0, 2+len(payload))
74 msg = appendVarUint(msg, uint64(MessageSync))
75 msg = appendVarUint(msg, uint64(innerType))
76 msg = appendVarByteArray(msg, payload)
77 return msg
78}
79
80func encodeAwarenessMessage(payload []byte) []byte {
81 msg := make([]byte, 0, 2+len(payload))
82 msg = appendVarUint(msg, uint64(MessageAwareness))
83 msg = appendVarByteArray(msg, payload)
84 return msg
85}
86
87func appendVarUint(b []byte, v uint64) []byte {
88 var buf [10]byte
89 n := writeVarUint(buf[:], v)
90 return append(b, buf[:n]...)
91}
92
93func appendVarByteArray(b []byte, data []byte) []byte {
94 b = appendVarUint(b, uint64(len(data)))
95 return append(b, data...)
96}