172 lines
4.2 KiB
Go
172 lines
4.2 KiB
Go
package oid
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
)
|
|
|
|
// Address represents global object identifier in FrostFS network. Each object
|
|
// belongs to exactly one container and is uniquely addressed within the container.
|
|
//
|
|
// Address is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs.Address
|
|
// message. See ReadFromV2 / WriteToV2 methods.
|
|
//
|
|
// Instances can be created using built-in var declaration.
|
|
type Address struct {
|
|
cnr cid.ID
|
|
|
|
obj ID
|
|
}
|
|
|
|
// ReadFromV2 reads Address from the refs.Address message. Returns an error if
|
|
// the message is malformed according to the FrostFS API V2 protocol.
|
|
//
|
|
// See also WriteToV2.
|
|
func (x *Address) ReadFromV2(m refs.Address) error {
|
|
cnr := m.GetContainerID()
|
|
if cnr == nil {
|
|
return errors.New("missing container ID")
|
|
}
|
|
|
|
obj := m.GetObjectID()
|
|
if obj == nil {
|
|
return errors.New("missing object ID")
|
|
}
|
|
|
|
err := x.cnr.ReadFromV2(*cnr)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid container ID: %w", err)
|
|
}
|
|
|
|
err = x.obj.ReadFromV2(*obj)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid object ID: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// WriteToV2 writes Address to the refs.Address message.
|
|
// The message must not be nil.
|
|
//
|
|
// See also ReadFromV2.
|
|
func (x Address) WriteToV2(m *refs.Address) {
|
|
var obj refs.ObjectID
|
|
x.obj.WriteToV2(&obj)
|
|
|
|
var cnr refs.ContainerID
|
|
x.cnr.WriteToV2(&cnr)
|
|
|
|
m.SetObjectID(&obj)
|
|
m.SetContainerID(&cnr)
|
|
}
|
|
|
|
// MarshalJSON encodes Address into a JSON format of the FrostFS API protocol
|
|
// (Protocol Buffers JSON).
|
|
//
|
|
// See also UnmarshalJSON.
|
|
func (x Address) MarshalJSON() ([]byte, error) {
|
|
var m refs.Address
|
|
x.WriteToV2(&m)
|
|
|
|
return m.MarshalJSON()
|
|
}
|
|
|
|
// UnmarshalJSON decodes FrostFS API protocol JSON format into the Address
|
|
// (Protocol Buffers JSON). Returns an error describing a format violation.
|
|
//
|
|
// See also MarshalJSON.
|
|
func (x *Address) UnmarshalJSON(data []byte) error {
|
|
var m refs.Address
|
|
|
|
err := m.UnmarshalJSON(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return x.ReadFromV2(m)
|
|
}
|
|
|
|
// Container returns unique identifier of the FrostFS object container.
|
|
//
|
|
// Zero Address has zero container ID, which is incorrect according to FrostFS
|
|
// API protocol.
|
|
//
|
|
// See also SetContainer.
|
|
func (x Address) Container() cid.ID {
|
|
return x.cnr
|
|
}
|
|
|
|
// SetContainer sets unique identifier of the FrostFS object container.
|
|
//
|
|
// See also Container.
|
|
func (x *Address) SetContainer(id cid.ID) {
|
|
x.cnr = id
|
|
}
|
|
|
|
// Object returns unique identifier of the object in the container
|
|
// identified by Container().
|
|
//
|
|
// Zero Address has zero object ID, which is incorrect according to FrostFS
|
|
// API protocol.
|
|
//
|
|
// See also SetObject.
|
|
func (x Address) Object() ID {
|
|
return x.obj
|
|
}
|
|
|
|
// SetObject sets unique identifier of the object in the container
|
|
// identified by Container().
|
|
//
|
|
// See also Object.
|
|
func (x *Address) SetObject(id ID) {
|
|
x.obj = id
|
|
}
|
|
|
|
// delimiter of container and object IDs in Address protocol string.
|
|
const idDelimiter = "/"
|
|
|
|
// EncodeToString encodes Address into FrostFS API protocol string: concatenation
|
|
// of the string-encoded container and object IDs delimited by a slash.
|
|
//
|
|
// See also DecodeString.
|
|
func (x Address) EncodeToString() string {
|
|
return x.cnr.EncodeToString() + "/" + x.obj.EncodeToString()
|
|
}
|
|
|
|
// DecodeString decodes string into Address according to FrostFS API protocol. Returns
|
|
// an error if s is malformed.
|
|
//
|
|
// See also DecodeString.
|
|
func (x *Address) DecodeString(s string) error {
|
|
indDelimiter := strings.Index(s, idDelimiter)
|
|
if indDelimiter < 0 {
|
|
return errors.New("missing delimiter")
|
|
}
|
|
|
|
err := x.cnr.DecodeString(s[:indDelimiter])
|
|
if err != nil {
|
|
return fmt.Errorf("decode container string: %w", err)
|
|
}
|
|
|
|
err = x.obj.DecodeString(s[indDelimiter+1:])
|
|
if err != nil {
|
|
return fmt.Errorf("decode object string: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// String implements fmt.Stringer.
|
|
//
|
|
// String is designed to be human-readable, and its format MAY differ between
|
|
// SDK versions. String MAY return same result as EncodeToString. String MUST NOT
|
|
// be used to encode Address into FrostFS protocol string.
|
|
func (x Address) String() string {
|
|
return x.EncodeToString()
|
|
}
|