123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- // Copyright 2019 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
- import (
- "errors"
- "fmt"
- "google.golang.org/protobuf/encoding/prototext"
- "google.golang.org/protobuf/encoding/protowire"
- "google.golang.org/protobuf/runtime/protoimpl"
- )
- const (
- WireVarint = 0
- WireFixed32 = 5
- WireFixed64 = 1
- WireBytes = 2
- WireStartGroup = 3
- WireEndGroup = 4
- )
- // EncodeVarint returns the varint encoded bytes of v.
- func EncodeVarint(v uint64) []byte {
- return protowire.AppendVarint(nil, v)
- }
- // SizeVarint returns the length of the varint encoded bytes of v.
- // This is equal to len(EncodeVarint(v)).
- func SizeVarint(v uint64) int {
- return protowire.SizeVarint(v)
- }
- // DecodeVarint parses a varint encoded integer from b,
- // returning the integer value and the length of the varint.
- // It returns (0, 0) if there is a parse error.
- func DecodeVarint(b []byte) (uint64, int) {
- v, n := protowire.ConsumeVarint(b)
- if n < 0 {
- return 0, 0
- }
- return v, n
- }
- // Buffer is a buffer for encoding and decoding the protobuf wire format.
- // It may be reused between invocations to reduce memory usage.
- type Buffer struct {
- buf []byte
- idx int
- deterministic bool
- }
- // NewBuffer allocates a new Buffer initialized with buf,
- // where the contents of buf are considered the unread portion of the buffer.
- func NewBuffer(buf []byte) *Buffer {
- return &Buffer{buf: buf}
- }
- // SetDeterministic specifies whether to use deterministic serialization.
- //
- // Deterministic serialization guarantees that for a given binary, equal
- // messages will always be serialized to the same bytes. This implies:
- //
- // - Repeated serialization of a message will return the same bytes.
- // - Different processes of the same binary (which may be executing on
- // different machines) will serialize equal messages to the same bytes.
- //
- // Note that the deterministic serialization is NOT canonical across
- // languages. It is not guaranteed to remain stable over time. It is unstable
- // across different builds with schema changes due to unknown fields.
- // Users who need canonical serialization (e.g., persistent storage in a
- // canonical form, fingerprinting, etc.) should define their own
- // canonicalization specification and implement their own serializer rather
- // than relying on this API.
- //
- // If deterministic serialization is requested, map entries will be sorted
- // by keys in lexographical order. This is an implementation detail and
- // subject to change.
- func (b *Buffer) SetDeterministic(deterministic bool) {
- b.deterministic = deterministic
- }
- // SetBuf sets buf as the internal buffer,
- // where the contents of buf are considered the unread portion of the buffer.
- func (b *Buffer) SetBuf(buf []byte) {
- b.buf = buf
- b.idx = 0
- }
- // Reset clears the internal buffer of all written and unread data.
- func (b *Buffer) Reset() {
- b.buf = b.buf[:0]
- b.idx = 0
- }
- // Bytes returns the internal buffer.
- func (b *Buffer) Bytes() []byte {
- return b.buf
- }
- // Unread returns the unread portion of the buffer.
- func (b *Buffer) Unread() []byte {
- return b.buf[b.idx:]
- }
- // Marshal appends the wire-format encoding of m to the buffer.
- func (b *Buffer) Marshal(m Message) error {
- var err error
- b.buf, err = marshalAppend(b.buf, m, b.deterministic)
- return err
- }
- // Unmarshal parses the wire-format message in the buffer and
- // places the decoded results in m.
- // It does not reset m before unmarshaling.
- func (b *Buffer) Unmarshal(m Message) error {
- err := UnmarshalMerge(b.Unread(), m)
- b.idx = len(b.buf)
- return err
- }
- type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields }
- func (m *unknownFields) String() string { panic("not implemented") }
- func (m *unknownFields) Reset() { panic("not implemented") }
- func (m *unknownFields) ProtoMessage() { panic("not implemented") }
- // DebugPrint dumps the encoded bytes of b with a header and footer including s
- // to stdout. This is only intended for debugging.
- func (*Buffer) DebugPrint(s string, b []byte) {
- m := MessageReflect(new(unknownFields))
- m.SetUnknown(b)
- b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface())
- fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s)
- }
- // EncodeVarint appends an unsigned varint encoding to the buffer.
- func (b *Buffer) EncodeVarint(v uint64) error {
- b.buf = protowire.AppendVarint(b.buf, v)
- return nil
- }
- // EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer.
- func (b *Buffer) EncodeZigzag32(v uint64) error {
- return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
- }
- // EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer.
- func (b *Buffer) EncodeZigzag64(v uint64) error {
- return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63))))
- }
- // EncodeFixed32 appends a 32-bit little-endian integer to the buffer.
- func (b *Buffer) EncodeFixed32(v uint64) error {
- b.buf = protowire.AppendFixed32(b.buf, uint32(v))
- return nil
- }
- // EncodeFixed64 appends a 64-bit little-endian integer to the buffer.
- func (b *Buffer) EncodeFixed64(v uint64) error {
- b.buf = protowire.AppendFixed64(b.buf, uint64(v))
- return nil
- }
- // EncodeRawBytes appends a length-prefixed raw bytes to the buffer.
- func (b *Buffer) EncodeRawBytes(v []byte) error {
- b.buf = protowire.AppendBytes(b.buf, v)
- return nil
- }
- // EncodeStringBytes appends a length-prefixed raw bytes to the buffer.
- // It does not validate whether v contains valid UTF-8.
- func (b *Buffer) EncodeStringBytes(v string) error {
- b.buf = protowire.AppendString(b.buf, v)
- return nil
- }
- // EncodeMessage appends a length-prefixed encoded message to the buffer.
- func (b *Buffer) EncodeMessage(m Message) error {
- var err error
- b.buf = protowire.AppendVarint(b.buf, uint64(Size(m)))
- b.buf, err = marshalAppend(b.buf, m, b.deterministic)
- return err
- }
- // DecodeVarint consumes an encoded unsigned varint from the buffer.
- func (b *Buffer) DecodeVarint() (uint64, error) {
- v, n := protowire.ConsumeVarint(b.buf[b.idx:])
- if n < 0 {
- return 0, protowire.ParseError(n)
- }
- b.idx += n
- return uint64(v), nil
- }
- // DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer.
- func (b *Buffer) DecodeZigzag32() (uint64, error) {
- v, err := b.DecodeVarint()
- if err != nil {
- return 0, err
- }
- return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil
- }
- // DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer.
- func (b *Buffer) DecodeZigzag64() (uint64, error) {
- v, err := b.DecodeVarint()
- if err != nil {
- return 0, err
- }
- return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil
- }
- // DecodeFixed32 consumes a 32-bit little-endian integer from the buffer.
- func (b *Buffer) DecodeFixed32() (uint64, error) {
- v, n := protowire.ConsumeFixed32(b.buf[b.idx:])
- if n < 0 {
- return 0, protowire.ParseError(n)
- }
- b.idx += n
- return uint64(v), nil
- }
- // DecodeFixed64 consumes a 64-bit little-endian integer from the buffer.
- func (b *Buffer) DecodeFixed64() (uint64, error) {
- v, n := protowire.ConsumeFixed64(b.buf[b.idx:])
- if n < 0 {
- return 0, protowire.ParseError(n)
- }
- b.idx += n
- return uint64(v), nil
- }
- // DecodeRawBytes consumes a length-prefixed raw bytes from the buffer.
- // If alloc is specified, it returns a copy the raw bytes
- // rather than a sub-slice of the buffer.
- func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) {
- v, n := protowire.ConsumeBytes(b.buf[b.idx:])
- if n < 0 {
- return nil, protowire.ParseError(n)
- }
- b.idx += n
- if alloc {
- v = append([]byte(nil), v...)
- }
- return v, nil
- }
- // DecodeStringBytes consumes a length-prefixed raw bytes from the buffer.
- // It does not validate whether the raw bytes contain valid UTF-8.
- func (b *Buffer) DecodeStringBytes() (string, error) {
- v, n := protowire.ConsumeString(b.buf[b.idx:])
- if n < 0 {
- return "", protowire.ParseError(n)
- }
- b.idx += n
- return v, nil
- }
- // DecodeMessage consumes a length-prefixed message from the buffer.
- // It does not reset m before unmarshaling.
- func (b *Buffer) DecodeMessage(m Message) error {
- v, err := b.DecodeRawBytes(false)
- if err != nil {
- return err
- }
- return UnmarshalMerge(v, m)
- }
- // DecodeGroup consumes a message group from the buffer.
- // It assumes that the start group marker has already been consumed and
- // consumes all bytes until (and including the end group marker).
- // It does not reset m before unmarshaling.
- func (b *Buffer) DecodeGroup(m Message) error {
- v, n, err := consumeGroup(b.buf[b.idx:])
- if err != nil {
- return err
- }
- b.idx += n
- return UnmarshalMerge(v, m)
- }
- // consumeGroup parses b until it finds an end group marker, returning
- // the raw bytes of the message (excluding the end group marker) and the
- // the total length of the message (including the end group marker).
- func consumeGroup(b []byte) ([]byte, int, error) {
- b0 := b
- depth := 1 // assume this follows a start group marker
- for {
- _, wtyp, tagLen := protowire.ConsumeTag(b)
- if tagLen < 0 {
- return nil, 0, protowire.ParseError(tagLen)
- }
- b = b[tagLen:]
- var valLen int
- switch wtyp {
- case protowire.VarintType:
- _, valLen = protowire.ConsumeVarint(b)
- case protowire.Fixed32Type:
- _, valLen = protowire.ConsumeFixed32(b)
- case protowire.Fixed64Type:
- _, valLen = protowire.ConsumeFixed64(b)
- case protowire.BytesType:
- _, valLen = protowire.ConsumeBytes(b)
- case protowire.StartGroupType:
- depth++
- case protowire.EndGroupType:
- depth--
- default:
- return nil, 0, errors.New("proto: cannot parse reserved wire type")
- }
- if valLen < 0 {
- return nil, 0, protowire.ParseError(valLen)
- }
- b = b[valLen:]
- if depth == 0 {
- return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil
- }
- }
- }
|