123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- // Copyright 2010 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package proto
- /*
- * Routines for decoding protocol buffer data to construct in-memory representations.
- */
- import (
- "errors"
- "fmt"
- "io"
- )
- // errOverflow is returned when an integer is too large to be represented.
- var errOverflow = errors.New("proto: integer overflow")
- // DecodeVarint reads a varint-encoded integer from the slice.
- // It returns the integer and the number of bytes consumed, or
- // zero if there is not enough.
- // This is the format for the
- // int32, int64, uint32, uint64, bool, and enum
- // protocol buffer types.
- func DecodeVarint(buf []byte) (x uint64, n int) {
- for shift := uint(0); shift < 64; shift += 7 {
- if n >= len(buf) {
- return 0, 0
- }
- b := uint64(buf[n])
- n++
- x |= (b & 0x7F) << shift
- if (b & 0x80) == 0 {
- return x, n
- }
- }
- // The number is too large to represent in a 64-bit value.
- return 0, 0
- }
- func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
- i := p.index
- l := len(p.buf)
- for shift := uint(0); shift < 64; shift += 7 {
- if i >= l {
- err = io.ErrUnexpectedEOF
- return
- }
- b := p.buf[i]
- i++
- x |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- p.index = i
- return
- }
- }
- // The number is too large to represent in a 64-bit value.
- err = errOverflow
- return
- }
- // DecodeVarint reads a varint-encoded integer from the Buffer.
- // This is the format for the
- // int32, int64, uint32, uint64, bool, and enum
- // protocol buffer types.
- func (p *Buffer) DecodeVarint() (x uint64, err error) {
- i := p.index
- buf := p.buf
- if i >= len(buf) {
- return 0, io.ErrUnexpectedEOF
- } else if buf[i] < 0x80 {
- p.index++
- return uint64(buf[i]), nil
- } else if len(buf)-i < 10 {
- return p.decodeVarintSlow()
- }
- var b uint64
- // we already checked the first byte
- x = uint64(buf[i]) - 0x80
- i++
- b = uint64(buf[i])
- i++
- x += b << 7
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 7
- b = uint64(buf[i])
- i++
- x += b << 14
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 14
- b = uint64(buf[i])
- i++
- x += b << 21
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 21
- b = uint64(buf[i])
- i++
- x += b << 28
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 28
- b = uint64(buf[i])
- i++
- x += b << 35
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 35
- b = uint64(buf[i])
- i++
- x += b << 42
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 42
- b = uint64(buf[i])
- i++
- x += b << 49
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 49
- b = uint64(buf[i])
- i++
- x += b << 56
- if b&0x80 == 0 {
- goto done
- }
- x -= 0x80 << 56
- b = uint64(buf[i])
- i++
- x += b << 63
- if b&0x80 == 0 {
- goto done
- }
- return 0, errOverflow
- done:
- p.index = i
- return x, nil
- }
- // DecodeFixed64 reads a 64-bit integer from the Buffer.
- // This is the format for the
- // fixed64, sfixed64, and double protocol buffer types.
- func (p *Buffer) DecodeFixed64() (x uint64, err error) {
- // x, err already 0
- i := p.index + 8
- if i < 0 || i > len(p.buf) {
- err = io.ErrUnexpectedEOF
- return
- }
- p.index = i
- x = uint64(p.buf[i-8])
- x |= uint64(p.buf[i-7]) << 8
- x |= uint64(p.buf[i-6]) << 16
- x |= uint64(p.buf[i-5]) << 24
- x |= uint64(p.buf[i-4]) << 32
- x |= uint64(p.buf[i-3]) << 40
- x |= uint64(p.buf[i-2]) << 48
- x |= uint64(p.buf[i-1]) << 56
- return
- }
- // DecodeFixed32 reads a 32-bit integer from the Buffer.
- // This is the format for the
- // fixed32, sfixed32, and float protocol buffer types.
- func (p *Buffer) DecodeFixed32() (x uint64, err error) {
- // x, err already 0
- i := p.index + 4
- if i < 0 || i > len(p.buf) {
- err = io.ErrUnexpectedEOF
- return
- }
- p.index = i
- x = uint64(p.buf[i-4])
- x |= uint64(p.buf[i-3]) << 8
- x |= uint64(p.buf[i-2]) << 16
- x |= uint64(p.buf[i-1]) << 24
- return
- }
- // DecodeZigzag64 reads a zigzag-encoded 64-bit integer
- // from the Buffer.
- // This is the format used for the sint64 protocol buffer type.
- func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
- x, err = p.DecodeVarint()
- if err != nil {
- return
- }
- x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
- return
- }
- // DecodeZigzag32 reads a zigzag-encoded 32-bit integer
- // from the Buffer.
- // This is the format used for the sint32 protocol buffer type.
- func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
- x, err = p.DecodeVarint()
- if err != nil {
- return
- }
- x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
- return
- }
- // DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
- // This is the format used for the bytes protocol buffer
- // type and for embedded messages.
- func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
- n, err := p.DecodeVarint()
- if err != nil {
- return nil, err
- }
- nb := int(n)
- if nb < 0 {
- return nil, fmt.Errorf("proto: bad byte length %d", nb)
- }
- end := p.index + nb
- if end < p.index || end > len(p.buf) {
- return nil, io.ErrUnexpectedEOF
- }
- if !alloc {
- // todo: check if can get more uses of alloc=false
- buf = p.buf[p.index:end]
- p.index += nb
- return
- }
- buf = make([]byte, nb)
- copy(buf, p.buf[p.index:])
- p.index += nb
- return
- }
- // DecodeStringBytes reads an encoded string from the Buffer.
- // This is the format used for the proto2 string type.
- func (p *Buffer) DecodeStringBytes() (s string, err error) {
- buf, err := p.DecodeRawBytes(false)
- if err != nil {
- return
- }
- return string(buf), nil
- }
- // Unmarshaler is the interface representing objects that can
- // unmarshal themselves. The argument points to data that may be
- // overwritten, so implementations should not keep references to the
- // buffer.
- // Unmarshal implementations should not clear the receiver.
- // Any unmarshaled data should be merged into the receiver.
- // Callers of Unmarshal that do not want to retain existing data
- // should Reset the receiver before calling Unmarshal.
- type Unmarshaler interface {
- Unmarshal([]byte) error
- }
- // newUnmarshaler is the interface representing objects that can
- // unmarshal themselves. The semantics are identical to Unmarshaler.
- //
- // This exists to support protoc-gen-go generated messages.
- // The proto package will stop type-asserting to this interface in the future.
- //
- // DO NOT DEPEND ON THIS.
- type newUnmarshaler interface {
- XXX_Unmarshal([]byte) error
- }
- // Unmarshal parses the protocol buffer representation in buf and places the
- // decoded result in pb. If the struct underlying pb does not match
- // the data in buf, the results can be unpredictable.
- //
- // Unmarshal resets pb before starting to unmarshal, so any
- // existing data in pb is always removed. Use UnmarshalMerge
- // to preserve and append to existing data.
- func Unmarshal(buf []byte, pb Message) error {
- pb.Reset()
- if u, ok := pb.(newUnmarshaler); ok {
- return u.XXX_Unmarshal(buf)
- }
- if u, ok := pb.(Unmarshaler); ok {
- return u.Unmarshal(buf)
- }
- return NewBuffer(buf).Unmarshal(pb)
- }
- // UnmarshalMerge parses the protocol buffer representation in buf and
- // writes the decoded result to pb. If the struct underlying pb does not match
- // the data in buf, the results can be unpredictable.
- //
- // UnmarshalMerge merges into existing data in pb.
- // Most code should use Unmarshal instead.
- func UnmarshalMerge(buf []byte, pb Message) error {
- if u, ok := pb.(newUnmarshaler); ok {
- return u.XXX_Unmarshal(buf)
- }
- if u, ok := pb.(Unmarshaler); ok {
- // NOTE: The history of proto have unfortunately been inconsistent
- // whether Unmarshaler should or should not implicitly clear itself.
- // Some implementations do, most do not.
- // Thus, calling this here may or may not do what people want.
- //
- // See https://github.com/golang/protobuf/issues/424
- return u.Unmarshal(buf)
- }
- return NewBuffer(buf).Unmarshal(pb)
- }
- // DecodeMessage reads a count-delimited message from the Buffer.
- func (p *Buffer) DecodeMessage(pb Message) error {
- enc, err := p.DecodeRawBytes(false)
- if err != nil {
- return err
- }
- return NewBuffer(enc).Unmarshal(pb)
- }
- // DecodeGroup reads a tag-delimited group from the Buffer.
- // StartGroup tag is already consumed. This function consumes
- // EndGroup tag.
- func (p *Buffer) DecodeGroup(pb Message) error {
- b := p.buf[p.index:]
- x, y := findEndGroup(b)
- if x < 0 {
- return io.ErrUnexpectedEOF
- }
- err := Unmarshal(b[:x], pb)
- p.index += y
- return err
- }
- // Unmarshal parses the protocol buffer representation in the
- // Buffer and places the decoded result in pb. If the struct
- // underlying pb does not match the data in the buffer, the results can be
- // unpredictable.
- //
- // Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
- func (p *Buffer) Unmarshal(pb Message) error {
- // If the object can unmarshal itself, let it.
- if u, ok := pb.(newUnmarshaler); ok {
- err := u.XXX_Unmarshal(p.buf[p.index:])
- p.index = len(p.buf)
- return err
- }
- if u, ok := pb.(Unmarshaler); ok {
- // NOTE: The history of proto have unfortunately been inconsistent
- // whether Unmarshaler should or should not implicitly clear itself.
- // Some implementations do, most do not.
- // Thus, calling this here may or may not do what people want.
- //
- // See https://github.com/golang/protobuf/issues/424
- err := u.Unmarshal(p.buf[p.index:])
- p.index = len(p.buf)
- return err
- }
- // Slow workaround for messages that aren't Unmarshalers.
- // This includes some hand-coded .pb.go files and
- // bootstrap protos.
- // TODO: fix all of those and then add Unmarshal to
- // the Message interface. Then:
- // The cast above and code below can be deleted.
- // The old unmarshaler can be deleted.
- // Clients can call Unmarshal directly (can already do that, actually).
- var info InternalMessageInfo
- err := info.Unmarshal(pb, p.buf[p.index:])
- p.index = len(p.buf)
- return err
- }
|