Last active
December 17, 2015 13:29
-
-
Save fizx/5617728 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
/** | |
* This is a little too permissive (and hacked together), but it illustrates | |
* the point of encoding a bufio.Scanner that is stateful, so that it can | |
* parse the redis protocol. | |
*/ | |
import ( | |
"bufio" | |
"bytes" | |
"fmt" | |
"strconv" | |
) | |
const ( | |
Marker = iota | |
Int | |
Content | |
) | |
func newScanFunc() bufio.SplitFunc { | |
expected := Marker | |
var tmp int64 = -1 | |
size := -1 | |
dollar := false | |
return func(data []byte, atEOF bool) (advance int, token []byte, err error) { | |
switch expected { | |
case Marker: | |
fmt.Println("parsing marker") | |
advance, token, err = bufio.ScanBytes(data, atEOF) | |
expected = Int | |
dollar = !atEOF && data[0] == '$' | |
case Int: | |
fmt.Println("parsing int") | |
advance, token, err = bufio.ScanWords(data, atEOF) | |
advance += 1 | |
if dollar { | |
tmp, err = strconv.ParseInt(string(token), 10, 32) | |
size = int(tmp) | |
expected = Content | |
} else { | |
expected = Marker | |
} | |
case Content: | |
fmt.Println("parsing content") | |
if len(data) < size { | |
if atEOF { | |
return 0, nil, fmt.Errorf("incomplete message at EOF") | |
} else { | |
return 0, nil, nil // ask to try again with more data | |
} | |
} else { | |
advance = size + 2 | |
token = data[:size] | |
expected = Marker | |
} | |
} | |
return | |
} | |
} | |
func main() { | |
reader := bytes.NewBufferString("*1\r\n$11\r\nhello world\r\n*1\r\n$13\r\ngoodbye world\r\n") | |
scanner := bufio.NewScanner(reader) | |
scanner.Split(newScanFunc()) | |
for scanner.Scan() { | |
fmt.Println(scanner.Text()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment