From 0df4e4bf0d94cec7b4c8fc6847bf3c19e5a48b4c Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Tue, 18 Aug 2020 09:48:57 +0300 Subject: [PATCH] Add nested structure stable marshal helper Signed-off-by: Alex Vanin --- util/proto/marshal.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/util/proto/marshal.go b/util/proto/marshal.go index a975e322..470d9741 100644 --- a/util/proto/marshal.go +++ b/util/proto/marshal.go @@ -11,6 +11,13 @@ import ( "math/bits" ) +type ( + stableMarshaller interface { + StableMarshal([]byte) ([]byte, error) + StableSize() int + } +) + func BytesMarshal(field int, buf, v []byte) (int, error) { if len(v) == 0 { return 0, nil @@ -296,3 +303,34 @@ func NestedStructurePrefix(field int64) (prefix uint64, ln int) { prefix = uint64(field<<3 | 0x02) return prefix, VarUIntSize(prefix) } + +func NestedStructureMarshal(field int64, buf []byte, v stableMarshaller) (int, error) { + if v == nil { + return 0, nil + } + + prefix, _ := NestedStructurePrefix(field) + offset := binary.PutUvarint(buf, prefix) + + n := v.StableSize() + offset += binary.PutUvarint(buf[offset:], uint64(n)) + + _, err := v.StableMarshal(buf[offset:]) + if err != nil { + return 0, err + } + + return offset + n, nil +} + +func NestedStructureSize(field int64, v stableMarshaller) (size int) { + if v == nil { + return 0 + } + + _, ln := NestedStructurePrefix(field) + n := v.StableSize() + size = ln + VarUIntSize(uint64(n)) + n + + return size +}