Source File
decode.go
Belonging Package
github.com/gogo/protobuf/proto
// Go support for Protocol Buffers - Google's data interchange format//// Copyright 2010 The Go Authors. All rights reserved.// https://github.com/golang/protobuf//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.package proto/** Routines for decoding protocol buffer data to construct in-memory representations.*/import ()// errOverflow is returned when an integer is too large to be represented.var errOverflow = errors.New("proto: integer overflow")// ErrInternalBadWireType is returned by generated code when an incorrect// wire type is encountered. It does not get returned to user code.var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")// 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 ( []byte) ( uint64, int) {for := uint(0); < 64; += 7 {if >= len() {return 0, 0}:= uint64([])++|= ( & 0x7F) <<if ( & 0x80) == 0 {return ,}}// The number is too large to represent in a 64-bit value.return 0, 0}func ( *Buffer) () ( uint64, error) {:= .index:= len(.buf)for := uint(0); < 64; += 7 {if >= {= io.ErrUnexpectedEOFreturn}:= .buf[]++|= (uint64() & 0x7F) <<if < 0x80 {.index =return}}// The number is too large to represent in a 64-bit value.= errOverflowreturn}// 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 ( *Buffer) () ( uint64, error) {:= .index:= .bufif >= len() {return 0, io.ErrUnexpectedEOF} else if [] < 0x80 {.index++return uint64([]), nil} else if len()- < 10 {return .decodeVarintSlow()}var uint64// we already checked the first byte= uint64([]) - 0x80++= uint64([])+++= << 7if &0x80 == 0 {goto}-= 0x80 << 7= uint64([])+++= << 14if &0x80 == 0 {goto}-= 0x80 << 14= uint64([])+++= << 21if &0x80 == 0 {goto}-= 0x80 << 21= uint64([])+++= << 28if &0x80 == 0 {goto}-= 0x80 << 28= uint64([])+++= << 35if &0x80 == 0 {goto}-= 0x80 << 35= uint64([])+++= << 42if &0x80 == 0 {goto}-= 0x80 << 42= uint64([])+++= << 49if &0x80 == 0 {goto}-= 0x80 << 49= uint64([])+++= << 56if &0x80 == 0 {goto}-= 0x80 << 56= uint64([])+++= << 63if &0x80 == 0 {goto}return 0, errOverflow:.index =return , nil}// DecodeFixed64 reads a 64-bit integer from the Buffer.// This is the format for the// fixed64, sfixed64, and double protocol buffer types.func ( *Buffer) () ( uint64, error) {// x, err already 0:= .index + 8if < 0 || > len(.buf) {= io.ErrUnexpectedEOFreturn}.index == uint64(.buf[-8])|= uint64(.buf[-7]) << 8|= uint64(.buf[-6]) << 16|= uint64(.buf[-5]) << 24|= uint64(.buf[-4]) << 32|= uint64(.buf[-3]) << 40|= uint64(.buf[-2]) << 48|= uint64(.buf[-1]) << 56return}// DecodeFixed32 reads a 32-bit integer from the Buffer.// This is the format for the// fixed32, sfixed32, and float protocol buffer types.func ( *Buffer) () ( uint64, error) {// x, err already 0:= .index + 4if < 0 || > len(.buf) {= io.ErrUnexpectedEOFreturn}.index == uint64(.buf[-4])|= uint64(.buf[-3]) << 8|= uint64(.buf[-2]) << 16|= uint64(.buf[-1]) << 24return}// DecodeZigzag64 reads a zigzag-encoded 64-bit integer// from the Buffer.// This is the format used for the sint64 protocol buffer type.func ( *Buffer) () ( uint64, error) {, = .DecodeVarint()if != nil {return}= ( >> 1) ^ uint64((int64(&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 ( *Buffer) () ( uint64, error) {, = .DecodeVarint()if != nil {return}= uint64((uint32() >> 1) ^ uint32((int32(&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 ( *Buffer) ( bool) ( []byte, error) {, := .DecodeVarint()if != nil {return nil,}:= int()if < 0 {return nil, fmt.Errorf("proto: bad byte length %d", )}:= .index +if < .index || > len(.buf) {return nil, io.ErrUnexpectedEOF}if ! {// todo: check if can get more uses of alloc=false= .buf[.index:].index +=return}= make([]byte, )copy(, .buf[.index:]).index +=return}// DecodeStringBytes reads an encoded string from the Buffer.// This is the format used for the proto2 string type.func ( *Buffer) () ( string, error) {, := .DecodeRawBytes(false)if != nil {return}return string(), 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 ( []byte, Message) error {.Reset()if , := .(newUnmarshaler); {return .XXX_Unmarshal()}if , := .(Unmarshaler); {return .Unmarshal()}return NewBuffer().Unmarshal()}// 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 ( []byte, Message) error {if , := .(newUnmarshaler); {return .XXX_Unmarshal()}if , := .(Unmarshaler); {// 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/424return .Unmarshal()}return NewBuffer().Unmarshal()}// DecodeMessage reads a count-delimited message from the Buffer.func ( *Buffer) ( Message) error {, := .DecodeRawBytes(false)if != nil {return}return NewBuffer().Unmarshal()}// DecodeGroup reads a tag-delimited group from the Buffer.// StartGroup tag is already consumed. This function consumes// EndGroup tag.func ( *Buffer) ( Message) error {:= .buf[.index:], := findEndGroup()if < 0 {return io.ErrUnexpectedEOF}:= Unmarshal([:], ).index +=return}// 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 ( *Buffer) ( Message) error {// If the object can unmarshal itself, let it.if , := .(newUnmarshaler); {:= .XXX_Unmarshal(.buf[.index:]).index = len(.buf)return}if , := .(Unmarshaler); {// 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:= .Unmarshal(.buf[.index:]).index = len(.buf)return}// 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 InternalMessageInfo:= .Unmarshal(, .buf[.index:]).index = len(.buf)return}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |