66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
|
|
package internal
|
||
|
|
|
||
|
|
// Minimal protobuf wire helpers (bytes/string fields only).
|
||
|
|
|
||
|
|
const (
|
||
|
|
errCodeOverflow = -2
|
||
|
|
errCodeTruncated = -1
|
||
|
|
)
|
||
|
|
|
||
|
|
func consumeVarint(b []byte) (uint64, int) {
|
||
|
|
var x uint64
|
||
|
|
var s uint
|
||
|
|
for i, c := range b {
|
||
|
|
if c < 0x80 {
|
||
|
|
if i > 9 || i == 9 && c > 1 {
|
||
|
|
return 0, errCodeOverflow
|
||
|
|
}
|
||
|
|
return x | uint64(c)<<s, i + 1
|
||
|
|
}
|
||
|
|
x |= uint64(c&0x7f) << s
|
||
|
|
s += 7
|
||
|
|
}
|
||
|
|
return 0, errCodeTruncated
|
||
|
|
}
|
||
|
|
|
||
|
|
// ConsumeBytes parses a length-delimited bytes field.
|
||
|
|
func ConsumeBytes(b []byte) ([]byte, int) {
|
||
|
|
v, n := consumeVarint(b)
|
||
|
|
if n < 0 {
|
||
|
|
return nil, n
|
||
|
|
}
|
||
|
|
if v > uint64(len(b)-n) {
|
||
|
|
return nil, errCodeOverflow
|
||
|
|
}
|
||
|
|
return b[n : n+int(v)], n + int(v)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ConsumeString parses a length-delimited string field.
|
||
|
|
func ConsumeString(b []byte) (string, int) {
|
||
|
|
v, n := ConsumeBytes(b)
|
||
|
|
if n < 0 {
|
||
|
|
return "", n
|
||
|
|
}
|
||
|
|
return string(v), n
|
||
|
|
}
|
||
|
|
|
||
|
|
func parseError(code int) error {
|
||
|
|
switch code {
|
||
|
|
case errCodeOverflow:
|
||
|
|
return errOverflow
|
||
|
|
case errCodeTruncated:
|
||
|
|
return errTruncated
|
||
|
|
default:
|
||
|
|
return errTruncated
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var (
|
||
|
|
errOverflow = &parseErr{"overflow"}
|
||
|
|
errTruncated = &parseErr{"truncated"}
|
||
|
|
)
|
||
|
|
|
||
|
|
type parseErr struct{ msg string }
|
||
|
|
|
||
|
|
func (e *parseErr) Error() string { return "protowire: " + e.msg }
|