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}