-
Notifications
You must be signed in to change notification settings - Fork 0
/
command.go
78 lines (66 loc) · 1.65 KB
/
command.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
package memcached
import (
"bufio"
"fmt"
"strings"
)
type command struct {
keys []string
delta uint64
name, key string
flags, exptime, byteLen, casUnique int
noReply bool
}
func parseCmd(cmdName string, r *bufio.Reader) (cmd *command, err error) {
cmd = &command{name: cmdName}
ln, err := r.ReadString('\n')
if err != nil {
return
}
ln = strings.TrimSpace(ln)
switch cmdName {
case cmdGet:
fallthrough
case cmdGets:
cmd.keys = strings.Split(ln, " ")
case cmdDel:
cmd.noReply, err = parseLine(ln, "%s", &cmd.key)
case cmdFlushAll:
case cmdIncr:
fallthrough
case cmdDecr:
cmd.noReply, err = parseLine(ln, "%s %d", &cmd.key, &cmd.delta)
case cmdCas:
cmd.noReply, err = parseLine(ln, "%s %d %d %d", &cmd.key, &cmd.exptime, &cmd.byteLen, &cmd.casUnique)
case cmdTouch:
cmd.noReply, err = parseLine(ln, "%s %d", &cmd.key, &cmd.exptime)
case cmdAppend:
fallthrough
case cmdPrepend:
fallthrough
case cmdReplace:
fallthrough
case cmdAdd:
fallthrough
case cmdSet:
cmd.noReply, err = parseLine(ln, "%s %d %d %d", &cmd.key, &cmd.flags, &cmd.exptime, &cmd.byteLen)
default:
err = ErrUnknownCommand
}
return
}
func isNoReply(lineFmt string, actual string) bool {
return strings.Count(lineFmt, " ") > strings.Count(actual, " ")
}
func parseLine(ln string, lineFmt string, vars ...interface{}) (noReply bool, err error) {
defer func() {
if r := recover(); r != nil {
err = ErrInvalidCommand
}
}()
if _, err = fmt.Sscanf(ln, lineFmt, vars...); err != nil {
return
}
noReply = strings.Count(ln, " ") > 3
return
}