diff --git a/util/proto/marshal.go b/util/proto/marshal.go index a602b78..21e8013 100644 --- a/util/proto/marshal.go +++ b/util/proto/marshal.go @@ -384,3 +384,34 @@ func Float64Size(fNum int, v float64) int { return VarUIntSize(uint64(prefix)) + 8 } + +// Fixed32Marshal encodes uint32 value to Protocol Buffers fixed32 field with specified number, +// and writes it to specified buffer. Returns number of bytes written. +// +// Panics if the buffer is undersized. +func Fixed32Marshal(field int, buf []byte, v uint32) int { + if v == 0 { + return 0 + } + + prefix := field<<3 | 5 + + // buf length check can prevent panic at PutUvarint, but it will make + // marshaller a bit slower. + i := binary.PutUvarint(buf, uint64(prefix)) + binary.LittleEndian.PutUint32(buf[i:], v) + + return i + 4 +} + +// Fixed32Size returns number of bytes required to encode uint32 value to Protocol Buffers fixed32 field +// with specified number. +func Fixed32Size(fNum int, v uint32) int { + if v == 0 { + return 0 + } + + prefix := fNum<<3 | 5 + + return VarUIntSize(uint64(prefix)) + 4 +} diff --git a/util/proto/marshal_test.go b/util/proto/marshal_test.go index ba78c00..a3f6882 100644 --- a/util/proto/marshal_test.go +++ b/util/proto/marshal_test.go @@ -24,6 +24,7 @@ type stablePrimitives struct { FieldH SomeEnum FieldI uint64 // fixed64 FieldJ float64 + FieldK uint32 // fixed32 } type stableRepPrimitives struct { @@ -144,6 +145,15 @@ func (s *stablePrimitives) stableMarshal(buf []byte, wrongField bool) ([]byte, e } i += offset + fieldNum = 207 + if wrongField { + fieldNum++ + } + + offset = proto.Fixed32Marshal(fieldNum, buf, s.FieldK) + + i += offset + fieldNum = 300 if wrongField { fieldNum++ @@ -167,6 +177,7 @@ func (s *stablePrimitives) stableSize() int { proto.UInt64Size(204, s.FieldG) + proto.Fixed64Size(205, s.FieldI) + proto.Float64Size(206, s.FieldJ) + + proto.Fixed32Size(207, s.FieldK) + proto.EnumSize(300, int32(s.FieldH)) } @@ -478,6 +489,17 @@ func TestFloat64Marshal(t *testing.T) { }) } +func TestFixed32Marshal(t *testing.T) { + t.Run("zero", func(t *testing.T) { + testFixed32Marshal(t, 0, false) + }) + + t.Run("non zero", func(t *testing.T) { + testFixed32Marshal(t, math.MaxUint32, false) + testFixed32Marshal(t, math.MaxUint32, true) + }) +} + func testMarshal(t *testing.T, c stablePrimitives, tr test.Primitives, wrongField bool) *test.Primitives { var ( wire []byte @@ -791,3 +813,18 @@ func testFixed64Marshal(t *testing.T, n uint64, wrongField bool) { require.EqualValues(t, 0, result.FieldI) } } + +func testFixed32Marshal(t *testing.T, n uint32, wrongField bool) { + var ( + custom = stablePrimitives{FieldK: n} + transport = test.Primitives{FieldK: n} + ) + + result := testMarshal(t, custom, transport, wrongField) + + if !wrongField { + require.Equal(t, n, result.FieldK) + } else { + require.EqualValues(t, 0, result.FieldK) + } +} diff --git a/util/proto/test/test.pb.go b/util/proto/test/test.pb.go index 7ce722a..2a433a2 100644 --- a/util/proto/test/test.pb.go +++ b/util/proto/test/test.pb.go @@ -83,6 +83,7 @@ type Primitives struct { FieldG uint64 `protobuf:"varint,204,opt,name=field_g,json=fieldG,proto3" json:"field_g,omitempty"` FieldI uint64 `protobuf:"fixed64,205,opt,name=field_i,json=fieldI,proto3" json:"field_i,omitempty"` FieldJ float64 `protobuf:"fixed64,206,opt,name=field_j,json=fieldJ,proto3" json:"field_j,omitempty"` + FieldK uint32 `protobuf:"fixed32,207,opt,name=field_k,json=fieldK,proto3" json:"field_k,omitempty"` FieldH Primitives_SomeEnum `protobuf:"varint,300,opt,name=field_h,json=fieldH,proto3,enum=test.Primitives_SomeEnum" json:"field_h,omitempty"` } @@ -181,6 +182,13 @@ func (x *Primitives) GetFieldJ() float64 { return 0 } +func (x *Primitives) GetFieldK() uint32 { + if x != nil { + return x.FieldK + } + return 0 +} + func (x *Primitives) GetFieldH() Primitives_SomeEnum { if x != nil { return x.FieldH @@ -280,7 +288,7 @@ var File_util_proto_test_test_proto protoreflect.FileDescriptor var file_util_proto_test_test_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x75, 0x74, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x74, 0x65, - 0x73, 0x74, 0x22, 0xe7, 0x02, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x73, 0x74, 0x22, 0x81, 0x03, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x41, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x65, @@ -295,26 +303,28 @@ var file_util_proto_test_test_proto_rawDesc = []byte{ 0x69, 0x65, 0x6c, 0x64, 0x47, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x69, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x06, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6a, 0x18, 0xce, 0x01, 0x20, 0x01, 0x28, - 0x01, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4a, 0x12, 0x33, 0x0a, 0x07, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x5f, 0x68, 0x18, 0xac, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6f, - 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x48, 0x22, 0x3c, - 0x0a, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x4f, 0x53, 0x49, 0x54, - 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x08, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, - 0x45, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x22, 0xa5, 0x01, 0x0a, - 0x0d, 0x52, 0x65, 0x70, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x17, - 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x41, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x5f, 0x62, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, - 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x63, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x5f, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x44, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x03, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x12, 0x17, 0x0a, 0x07, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, 0x18, 0x06, 0x20, 0x03, 0x28, 0x04, 0x52, 0x06, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x46, 0x42, 0x11, 0x5a, 0x0f, 0x75, 0x74, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4a, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x5f, 0x6b, 0x18, 0xcf, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x06, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x4b, 0x12, 0x33, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x68, 0x18, 0xac, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x69, + 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, + 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x48, 0x22, 0x3c, 0x0a, 0x08, 0x53, 0x6f, 0x6d, 0x65, + 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, + 0x15, 0x0a, 0x08, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x22, 0xa5, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x70, 0x50, 0x72, + 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x5f, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x41, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x5f, 0x63, 0x18, 0x03, 0x20, 0x03, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x43, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x64, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x12, 0x17, 0x0a, 0x07, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x03, 0x52, 0x06, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x45, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x04, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x42, 0x11, + 0x5a, 0x0f, 0x75, 0x74, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, + 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var (