-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbinparser_common.go
More file actions
129 lines (113 loc) · 2.4 KB
/
binparser_common.go
File metadata and controls
129 lines (113 loc) · 2.4 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package binp
import "errors"
// Parser type. Don't touch the internals.
type Parser struct {
r []byte
off int
}
// Create a new parser with the given buffer. Panics on error.
func NewParser(b []byte) *Parser {
return &Parser{b, 0}
}
// Parse a byte from the buffer.
func (p *Parser) Byte(d *byte) *Parser {
if p == nil || len(p.r) < p.off+1 {
return nil
}
*d = p.r[p.off]
p.off++
return p
}
// Parse a byte from the buffer, synonym for .Byte.
func (p *Parser) B8(d *byte) *Parser {
if p == nil || len(p.r) < p.off+1 {
return nil
}
*d = p.r[p.off]
p.off++
return p
}
// Parse a byte from the buffer, synonym for .Byte.
func (p *Parser) N8(d *byte) *Parser {
if p == nil || len(p.r) < p.off+1 {
return nil
}
*d = p.r[p.off]
p.off++
return p
}
// Parse n bytes from the buffer and copy to a []byte pointer that is allocated.
func (p *Parser) NBytes(n int, d *[]byte) *Parser {
if p == nil || n > len(p.r[p.off:]) {
return nil
}
*d = make([]byte, n)
copy(*d, p.r[p.off:])
p.off += n
return p
}
// Parse n bytes from the buffer and copy to the supplied []byte.
func (p *Parser) NBytesCopy(n int, d []byte) *Parser {
if p == nil || n > len(p.r[p.off:]) {
return nil
}
copy(d, p.r[p.off:p.off+n])
p.off += n
return p
}
// Parse n bytes from the buffer to a []byte pointer that refers to the parser internal buffer.
func (p *Parser) NBytesPeek(n int, d *[]byte) *Parser {
if p == nil || n > len(p.r[p.off:]) {
return nil
}
*d = p.r[p.off : p.off+n]
p.off += n
return p
}
// Ensure the input is aligned possibly skipping bytes.
func (p *Parser) Align(n int) *Parser {
if p == nil {
return nil
}
r := p.off % n
if r != 0 {
p.off += n - r
}
return p
}
// Skip bytes.
func (p *Parser) Skip(n int) *Parser {
p.off += n
return p
}
// Parse a null terminated string.
func (p *Parser) String0(d *string) *Parser {
if p == nil {
return nil
}
for i, ch := range p.r[p.off:] {
if ch == 0 {
p.NString(i, d)
p.off++
return p
}
}
panic("String0: null byte not found")
}
// Check that we are at the end of input.
func (p *Parser) End() error {
if p == nil || p.off != len(p.r) {
return eparse
}
return nil
}
var eparse = errors.New("binparser invalid input")
// Check that we are at the end of input.
func (p *Parser) AtEnd() bool {
return p.off == len(p.r)
}
// Peek the rest of input as raw bytes.
func (p *Parser) PeekRest(d *[]byte) *Parser {
*d = p.r[p.off:]
return p
}