1
0
mirror of https://github.com/fumiama/go-simple-protobuf.git synced 2026-06-08 03:53:49 +08:00
Files
go-simple-protobuf/spb.go
源文雨 751fa4688d init
2022-10-27 15:25:16 +08:00

88 lines
1.3 KiB
Go

package spb
import "io"
func ReadNum(r io.Reader) (n uint32, cnt int, err error) {
var buf [1]byte
for cnt < 5 {
_, err = r.Read(buf[:])
if err != nil {
return
}
n |= uint32(buf[0]&0x7f) << (7 * cnt)
cnt++
if buf[0]&0x80 == 0 {
break
}
}
return
}
/*
func WriteNum(w io.Writer, n uint32) (cnt int, err error) {
var buf [1]byte
for n > 0 {
buf[0] = uint8(n & 0x7f)
if n>>7 > 0 {
buf[0] |= 0x80
}
_, err = w.Write(buf[:])
if err != nil {
return
}
n >>= 7
cnt++
}
return
}
*/
type SimplePB struct {
StructLen, RealLen uint32
Target [][]byte
}
func NewSimplePB(r io.Reader) (s SimplePB, err error) {
cnt := 0
s.StructLen, cnt, err = ReadNum(r)
if err != nil {
s.RealLen = uint32(cnt)
return
}
if s.StructLen <= 1 || s.StructLen >= uint32(1)<<20 {
err = ErrInvalidStructLen
s.RealLen = uint32(cnt)
return
}
var offset, datalen uint32
n := 0
for i := uint32(0); i < s.StructLen; i += offset {
offset, n, err = ReadNum(r)
cnt += n
if err != nil {
break
}
datalen, n, err = ReadNum(r)
cnt += n
if err != nil {
break
}
if datalen == 0 {
break
}
if datalen > offset {
err = ErrInvalidDataLen
break
}
t := make([]byte, datalen)
n, err = r.Read(t)
cnt += n
if err != nil {
break
}
s.Target = append(s.Target, t)
}
s.RealLen = uint32(cnt)
return
}