From b0a2b73650d04f5f859cac10bb6a512e523ba312 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Thu, 18 Nov 2021 16:14:49 +0300 Subject: [PATCH] [#355] util/proto: Support fixed32 fields Implement `Fixed32Marshal` / `Fixed32Size` functions which allow to work with protobuf fixed32 fields. Signed-off-by: Leonard Lyubich --- util/proto/marshal.go | 31 +++++++++++++++++++++++++++++++ util/proto/marshal_test.go | 37 +++++++++++++++++++++++++++++++++++++ util/proto/test/test.pb.go | Bin 13488 -> 13851 bytes 3 files changed, 68 insertions(+) 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 7ce722ac76c59f96d23e636dca411f40b1a437c4..2a433a2b2189478b80e8fb87f85793bd838ed092 100644 GIT binary patch delta 473 zcmX|7J4?e*7$suVCO%SaL~4@Wnlz7^mbTUh1O*qDf~bRoisBQj+A4}D_zP4VdPW`G z1zYIkA~@(Ef^_va2s#KZ4&Ixh%f0uU^L^*L=c{a9ZdXbom%~DU;8o!DfsC6;4ZFqN z1Glievp%}9xxT%&wB_dai-kJK;h{z5wvd*)swL5CZp_&Z!F|}KE|Flede=E4w2Y)( zk~&HaRJ+s~4>2l(n5{V0BqX)wwiPC(N7%W#fvKp<4WmXPR1b11cC8|@rH+|U^@X?PTz)j`<@?{y%>JbW7+ zn2-4;dofmc8}qvos)Mo~z^a{KCKsxOIWvT3)gSUf)rzLz%?vYjN^|H(C7f!l$lGD` zXewSb5hs?+v-E?1q3~q6|B><$kxyk^+COc|NZ2MML%^c#Th>(K=f1W>m^CFl(pz>E meA!XD!M?^J*5^4MDpq$X%8S{IzsfYDuPD8%B&&SFv delta 362 zcmXX>ze~eF7{zL>Nh`JfYDrDG<}P>1HDXMQ3WZMYf`5PrqEJxiD2V9fEPW1w&Mrl$ zWN;F35*$RG9dvMXR1g%+#SY)c_ult-ymzwMZFbw~a3CX6;lbFlKD0jX5r5kc!WZ)~ zi6vGBaYwMnCXz9Y8!L|sMiRP)Cr0sWG8lG2!KzJ>a7$>hY_7JTT!KLD>Y5jQkD_nG zF5tmtO8jBdJ_3W+73gpSEv`kx&OdR(oS5Tgp_oGQ+Rr_NVP z;JUXvHC$6+XXD_04PBYX zvCDBPblkc{tS|>@Ij*dTq}X+)uqp}O%d~&aBRG?Fyp<;LDYH?HR3+}!Fe&y;Eo@af F`X5oCXu1FZ