From 0cbb8d09135e39026e72a09872364ae22452e169 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Wed, 24 Mar 2021 10:10:30 +0300 Subject: [PATCH] [#265] proto: Implement functions for double (float64) protobuf data type Signed-off-by: Leonard Lyubich --- util/proto/marshal.go | 24 ++++++++++++++++++++++ util/proto/marshal_test.go | 40 +++++++++++++++++++++++++++++++++++++ util/proto/test/test.pb.go | Bin 13328 -> 13691 bytes util/proto/test/test.proto | 1 + 4 files changed, 65 insertions(+) diff --git a/util/proto/marshal.go b/util/proto/marshal.go index 66824b3..a602b78 100644 --- a/util/proto/marshal.go +++ b/util/proto/marshal.go @@ -8,6 +8,7 @@ package proto import ( "encoding/binary" + "math" "math/bits" "reflect" ) @@ -360,3 +361,26 @@ func Fixed64Size(fNum int, v uint64) int { return VarUIntSize(uint64(prefix)) + 8 } + +func Float64Marshal(field int, buf []byte, v float64) (int, error) { + if v == 0 { + return 0, nil + } + + prefix := field<<3 | 1 + + i := binary.PutUvarint(buf, uint64(prefix)) + binary.LittleEndian.PutUint64(buf[i:], math.Float64bits(v)) + + return i + 8, nil +} + +func Float64Size(fNum int, v float64) int { + if v == 0 { + return 0 + } + + prefix := fNum<<3 | 1 + + return VarUIntSize(uint64(prefix)) + 8 +} diff --git a/util/proto/marshal_test.go b/util/proto/marshal_test.go index 6844309..34b5a44 100644 --- a/util/proto/marshal_test.go +++ b/util/proto/marshal_test.go @@ -23,6 +23,7 @@ type stablePrimitives struct { FieldG uint64 FieldH SomeEnum FieldI uint64 // fixed64 + FieldJ float64 } type stableRepPrimitives struct { @@ -133,6 +134,16 @@ func (s *stablePrimitives) stableMarshal(buf []byte, wrongField bool) ([]byte, e } i += offset + fieldNum = 206 + if wrongField { + fieldNum++ + } + offset, err = proto.Float64Marshal(fieldNum, buf, s.FieldJ) + if err != nil { + return nil, errors.Wrap(err, "can't marshal field J") + } + i += offset + fieldNum = 300 if wrongField { fieldNum++ @@ -155,6 +166,7 @@ func (s *stablePrimitives) stableSize() int { proto.Int64Size(203, s.FieldF) + proto.UInt64Size(204, s.FieldG) + proto.Fixed64Size(205, s.FieldI) + + proto.Float64Size(206, s.FieldJ) + proto.EnumSize(300, int32(s.FieldH)) } @@ -453,6 +465,19 @@ func TestFixed64Marshal(t *testing.T) { }) } +func TestFloat64Marshal(t *testing.T) { + t.Run("zero", func(t *testing.T) { + testFloat64Marshal(t, 0, false) + }) + + t.Run("non zero", func(t *testing.T) { + f := math.Float64frombits(12345677890) + + testFloat64Marshal(t, f, false) + testFloat64Marshal(t, f, true) + }) +} + func testMarshal(t *testing.T, c stablePrimitives, tr test.Primitives, wrongField bool) *test.Primitives { var ( wire []byte @@ -589,6 +614,21 @@ func testUInt64Marshal(t *testing.T, n uint64, wrongField bool) { } } +func testFloat64Marshal(t *testing.T, n float64, wrongField bool) { + var ( + custom = stablePrimitives{FieldJ: n} + transport = test.Primitives{FieldJ: n} + ) + + result := testMarshal(t, custom, transport, wrongField) + + if !wrongField { + require.Equal(t, n, result.FieldJ) + } else { + require.EqualValues(t, 0, result.FieldJ) + } +} + func testEnumMarshal(t *testing.T, e SomeEnum, wrongField bool) { var ( custom = stablePrimitives{FieldH: e} diff --git a/util/proto/test/test.pb.go b/util/proto/test/test.pb.go index a0808f88ba26aefe0eb3c46a605ba40e1d9541b2..b194e1f1c63f66df7297de0dfd5b84d3d91ee0fe 100644 GIT binary patch delta 461 zcmXYtJx|+E6o!>3gxC>KLX0AkYdgNau_HMpUxW{ffwAt;sDB_t)KP2E1VmIJHa3`m zyaN(bSvoO9ip0<|z(6}71ndl*n}Kw$RF&&=Inr~^bB^wN58wasy8Wo&sEzejymS|a#s_!(UCpz+tyXgg4ysWp;GrN)_4?79aKtgQ{srtNS-=6A zeAzpXy%mG*d`~1xBk0KUV|7c-ZxEaOTqu=rrzrR& zzd&2dVIYU_MN@;KfFGKTH%vl;PH;S>6t8IlKiM>P=s0ifQ#+vIJEa_c`C#ZieAZ{+ z>gng{-mr0|+qlyO{MM6P9%FpdVZQvJWN}C|d}VPyo74SVk;4_y@nnd>av7^^rDOVsCDVqggaUII5CtSn uacs`uf{F0baon3>Nb)rLrh!)}oxh}+qUffCNX7rDd*u2WK4=99+dg!BJdvu`d;u3%_&EJ@;~d4x;_RM<#A)cXE6_yRD|0t@v4AOQX*y zPDvJ#Ie|B3qs`LDTLc}wh)v5$sS4T_gH~~HV-@jg%;i>At0d@zp{UEvD#4evE_}5L zlL&Sz3G@=U9>Zq>B|GWt*ur)+hAW%l(l!21m~tj%RS7yl4KMDz)I^v27#ao0#P69U z44txA^=MKl#4R^5ASG-tS%`I41n;@Y7T>7j$+d+Z8B2(WhI?KZ*=JyI6)nDicQ=QK ySHWriuP35Z9MTM?y{s7Z7j^V0MZ=>4PdtVTJ&Uc;bB=Wd4`WwXFUQ~BnfeRq=x12~ diff --git a/util/proto/test/test.proto b/util/proto/test/test.proto index e9c2758..c568a31 100644 --- a/util/proto/test/test.proto +++ b/util/proto/test/test.proto @@ -13,6 +13,7 @@ message Primitives { int64 field_f = 203; uint64 field_g = 204; fixed64 field_i = 205; + double field_j = 206; enum SomeEnum { UNKNOWN = 0;