aboutsummaryrefslogtreecommitdiff
path: root/proto/encode.go
diff options
context:
space:
mode:
authorDavid Symonds <dsymonds@golang.org>2014-07-22 14:06:27 +1000
committerDavid Symonds <dsymonds@golang.org>2014-07-22 14:06:27 +1000
commitf054e84f761734905e22c464034076f2ffb46a50 (patch)
tree6b6bd66a4d1874f222c25ed73e254b6e560b4556 /proto/encode.go
parentb16d165ede2e9c6bf3e9a9141029ecac8241d00d (diff)
downloadprotobuf-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.go26
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))