mirror of https://github.com/gogits/gogs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
6.1 KiB
203 lines
6.1 KiB
// 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 encoding data into the wire format for protocol buffers. |
|
*/ |
|
|
|
import ( |
|
"errors" |
|
"reflect" |
|
) |
|
|
|
var ( |
|
// errRepeatedHasNil is the error returned if Marshal is called with |
|
// a struct with a repeated field containing a nil element. |
|
errRepeatedHasNil = errors.New("proto: repeated field has nil element") |
|
|
|
// errOneofHasNil is the error returned if Marshal is called with |
|
// a struct with a oneof field containing a nil element. |
|
errOneofHasNil = errors.New("proto: oneof field has nil value") |
|
|
|
// ErrNil is the error returned if Marshal is called with nil. |
|
ErrNil = errors.New("proto: Marshal called with nil") |
|
|
|
// ErrTooLarge is the error returned if Marshal is called with a |
|
// message that encodes to >2GB. |
|
ErrTooLarge = errors.New("proto: message encodes to over 2 GB") |
|
) |
|
|
|
// The fundamental encoders that put bytes on the wire. |
|
// Those that take integer types all accept uint64 and are |
|
// therefore of type valueEncoder. |
|
|
|
const maxVarintBytes = 10 // maximum length of a varint |
|
|
|
// EncodeVarint returns the varint encoding of x. |
|
// This is the format for the |
|
// int32, int64, uint32, uint64, bool, and enum |
|
// protocol buffer types. |
|
// Not used by the package itself, but helpful to clients |
|
// wishing to use the same encoding. |
|
func EncodeVarint(x uint64) []byte { |
|
var buf [maxVarintBytes]byte |
|
var n int |
|
for n = 0; x > 127; n++ { |
|
buf[n] = 0x80 | uint8(x&0x7F) |
|
x >>= 7 |
|
} |
|
buf[n] = uint8(x) |
|
n++ |
|
return buf[0:n] |
|
} |
|
|
|
// EncodeVarint writes a varint-encoded integer to the Buffer. |
|
// This is the format for the |
|
// int32, int64, uint32, uint64, bool, and enum |
|
// protocol buffer types. |
|
func (p *Buffer) EncodeVarint(x uint64) error { |
|
for x >= 1<<7 { |
|
p.buf = append(p.buf, uint8(x&0x7f|0x80)) |
|
x >>= 7 |
|
} |
|
p.buf = append(p.buf, uint8(x)) |
|
return nil |
|
} |
|
|
|
// SizeVarint returns the varint encoding size of an integer. |
|
func SizeVarint(x uint64) int { |
|
switch { |
|
case x < 1<<7: |
|
return 1 |
|
case x < 1<<14: |
|
return 2 |
|
case x < 1<<21: |
|
return 3 |
|
case x < 1<<28: |
|
return 4 |
|
case x < 1<<35: |
|
return 5 |
|
case x < 1<<42: |
|
return 6 |
|
case x < 1<<49: |
|
return 7 |
|
case x < 1<<56: |
|
return 8 |
|
case x < 1<<63: |
|
return 9 |
|
} |
|
return 10 |
|
} |
|
|
|
// EncodeFixed64 writes a 64-bit integer to the Buffer. |
|
// This is the format for the |
|
// fixed64, sfixed64, and double protocol buffer types. |
|
func (p *Buffer) EncodeFixed64(x uint64) error { |
|
p.buf = append(p.buf, |
|
uint8(x), |
|
uint8(x>>8), |
|
uint8(x>>16), |
|
uint8(x>>24), |
|
uint8(x>>32), |
|
uint8(x>>40), |
|
uint8(x>>48), |
|
uint8(x>>56)) |
|
return nil |
|
} |
|
|
|
// EncodeFixed32 writes a 32-bit integer to the Buffer. |
|
// This is the format for the |
|
// fixed32, sfixed32, and float protocol buffer types. |
|
func (p *Buffer) EncodeFixed32(x uint64) error { |
|
p.buf = append(p.buf, |
|
uint8(x), |
|
uint8(x>>8), |
|
uint8(x>>16), |
|
uint8(x>>24)) |
|
return nil |
|
} |
|
|
|
// EncodeZigzag64 writes a zigzag-encoded 64-bit integer |
|
// to the Buffer. |
|
// This is the format used for the sint64 protocol buffer type. |
|
func (p *Buffer) EncodeZigzag64(x uint64) error { |
|
// use signed number to get arithmetic right shift. |
|
return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) |
|
} |
|
|
|
// EncodeZigzag32 writes a zigzag-encoded 32-bit integer |
|
// to the Buffer. |
|
// This is the format used for the sint32 protocol buffer type. |
|
func (p *Buffer) EncodeZigzag32(x uint64) error { |
|
// use signed number to get arithmetic right shift. |
|
return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) |
|
} |
|
|
|
// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. |
|
// This is the format used for the bytes protocol buffer |
|
// type and for embedded messages. |
|
func (p *Buffer) EncodeRawBytes(b []byte) error { |
|
p.EncodeVarint(uint64(len(b))) |
|
p.buf = append(p.buf, b...) |
|
return nil |
|
} |
|
|
|
// EncodeStringBytes writes an encoded string to the Buffer. |
|
// This is the format used for the proto2 string type. |
|
func (p *Buffer) EncodeStringBytes(s string) error { |
|
p.EncodeVarint(uint64(len(s))) |
|
p.buf = append(p.buf, s...) |
|
return nil |
|
} |
|
|
|
// Marshaler is the interface representing objects that can marshal themselves. |
|
type Marshaler interface { |
|
Marshal() ([]byte, error) |
|
} |
|
|
|
// EncodeMessage writes the protocol buffer to the Buffer, |
|
// prefixed by a varint-encoded length. |
|
func (p *Buffer) EncodeMessage(pb Message) error { |
|
siz := Size(pb) |
|
p.EncodeVarint(uint64(siz)) |
|
return p.Marshal(pb) |
|
} |
|
|
|
// All protocol buffer fields are nillable, but be careful. |
|
func isNil(v reflect.Value) bool { |
|
switch v.Kind() { |
|
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: |
|
return v.IsNil() |
|
} |
|
return false |
|
}
|
|
|