forked from ssdb/gossdb
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconn.go
102 lines (91 loc) · 1.83 KB
/
conn.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 ssdb
import (
"bufio"
"io"
"net"
"strconv"
"time"
)
// Conn a SSDB connection
type Conn struct {
conn net.Conn
r *bufio.Reader
w *bufio.Writer
readWriteTimeout time.Duration
}
func newConn(conn net.Conn, readWriteTimeout time.Duration) *Conn {
return &Conn{
conn: conn,
r: bufio.NewReader(conn),
w: bufio.NewWriter(conn),
readWriteTimeout: readWriteTimeout,
}
}
var zeroTime = time.Time{}
// Send send data
func (c *Conn) Send(args Values) error {
if c.readWriteTimeout != 0 {
if err := c.conn.SetDeadline(time.Now().Add(c.readWriteTimeout)); err == nil {
defer func() {
_ = c.conn.SetDeadline(zeroTime)
}()
}
}
for _, arg := range args {
c.w.Write(strconv.AppendInt(nil, int64(len(arg)), 10))
c.w.WriteByte('\n')
c.w.Write(arg)
c.w.WriteByte('\n')
}
c.w.WriteByte('\n')
return c.w.Flush()
}
// Recv receive data
func (c *Conn) Recv() (Values, error) {
if c.readWriteTimeout != 0 {
if err := c.conn.SetDeadline(time.Now().Add(c.readWriteTimeout)); err == nil {
defer func() {
_ = c.conn.SetDeadline(zeroTime)
}()
}
}
resp := Values{}
loop:
for {
tmp, err := c.r.ReadSlice('\n')
if err != nil {
return nil, err
}
switch len(tmp) {
case 0:
continue loop
case 2:
if tmp[0] == '\r' {
if len(resp) == 0 {
continue loop
}
return resp, nil
}
case 1:
if len(resp) == 0 {
continue loop
}
return resp, nil
}
size, err := strconv.ParseInt(string(tmp[:len(tmp)-1]), 0, 0)
if err != nil || size < 0 {
return nil, err
}
buf := make([]byte, size)
_, err = io.ReadFull(c.r, buf)
if err != nil {
return nil, err
}
resp = append(resp, Value(buf))
c.r.ReadByte()
}
}
// Close Connection
func (c *Conn) Close() error {
return c.conn.Close()
}