From 51e8e318c2cae33664ba423c39be96dd3878f6a2 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 21 Dec 2020 10:51:04 +0300 Subject: [PATCH] [#233] proto: Implement functions for fixed64 protobuf data type Signed-off-by: Leonard Lyubich --- util/proto/marshal.go | 25 ++++++++++++++++++++++++ util/proto/marshal_test.go | 38 +++++++++++++++++++++++++++++++++++++ util/proto/test/test.pb.go | Bin 12965 -> 13328 bytes util/proto/test/test.proto | 1 + 4 files changed, 64 insertions(+) diff --git a/util/proto/marshal.go b/util/proto/marshal.go index 250db0f..66824b3 100644 --- a/util/proto/marshal.go +++ b/util/proto/marshal.go @@ -335,3 +335,28 @@ func NestedStructureSize(field int64, v stableMarshaller) (size int) { return size } + +func Fixed64Marshal(field int, buf []byte, v uint64) (int, error) { + if v == 0 { + return 0, nil + } + + prefix := field<<3 | 1 + + // buf length check can prevent panic at PutUvarint, but it will make + // marshaller a bit slower. + i := binary.PutUvarint(buf, uint64(prefix)) + binary.LittleEndian.PutUint64(buf[i:], v) + + return i + 8, nil +} + +func Fixed64Size(fNum int, v uint64) 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 56e0a23..6844309 100644 --- a/util/proto/marshal_test.go +++ b/util/proto/marshal_test.go @@ -22,6 +22,7 @@ type stablePrimitives struct { FieldF int64 FieldG uint64 FieldH SomeEnum + FieldI uint64 // fixed64 } type stableRepPrimitives struct { @@ -122,6 +123,16 @@ func (s *stablePrimitives) stableMarshal(buf []byte, wrongField bool) ([]byte, e } i += offset + fieldNum = 205 + if wrongField { + fieldNum++ + } + offset, err = proto.Fixed64Marshal(fieldNum, buf, s.FieldI) + if err != nil { + return nil, errors.Wrap(err, "can't marshal field I") + } + i += offset + fieldNum = 300 if wrongField { fieldNum++ @@ -143,6 +154,7 @@ func (s *stablePrimitives) stableSize() int { proto.UInt32Size(202, s.FieldE) + proto.Int64Size(203, s.FieldF) + proto.UInt64Size(204, s.FieldG) + + proto.Fixed64Size(205, s.FieldI) + proto.EnumSize(300, int32(s.FieldH)) } @@ -430,6 +442,17 @@ func TestRepeatedUInt64Marshal(t *testing.T) { }) } +func TestFixed64Marshal(t *testing.T) { + t.Run("zero", func(t *testing.T) { + testFixed64Marshal(t, 0, false) + }) + + t.Run("non zero", func(t *testing.T) { + testFixed64Marshal(t, math.MaxUint64, false) + testFixed64Marshal(t, math.MaxUint64, true) + }) +} + func testMarshal(t *testing.T, c stablePrimitives, tr test.Primitives, wrongField bool) *test.Primitives { var ( wire []byte @@ -713,3 +736,18 @@ func testRepeatedUInt64Marshal(t *testing.T, n []uint64, wrongField bool) { require.Len(t, result.FieldF, 0) } } + +func testFixed64Marshal(t *testing.T, n uint64, wrongField bool) { + var ( + custom = stablePrimitives{FieldI: n} + transport = test.Primitives{FieldI: n} + ) + + result := testMarshal(t, custom, transport, wrongField) + + if !wrongField { + require.Equal(t, n, result.FieldI) + } else { + require.EqualValues(t, 0, result.FieldI) + } +} diff --git a/util/proto/test/test.pb.go b/util/proto/test/test.pb.go index 0254baa8b1f8eeeaaa9087005e8d7fd2a5f6c1ae..a0808f88ba26aefe0eb3c46a605ba40e1d9541b2 100644 GIT binary patch delta 458 zcmYk1J4?e*7>0>jY0^?HTB)_sljO7!jJCBkC_!-3E+P&tf)|Sh78;NYm^Hp;eH zFebB8MzvNqDx16IS;sB!*z2yby;rTYMG;CYCb-CnecnN+)-4oq869K)jp&5;5nYx# zO13wfyzPQTV)!I#WX6!hY$G>qkZhx5qe*1Jgg`PZU`}q*kMns5bP(@yvXd3juV@{T zh-t;bN|N&NnvIKU4+89Jf({^}>UdJ(%nS2)RkZ|ymg=uP`Qp1RWX-~%CZefz|NjDx z!@xLV=~A2U#zw}+OESnW&QS}5^x};6b9qNO;FbCSL00f6hmlD|5TRkV7U!K(%0iV% zwkGBO9)}-I_7C3-hajehcyo=)yd@NHPIKHiOOii?pbTGYh2p5XR^&Z#H5Pdyx( P$CvJtp7n%BM~|gnBVK$V delta 322 zcmbP`u{3olDbOxYU5VNwBc)K$Qo zWH6@#!nvR#KKZGC9G??`72{$1BN9 zwp8N-DccCNHdc*q@>yA>$$e^4AR$L}^~opYxF_FH)16$WC_6b`)rrLf