-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathencode.go
102 lines (90 loc) · 2.31 KB
/
encode.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
97
98
99
100
101
102
package goresp
import (
"errors"
"strconv"
)
var (
ErrUnsupportedType = errors.New("Unsupported Type")
crlf = []byte{'\r', '\n'}
)
func encodeNil() []byte {
return []byte{'$', '-', '1', '\r', '\n'}
}
func encodeError(e error) []byte {
err := e.Error()
encoded := append([]byte{'-'}, err...)
encoded = append(encoded, crlf...)
return encoded
}
func encodeInteger(i int64) []byte {
size := strconv.FormatInt(i, 10)
encoded := append([]byte{':'}, size...)
encoded = append(encoded, crlf...)
return encoded
}
func encodeUnsignedInteger(i uint64) []byte {
size := strconv.FormatUint(i, 10)
encoded := append([]byte{':'}, size...)
encoded = append(encoded, crlf...)
return encoded
}
func encodeSimpleString(s string) []byte {
encoded := append([]byte{'+'}, s...)
encoded = append(encoded, crlf...)
return encoded
}
func encodeBulkString(b []byte) []byte {
size := strconv.Itoa(len(b))
encoded := append([]byte{'$'}, size...)
encoded = append(encoded, crlf...)
encoded = append(encoded, b...)
encoded = append(encoded, crlf...)
return encoded
}
func encodeArray(a []interface{}) ([]byte, error) {
size := strconv.Itoa(len(a))
encoded := append([]byte{'*'}, size...)
encoded = append(encoded, crlf...)
for _, element := range a {
encodedElement, err := Marshal(element)
if err != nil {
return nil, err
}
encoded = append(encoded, encodedElement...)
}
return encoded, nil
}
func Marshal(v interface{}) ([]byte, error) {
switch v.(type) {
case nil:
return encodeNil(), nil
case int:
return encodeInteger(int64(v.(int))), nil
case int8:
return encodeInteger(int64(v.(int8))), nil
case int16:
return encodeInteger(int64(v.(int16))), nil
case int32:
return encodeInteger(int64(v.(int32))), nil
case int64:
return encodeInteger(v.(int64)), nil
case uint8:
return encodeUnsignedInteger(uint64(v.(uint8))), nil
case uint16:
return encodeUnsignedInteger(uint64(v.(uint16))), nil
case uint32:
return encodeUnsignedInteger(uint64(v.(uint32))), nil
case uint64:
return encodeUnsignedInteger(v.(uint64)), nil
case string:
return encodeSimpleString(v.(string)), nil
case []byte:
return encodeBulkString(v.([]byte)), nil
case error:
return encodeError(v.(error)), nil
case []interface{}:
return encodeArray(v.([]interface{}))
default:
return nil, ErrUnsupportedType
}
}