/
scanner.go
41 lines (34 loc) · 1.03 KB
/
scanner.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
package scanner
import (
"bufio"
"bytes"
"encoding/binary"
"io"
)
// needMoreData returns the requisite values to get the bufio.Scanner to send more data to
// the splitter.
// http://pkg.golang.org/pkg/bufio/#SplitFunc
func needMoreData() (int, []byte, error) { return 0, nil, nil }
const headerSize = 12
// New returns a new Scanner that parses a Reader as the Gearman protocol.
// See: http://gearman.org/protocol/
func New(r io.Reader) *bufio.Scanner {
scanner := bufio.NewScanner(r)
scanner.Split(func(data []byte, atEOF bool) (int, []byte, error) {
if len(data) < headerSize {
return needMoreData()
}
var size int32
if err := binary.Read(bytes.NewBuffer(data[8:12]), binary.BigEndian, &size); err != nil {
return 0, nil, err
}
if len(data) < headerSize+int(size) {
return needMoreData()
}
// bufio.Scanner reuses these bytes, so make sure we copy them.
var packet = make([]byte, int(headerSize+size))
copy(packet, data[0:headerSize+size])
return int(headerSize + size), packet, nil
})
return scanner
}