diff options
author | David Symonds <dsymonds@golang.org> | 2014-07-22 14:06:27 +1000 |
---|---|---|
committer | David Symonds <dsymonds@golang.org> | 2014-07-22 14:06:27 +1000 |
commit | f054e84f761734905e22c464034076f2ffb46a50 (patch) | |
tree | 6b6bd66a4d1874f222c25ed73e254b6e560b4556 /proto/encode.go | |
parent | b16d165ede2e9c6bf3e9a9141029ecac8241d00d (diff) | |
download | protobuf-f054e84f761734905e22c464034076f2ffb46a50.tar.gz |
goprotobuf: Split encoding of int32 and uint32 fields.
int32 needs special handling; negative values need to be sign-extended,
so need to be converted from uint32 back to int32 before converting to
uint64 for the varint encoding step (yielding 10 bytes).
uint32 is simpler and stays as just encoding the bit pattern,
and thus never takes more than 5 bytes.
This permits upgrading int32 fields to int64, and matches C++.
LGTM=nigeltao
R=nigeltao
CC=golang-codereviews
https://codereview.appspot.com/114190043
Diffstat (limited to 'proto/encode.go')
-rw-r--r-- | proto/encode.go | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/proto/encode.go b/proto/encode.go index 2d3e03f..b160372 100644 --- a/proto/encode.go +++ b/proto/encode.go @@ -312,7 +312,7 @@ func (o *Buffer) enc_int32(p *Properties, base structPointer) error { if word32_IsNil(v) { return ErrNil } - x := word32_Get(v) + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range o.buf = append(o.buf, p.tagcode...) p.valEnc(o, uint64(x)) return nil @@ -323,6 +323,30 @@ func size_int32(p *Properties, base structPointer) (n int) { if word32_IsNil(v) { return 0 } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +// Encode a uint32. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return ErrNil + } + x := word32_Get(v) + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } x := word32_Get(v) n += len(p.tagcode) n += p.valSize(uint64(x)) |