diff --git a/v2/refs/convert.go b/v2/refs/convert.go index 936a920..4a84077 100644 --- a/v2/refs/convert.go +++ b/v2/refs/convert.go @@ -111,3 +111,31 @@ func AddressFromGRPCMessage(m *refs.Address) *Address { return a } + +func ChecksumToGRPCMessage(c *Checksum) *refs.Checksum { + if c == nil { + return nil + } + + m := new(refs.Checksum) + + m.SetChecksumType(refs.ChecksumType(c.GetType())) + + m.SetSum(c.GetSum()) + + return m +} + +func ChecksumFromGRPCMessage(m *refs.Checksum) *Checksum { + if m == nil { + return nil + } + + c := new(Checksum) + + c.SetType(ChecksumType(m.GetType())) + + c.SetSum(m.GetSum()) + + return c +} diff --git a/v2/refs/grpc/types.go b/v2/refs/grpc/types.go index 357b4da..e55504d 100644 --- a/v2/refs/grpc/types.go +++ b/v2/refs/grpc/types.go @@ -34,3 +34,17 @@ func (m *Address) SetObjectId(v *ObjectID) { m.ObjectId = v } } + +// SetChecksumType in generic checksum structure. +func (m *Checksum) SetChecksumType(v ChecksumType) { + if m != nil { + m.Type = v + } +} + +// SetChecksumSum in generic checksum structure. +func (m *Checksum) SetSum(v []byte) { + if m != nil { + m.Sum = v + } +} diff --git a/v2/refs/marshal.go b/v2/refs/marshal.go index 4018500..7c1f524 100644 --- a/v2/refs/marshal.go +++ b/v2/refs/marshal.go @@ -13,6 +13,9 @@ const ( addressContainerField = 1 addressObjectField = 2 + + checksumTypeField = 1 + checksumValueField = 2 ) func (o *OwnerID) StableMarshal(buf []byte) ([]byte, error) { @@ -130,3 +133,43 @@ func (a *Address) StableSize() (size int) { return size } + +func (c *Checksum) StableMarshal(buf []byte) ([]byte, error) { + if c == nil { + return []byte{}, nil + } + + if buf == nil { + buf = make([]byte, c.StableSize()) + } + + var ( + offset, n int + err error + ) + + n, err = proto.EnumMarshal(checksumTypeField, buf[offset:], int32(c.typ)) + if err != nil { + return nil, err + } + + offset += n + + _, err = proto.BytesMarshal(checksumValueField, buf[offset:], c.sum) + if err != nil { + return nil, err + } + + return buf, nil +} + +func (c *Checksum) StableSize() (size int) { + if c == nil { + return 0 + } + + size += proto.EnumSize(checksumTypeField, int32(c.typ)) + size += proto.BytesSize(checksumValueField, c.sum) + + return size +} diff --git a/v2/refs/marshal_test.go b/v2/refs/marshal_test.go index 0e9f7ac..441174e 100644 --- a/v2/refs/marshal_test.go +++ b/v2/refs/marshal_test.go @@ -87,3 +87,22 @@ func TestAddress_StableMarshal(t *testing.T) { require.Equal(t, addressFrom, addressTo) }) } + +func TestChecksum_StableMarshal(t *testing.T) { + checksumFrom := new(refs.Checksum) + transport := new(grpc.Checksum) + + t.Run("non empty", func(t *testing.T) { + checksumFrom.SetType(refs.TillichZemor) + checksumFrom.SetSum([]byte("Homomorphic Hash")) + + wire, err := checksumFrom.StableMarshal(nil) + require.NoError(t, err) + + err = transport.Unmarshal(wire) + require.NoError(t, err) + + checksumTo := refs.ChecksumFromGRPCMessage(transport) + require.Equal(t, checksumFrom, checksumTo) + }) +} diff --git a/v2/refs/types.go b/v2/refs/types.go index 269edf4..e368b62 100644 --- a/v2/refs/types.go +++ b/v2/refs/types.go @@ -18,6 +18,20 @@ type Address struct { oid *ObjectID } +type Checksum struct { + typ ChecksumType + + sum []byte +} + +type ChecksumType uint32 + +const ( + UnknownChecksum ChecksumType = iota + TillichZemor + SHA256 +) + func (o *OwnerID) GetValue() []byte { if o != nil { return o.val @@ -87,3 +101,31 @@ func (a *Address) SetObjectID(v *ObjectID) { a.oid = v } } + +func (c *Checksum) GetType() ChecksumType { + if c != nil { + return c.typ + } + + return UnknownChecksum +} + +func (c *Checksum) SetType(v ChecksumType) { + if c != nil { + c.typ = v + } +} + +func (c *Checksum) GetSum() []byte { + if c != nil { + return c.sum + } + + return nil +} + +func (c *Checksum) SetSum(v []byte) { + if c != nil { + c.sum = v + } +}