forked from TrueCloudLab/frostfs-api-go
initial
This commit is contained in:
commit
1cf33e5ffd
87 changed files with 29835 additions and 0 deletions
68
refs/address.go
Normal file
68
refs/address.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
package refs
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"strings"
|
||||
|
||||
"github.com/nspcc-dev/neofs-proto/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
joinSeparator = "/"
|
||||
|
||||
// ErrWrongAddress is raised when wrong address is passed to Address.Parse ParseAddress.
|
||||
ErrWrongAddress = internal.Error("wrong address")
|
||||
|
||||
// ErrEmptyAddress is raised when empty address is passed to Address.Parse ParseAddress.
|
||||
ErrEmptyAddress = internal.Error("empty address")
|
||||
)
|
||||
|
||||
// ParseAddress parses address from string representation into new Address.
|
||||
func ParseAddress(str string) (*Address, error) {
|
||||
var addr Address
|
||||
return &addr, addr.Parse(str)
|
||||
}
|
||||
|
||||
// Parse parses address from string representation into current Address.
|
||||
func (m *Address) Parse(addr string) error {
|
||||
if m == nil {
|
||||
return ErrEmptyAddress
|
||||
}
|
||||
|
||||
items := strings.Split(addr, joinSeparator)
|
||||
if len(items) != 2 {
|
||||
return ErrWrongAddress
|
||||
}
|
||||
|
||||
if err := m.CID.Parse(items[0]); err != nil {
|
||||
return err
|
||||
} else if err := m.ObjectID.Parse(items[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns string representation of Address.
|
||||
func (m Address) String() string {
|
||||
return strings.Join([]string{m.CID.String(), m.ObjectID.String()}, joinSeparator)
|
||||
}
|
||||
|
||||
// IsFull checks that ContainerID and ObjectID is not empty.
|
||||
func (m Address) IsFull() bool {
|
||||
return !m.CID.Empty() && !m.ObjectID.Empty()
|
||||
}
|
||||
|
||||
// Equal checks that current Address is equal to passed Address.
|
||||
func (m Address) Equal(a2 *Address) bool {
|
||||
return m.CID.Equal(a2.CID) && m.ObjectID.Equal(a2.ObjectID)
|
||||
}
|
||||
|
||||
// Hash returns []byte that used as a key for storage bucket.
|
||||
func (m Address) Hash() ([]byte, error) {
|
||||
if !m.IsFull() {
|
||||
return nil, ErrEmptyAddress
|
||||
}
|
||||
h := sha256.Sum256(append(m.ObjectID.Bytes(), m.CID.Bytes()...))
|
||||
return h[:], nil
|
||||
}
|
96
refs/cid.go
Normal file
96
refs/cid.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package refs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// CIDForBytes creates CID for passed bytes.
|
||||
func CIDForBytes(data []byte) CID { return sha256.Sum256(data) }
|
||||
|
||||
// CIDFromBytes parses CID from passed bytes.
|
||||
func CIDFromBytes(data []byte) (cid CID, err error) {
|
||||
if ln := len(data); ln != CIDSize {
|
||||
return CID{}, errors.Wrapf(ErrWrongDataSize, "expect=%d, actual=%d", CIDSize, ln)
|
||||
}
|
||||
|
||||
copy(cid[:], data)
|
||||
return
|
||||
}
|
||||
|
||||
// CIDFromString parses CID from string representation of CID.
|
||||
func CIDFromString(c string) (CID, error) {
|
||||
var cid CID
|
||||
decoded, err := base58.Decode(c)
|
||||
if err != nil {
|
||||
return cid, err
|
||||
}
|
||||
return CIDFromBytes(decoded)
|
||||
}
|
||||
|
||||
// Size returns size of CID (CIDSize).
|
||||
func (c CID) Size() int { return CIDSize }
|
||||
|
||||
// Parse tries to parse CID from string representation.
|
||||
func (c *CID) Parse(cid string) error {
|
||||
var err error
|
||||
if *c, err = CIDFromString(cid); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Empty checks that current CID is empty.
|
||||
func (c CID) Empty() bool { return bytes.Equal(c.Bytes(), emptyCID) }
|
||||
|
||||
// Equal checks that current CID is equal to passed CID.
|
||||
func (c CID) Equal(cid CID) bool { return bytes.Equal(c.Bytes(), cid.Bytes()) }
|
||||
|
||||
// Marshal returns CID bytes representation.
|
||||
func (c CID) Marshal() ([]byte, error) { return c.Bytes(), nil }
|
||||
|
||||
// MarshalBinary returns CID bytes representation.
|
||||
func (c CID) MarshalBinary() ([]byte, error) { return c.Bytes(), nil }
|
||||
|
||||
// MarshalTo marshal CID to bytes representation into passed bytes.
|
||||
func (c *CID) MarshalTo(data []byte) (int, error) { return copy(data, c.Bytes()), nil }
|
||||
|
||||
// ProtoMessage method to satisfy proto.Message interface.
|
||||
func (c CID) ProtoMessage() {}
|
||||
|
||||
// String returns string representation of CID.
|
||||
func (c CID) String() string { return base58.Encode(c[:]) }
|
||||
|
||||
// Reset resets current CID to zero value.
|
||||
func (c *CID) Reset() { *c = CID{} }
|
||||
|
||||
// Bytes returns CID bytes representation.
|
||||
func (c CID) Bytes() []byte {
|
||||
buf := make([]byte, CIDSize)
|
||||
copy(buf, c[:])
|
||||
return buf
|
||||
}
|
||||
|
||||
// UnmarshalBinary tries to parse bytes representation of CID.
|
||||
func (c *CID) UnmarshalBinary(data []byte) error { return c.Unmarshal(data) }
|
||||
|
||||
// Unmarshal tries to parse bytes representation of CID.
|
||||
func (c *CID) Unmarshal(data []byte) error {
|
||||
if ln := len(data); ln != CIDSize {
|
||||
return errors.Wrapf(ErrWrongDataSize, "expect=%d, actual=%d", CIDSize, ln)
|
||||
}
|
||||
|
||||
copy((*c)[:], data)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify validates that current CID is generated for passed bytes data.
|
||||
func (c CID) Verify(data []byte) error {
|
||||
if id := CIDForBytes(data); !bytes.Equal(c[:], id[:]) {
|
||||
return errors.New("wrong hash for data")
|
||||
}
|
||||
return nil
|
||||
}
|
65
refs/owner.go
Normal file
65
refs/owner.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package refs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-proto/chain"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NewOwnerID returns generated OwnerID from passed public keys.
|
||||
func NewOwnerID(keys ...*ecdsa.PublicKey) (owner OwnerID, err error) {
|
||||
if len(keys) == 0 {
|
||||
return
|
||||
}
|
||||
var d []byte
|
||||
d, err = base58.Decode(chain.KeysToAddress(keys...))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
copy(owner[:], d)
|
||||
return owner, nil
|
||||
}
|
||||
|
||||
// Size returns OwnerID size in bytes (OwnerIDSize).
|
||||
func (OwnerID) Size() int { return OwnerIDSize }
|
||||
|
||||
// Empty checks that current OwnerID is empty value.
|
||||
func (o OwnerID) Empty() bool { return bytes.Equal(o.Bytes(), emptyOwner) }
|
||||
|
||||
// Equal checks that current OwnerID is equal to passed OwnerID.
|
||||
func (o OwnerID) Equal(id OwnerID) bool { return bytes.Equal(o.Bytes(), id.Bytes()) }
|
||||
|
||||
// Reset sets current OwnerID to empty value.
|
||||
func (o *OwnerID) Reset() { *o = OwnerID{} }
|
||||
|
||||
// ProtoMessage method to satisfy proto.Message interface.
|
||||
func (OwnerID) ProtoMessage() {}
|
||||
|
||||
// Marshal returns OwnerID bytes representation.
|
||||
func (o OwnerID) Marshal() ([]byte, error) { return o.Bytes(), nil }
|
||||
|
||||
// MarshalTo copies OwnerID bytes representation into passed slice of bytes.
|
||||
func (o OwnerID) MarshalTo(data []byte) (int, error) { return copy(data, o.Bytes()), nil }
|
||||
|
||||
// String returns string representation of OwnerID.
|
||||
func (o OwnerID) String() string { return base58.Encode(o[:]) }
|
||||
|
||||
// Bytes returns OwnerID bytes representation.
|
||||
func (o OwnerID) Bytes() []byte {
|
||||
buf := make([]byte, OwnerIDSize)
|
||||
copy(buf, o[:])
|
||||
return buf
|
||||
}
|
||||
|
||||
// Unmarshal tries to parse OwnerID bytes representation into current OwnerID.
|
||||
func (o *OwnerID) Unmarshal(data []byte) error {
|
||||
if ln := len(data); ln != OwnerIDSize {
|
||||
return errors.Wrapf(ErrWrongDataSize, "expect=%d, actual=%d", OwnerIDSize, ln)
|
||||
}
|
||||
|
||||
copy((*o)[:], data)
|
||||
return nil
|
||||
}
|
14
refs/sgid.go
Normal file
14
refs/sgid.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package refs
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// SGIDFromBytes parse bytes representation of SGID into new SGID value.
|
||||
func SGIDFromBytes(data []byte) (sgid SGID, err error) {
|
||||
if ln := len(data); ln != SGIDSize {
|
||||
return SGID{}, errors.Wrapf(ErrWrongDataSize, "expect=%d, actual=%d", SGIDSize, ln)
|
||||
}
|
||||
copy(sgid[:], data)
|
||||
return
|
||||
}
|
106
refs/types.go
Normal file
106
refs/types.go
Normal file
|
@ -0,0 +1,106 @@
|
|||
// This package contains basic structures implemented in Go, such as
|
||||
//
|
||||
// CID - container id
|
||||
// OwnerID - owner id
|
||||
// ObjectID - object id
|
||||
// SGID - storage group id
|
||||
// Address - contains object id and container id
|
||||
// UUID - a 128 bit (16 byte) Universal Unique Identifier as defined in RFC 4122
|
||||
|
||||
package refs
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neofs-proto/chain"
|
||||
"github.com/nspcc-dev/neofs-proto/internal"
|
||||
)
|
||||
|
||||
type (
|
||||
// CID is implementation of ContainerID.
|
||||
CID [CIDSize]byte
|
||||
|
||||
// UUID wrapper over github.com/google/uuid.UUID.
|
||||
UUID uuid.UUID
|
||||
|
||||
// SGID is type alias of UUID.
|
||||
SGID = UUID
|
||||
|
||||
// ObjectID is type alias of UUID.
|
||||
ObjectID = UUID
|
||||
|
||||
// MessageID is type alias of UUID.
|
||||
MessageID = UUID
|
||||
|
||||
// OwnerID is wrapper over neofs-proto/chain.WalletAddress.
|
||||
OwnerID chain.WalletAddress
|
||||
)
|
||||
|
||||
const (
|
||||
// UUIDSize contains size of UUID.
|
||||
UUIDSize = 16
|
||||
|
||||
// SGIDSize contains size of SGID.
|
||||
SGIDSize = UUIDSize
|
||||
|
||||
// CIDSize contains size of CID.
|
||||
CIDSize = sha256.Size
|
||||
|
||||
// OwnerIDSize contains size of OwnerID.
|
||||
OwnerIDSize = chain.AddressLength
|
||||
|
||||
// ErrWrongDataSize is raised when passed bytes into Unmarshal have wrong size.
|
||||
ErrWrongDataSize = internal.Error("wrong data size")
|
||||
|
||||
// ErrEmptyOwner is raised when empty OwnerID is passed into container.New.
|
||||
ErrEmptyOwner = internal.Error("owner cant be empty")
|
||||
|
||||
// ErrEmptyCapacity is raised when empty Capacity is passed container.New.
|
||||
ErrEmptyCapacity = internal.Error("capacity cant be empty")
|
||||
|
||||
// ErrEmptyContainer is raised when it CID method is called for an empty container.
|
||||
ErrEmptyContainer = internal.Error("cannot return ID for empty container")
|
||||
)
|
||||
|
||||
var (
|
||||
emptyCID = (CID{}).Bytes()
|
||||
emptyUUID = (UUID{}).Bytes()
|
||||
emptyOwner = (OwnerID{}).Bytes()
|
||||
|
||||
_ internal.Custom = (*CID)(nil)
|
||||
_ internal.Custom = (*SGID)(nil)
|
||||
_ internal.Custom = (*UUID)(nil)
|
||||
_ internal.Custom = (*OwnerID)(nil)
|
||||
_ internal.Custom = (*ObjectID)(nil)
|
||||
_ internal.Custom = (*MessageID)(nil)
|
||||
|
||||
// NewSGID method alias.
|
||||
NewSGID = NewUUID
|
||||
|
||||
// NewObjectID method alias.
|
||||
NewObjectID = NewUUID
|
||||
|
||||
// NewMessageID method alias.
|
||||
NewMessageID = NewUUID
|
||||
)
|
||||
|
||||
// NewUUID returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
// package.
|
||||
//
|
||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||
//
|
||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
||||
// means the probability is about 0.00000000006 (6 × 10−11),
|
||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
||||
// year and having one duplicate.
|
||||
func NewUUID() (UUID, error) {
|
||||
id, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return UUID{}, err
|
||||
}
|
||||
return UUID(id), nil
|
||||
}
|
368
refs/types.pb.go
Normal file
368
refs/types.pb.go
Normal file
|
@ -0,0 +1,368 @@
|
|||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: refs/types.proto
|
||||
|
||||
package refs
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type Address struct {
|
||||
ObjectID ObjectID `protobuf:"bytes,1,opt,name=ObjectID,proto3,customtype=ObjectID" json:"ObjectID"`
|
||||
CID CID `protobuf:"bytes,2,opt,name=CID,proto3,customtype=CID" json:"CID"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Address) Reset() { *m = Address{} }
|
||||
func (*Address) ProtoMessage() {}
|
||||
func (*Address) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_063a64a96d952d31, []int{0}
|
||||
}
|
||||
func (m *Address) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
func (m *Address) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Address.Merge(m, src)
|
||||
}
|
||||
func (m *Address) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *Address) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Address.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Address proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Address)(nil), "refs.Address")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("refs/types.proto", fileDescriptor_063a64a96d952d31) }
|
||||
|
||||
var fileDescriptor_063a64a96d952d31 = []byte{
|
||||
// 199 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x28, 0x4a, 0x4d, 0x2b,
|
||||
0xd6, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x01, 0x89,
|
||||
0x48, 0xe9, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xa7, 0xe7, 0xa7,
|
||||
0xe7, 0xeb, 0x83, 0x25, 0x93, 0x4a, 0xd3, 0xc0, 0x3c, 0x30, 0x07, 0xcc, 0x82, 0x68, 0x52, 0x0a,
|
||||
0xe3, 0x62, 0x77, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x16, 0xd2, 0xe1, 0xe2, 0xf0, 0x4f, 0xca,
|
||||
0x4a, 0x4d, 0x2e, 0xf1, 0x74, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x71, 0x12, 0x38, 0x71, 0x4f,
|
||||
0x9e, 0xe1, 0xd6, 0x3d, 0x79, 0xb8, 0x78, 0x10, 0x9c, 0x25, 0x24, 0xcb, 0xc5, 0xec, 0xec, 0xe9,
|
||||
0x22, 0xc1, 0x04, 0x56, 0xc8, 0x0d, 0x55, 0x08, 0x12, 0x0a, 0x02, 0x11, 0x4e, 0xce, 0x37, 0x1e,
|
||||
0xca, 0x31, 0x34, 0x3c, 0x92, 0x63, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x1b,
|
||||
0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x15, 0xc9, 0x91,
|
||||
0x79, 0xc5, 0x05, 0xc9, 0xc9, 0xba, 0x29, 0xa9, 0x65, 0xfa, 0x79, 0xa9, 0xf9, 0x69, 0xc5, 0xba,
|
||||
0x10, 0x27, 0x82, 0xfc, 0x92, 0xc4, 0x06, 0x66, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xfd,
|
||||
0xb6, 0x0b, 0x68, 0xec, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Address) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *Address) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *Address) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.XXX_unrecognized != nil {
|
||||
i -= len(m.XXX_unrecognized)
|
||||
copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
{
|
||||
size := m.CID.Size()
|
||||
i -= size
|
||||
if _, err := m.CID.MarshalTo(dAtA[i:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i = encodeVarintTypes(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
{
|
||||
size := m.ObjectID.Size()
|
||||
i -= size
|
||||
if _, err := m.ObjectID.MarshalTo(dAtA[i:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i = encodeVarintTypes(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintTypes(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovTypes(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *Address) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.ObjectID.Size()
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
l = m.CID.Size()
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovTypes(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozTypes(x uint64) (n int) {
|
||||
return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *Address) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Address: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Address: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ObjectID", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.ObjectID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CID", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.CID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTypes(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipTypes(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthTypes
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupTypes
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthTypes
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
15
refs/types.proto
Normal file
15
refs/types.proto
Normal file
|
@ -0,0 +1,15 @@
|
|||
syntax = "proto3";
|
||||
package refs;
|
||||
option go_package = "github.com/nspcc-dev/neofs-proto/refs";
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
option (gogoproto.stable_marshaler_all) = true;
|
||||
|
||||
option (gogoproto.stringer_all) = false;
|
||||
option (gogoproto.goproto_stringer_all) = false;
|
||||
|
||||
message Address {
|
||||
bytes ObjectID = 1[(gogoproto.customtype) = "ObjectID", (gogoproto.nullable) = false]; // UUID
|
||||
bytes CID = 2[(gogoproto.customtype) = "CID", (gogoproto.nullable) = false]; // sha256
|
||||
}
|
112
refs/types_test.go
Normal file
112
refs/types_test.go
Normal file
|
@ -0,0 +1,112 @@
|
|||
package refs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neofs-crypto/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSGID(t *testing.T) {
|
||||
t.Run("check that marshal/unmarshal works like expected", func(t *testing.T) {
|
||||
var sgid1, sgid2 UUID
|
||||
|
||||
sgid1, err := NewSGID()
|
||||
require.NoError(t, err)
|
||||
|
||||
data, err := proto.Marshal(&sgid1)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, sgid2.Unmarshal(data))
|
||||
require.Equal(t, sgid1, sgid2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUUID(t *testing.T) {
|
||||
t.Run("parse should work like expected", func(t *testing.T) {
|
||||
var u UUID
|
||||
|
||||
id, err := uuid.NewRandom()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, u.Parse(id.String()))
|
||||
require.Equal(t, id.String(), u.String())
|
||||
})
|
||||
|
||||
t.Run("check that marshal/unmarshal works like expected", func(t *testing.T) {
|
||||
var u1, u2 UUID
|
||||
|
||||
u1 = UUID{0x8f, 0xe4, 0xeb, 0xa0, 0xb8, 0xfb, 0x49, 0x3b, 0xbb, 0x1d, 0x1d, 0x13, 0x6e, 0x69, 0xfc, 0xf7}
|
||||
|
||||
data, err := proto.Marshal(&u1)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, u2.Unmarshal(data))
|
||||
require.Equal(t, u1, u2)
|
||||
})
|
||||
|
||||
t.Run("check that marshal/unmarshal works like expected even for msg id", func(t *testing.T) {
|
||||
var u2 MessageID
|
||||
|
||||
u1, err := NewMessageID()
|
||||
require.NoError(t, err)
|
||||
|
||||
data, err := proto.Marshal(&u1)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, u2.Unmarshal(data))
|
||||
require.Equal(t, u1, u2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestOwnerID(t *testing.T) {
|
||||
t.Run("check that marshal/unmarshal works like expected", func(t *testing.T) {
|
||||
var u1, u2 OwnerID
|
||||
|
||||
owner, err := NewOwnerID()
|
||||
require.NoError(t, err)
|
||||
require.True(t, owner.Empty())
|
||||
|
||||
key := test.DecodeKey(0)
|
||||
|
||||
u1, err = NewOwnerID(&key.PublicKey)
|
||||
require.NoError(t, err)
|
||||
data, err := proto.Marshal(&u1)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, u2.Unmarshal(data))
|
||||
require.Equal(t, u1, u2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddress(t *testing.T) {
|
||||
cid := CIDForBytes([]byte("test"))
|
||||
|
||||
id, err := NewObjectID()
|
||||
require.NoError(t, err)
|
||||
|
||||
expect := strings.Join([]string{
|
||||
cid.String(),
|
||||
id.String(),
|
||||
}, joinSeparator)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
actual := (Address{
|
||||
ObjectID: id,
|
||||
CID: cid,
|
||||
}).String()
|
||||
|
||||
require.Equal(t, expect, actual)
|
||||
})
|
||||
|
||||
var temp Address
|
||||
require.NoError(t, temp.Parse(expect))
|
||||
require.Equal(t, expect, temp.String())
|
||||
|
||||
actual, err := ParseAddress(expect)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expect, actual.String())
|
||||
}
|
76
refs/uuid.go
Normal file
76
refs/uuid.go
Normal file
|
@ -0,0 +1,76 @@
|
|||
package refs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func encodeHex(dst []byte, uuid UUID) {
|
||||
hex.Encode(dst, uuid[:4])
|
||||
dst[8] = '-'
|
||||
hex.Encode(dst[9:13], uuid[4:6])
|
||||
dst[13] = '-'
|
||||
hex.Encode(dst[14:18], uuid[6:8])
|
||||
dst[18] = '-'
|
||||
hex.Encode(dst[19:23], uuid[8:10])
|
||||
dst[23] = '-'
|
||||
hex.Encode(dst[24:], uuid[10:])
|
||||
}
|
||||
|
||||
// Size returns size in bytes of UUID (UUIDSize).
|
||||
func (UUID) Size() int { return UUIDSize }
|
||||
|
||||
// Empty checks that current UUID is empty value.
|
||||
func (u UUID) Empty() bool { return bytes.Equal(u.Bytes(), emptyUUID) }
|
||||
|
||||
// Reset sets current UUID to empty value.
|
||||
func (u *UUID) Reset() { *u = [UUIDSize]byte{} }
|
||||
|
||||
// ProtoMessage method to satisfy proto.Message.
|
||||
func (UUID) ProtoMessage() {}
|
||||
|
||||
// Marshal returns UUID bytes representation.
|
||||
func (u UUID) Marshal() ([]byte, error) { return u.Bytes(), nil }
|
||||
|
||||
// MarshalTo returns UUID bytes representation.
|
||||
func (u UUID) MarshalTo(data []byte) (int, error) { return copy(data, u[:]), nil }
|
||||
|
||||
// Bytes returns UUID bytes representation.
|
||||
func (u UUID) Bytes() []byte {
|
||||
buf := make([]byte, UUIDSize)
|
||||
copy(buf, u[:])
|
||||
return buf
|
||||
}
|
||||
|
||||
// Equal checks that current UUID is equal to passed UUID.
|
||||
func (u UUID) Equal(u2 UUID) bool { return bytes.Equal(u.Bytes(), u2.Bytes()) }
|
||||
|
||||
func (u UUID) String() string {
|
||||
var buf [36]byte
|
||||
encodeHex(buf[:], u)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
// Unmarshal tries to parse UUID bytes representation.
|
||||
func (u *UUID) Unmarshal(data []byte) error {
|
||||
if ln := len(data); ln != UUIDSize {
|
||||
return errors.Wrapf(ErrWrongDataSize, "expect=%d, actual=%d", UUIDSize, ln)
|
||||
}
|
||||
|
||||
copy((*u)[:], data)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse tries to parse UUID string representation.
|
||||
func (u *UUID) Parse(id string) error {
|
||||
tmp, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not parse `%s`", id)
|
||||
}
|
||||
|
||||
copy((*u)[:], tmp[:])
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue