goprotobuf: Split encoding of repeated int32 and repeated uint32 fields.
This is a follow-on from a previous change where we split the singular int32/uint32.
It was an oversight not to fix the repeated versions at the same time.
Also simplify setEncAndDec for repeated fields while I'm here.
We were doing a lot of unnecessary work: unnecessarily doing two layers of
switches, plus trying to handle a bunch of field types we never generate.
Fixes #52.
LGTM=djd
R=djd
CC=golang-codereviews
https://codereview.appspot.com/123240043
diff --git a/proto/encode.go b/proto/encode.go
index b160372..35e5ad5 100644
--- a/proto/encode.go
+++ b/proto/encode.go
@@ -570,7 +570,7 @@
}
for i := 0; i < l; i++ {
o.buf = append(o.buf, p.tagcode...)
- x := s.Index(i)
+ x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
p.valEnc(o, uint64(x))
}
return nil
@@ -584,7 +584,7 @@
}
for i := 0; i < l; i++ {
n += len(p.tagcode)
- x := s.Index(i)
+ x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
n += p.valSize(uint64(x))
}
return
@@ -600,6 +600,75 @@
// TODO: Reuse a Buffer.
buf := NewBuffer(nil)
for i := 0; i < l; i++ {
+ x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+ p.valEnc(buf, uint64(x))
+ }
+
+ o.buf = append(o.buf, p.tagcode...)
+ o.EncodeVarint(uint64(len(buf.buf)))
+ o.buf = append(o.buf, buf.buf...)
+ return nil
+}
+
+func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+ s := structPointer_Word32Slice(base, p.field)
+ l := s.Len()
+ if l == 0 {
+ return 0
+ }
+ var bufSize int
+ for i := 0; i < l; i++ {
+ x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+ bufSize += p.valSize(uint64(x))
+ }
+
+ n += len(p.tagcode)
+ n += sizeVarint(uint64(bufSize))
+ n += bufSize
+ return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
+ s := structPointer_Word32Slice(base, p.field)
+ l := s.Len()
+ if l == 0 {
+ return ErrNil
+ }
+ for i := 0; i < l; i++ {
+ o.buf = append(o.buf, p.tagcode...)
+ x := s.Index(i)
+ p.valEnc(o, uint64(x))
+ }
+ return nil
+}
+
+func size_slice_uint32(p *Properties, base structPointer) (n int) {
+ s := structPointer_Word32Slice(base, p.field)
+ l := s.Len()
+ if l == 0 {
+ return 0
+ }
+ for i := 0; i < l; i++ {
+ n += len(p.tagcode)
+ x := s.Index(i)
+ n += p.valSize(uint64(x))
+ }
+ return
+}
+
+// Encode a slice of uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
+ s := structPointer_Word32Slice(base, p.field)
+ l := s.Len()
+ if l == 0 {
+ return ErrNil
+ }
+ // TODO: Reuse a Buffer.
+ buf := NewBuffer(nil)
+ for i := 0; i < l; i++ {
p.valEnc(buf, uint64(s.Index(i)))
}
@@ -609,7 +678,7 @@
return nil
}
-func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
s := structPointer_Word32Slice(base, p.field)
l := s.Len()
if l == 0 {