2021-10-26 13:19:11 +00:00
|
|
|
package cid
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
2022-04-11 16:25:14 +00:00
|
|
|
"fmt"
|
2021-10-26 13:19:11 +00:00
|
|
|
|
2024-10-07 14:20:25 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
|
2021-10-26 13:19:11 +00:00
|
|
|
"github.com/mr-tron/base58"
|
|
|
|
)
|
|
|
|
|
2022-12-29 10:46:18 +00:00
|
|
|
// ID represents FrostFS container identifier.
|
2021-10-26 13:19:11 +00:00
|
|
|
//
|
2024-10-07 14:20:25 +00:00
|
|
|
// ID is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs.ContainerID
|
2022-04-11 16:25:14 +00:00
|
|
|
// message. See ReadFromV2 / WriteToV2 methods.
|
|
|
|
//
|
|
|
|
// Instances can be created using built-in var declaration.
|
|
|
|
//
|
|
|
|
// Note that direct typecast is not safe and may result in loss of compatibility:
|
2022-08-24 14:17:40 +00:00
|
|
|
//
|
|
|
|
// _ = ID([32]byte) // not recommended
|
2022-04-11 16:25:14 +00:00
|
|
|
type ID [sha256.Size]byte
|
2021-10-26 13:19:11 +00:00
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
// ReadFromV2 reads ID from the refs.ContainerID message.
|
|
|
|
// Returns an error if the message is malformed according
|
2022-12-29 10:46:18 +00:00
|
|
|
// to the FrostFS API V2 protocol.
|
2021-10-26 13:19:11 +00:00
|
|
|
//
|
2022-04-11 16:25:14 +00:00
|
|
|
// See also WriteToV2.
|
|
|
|
func (id *ID) ReadFromV2(m refs.ContainerID) error {
|
|
|
|
return id.Decode(m.GetValue())
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
// WriteToV2 writes ID to the refs.ContainerID message.
|
|
|
|
// The message must not be nil.
|
|
|
|
//
|
|
|
|
// See also ReadFromV2.
|
|
|
|
func (id ID) WriteToV2(m *refs.ContainerID) {
|
|
|
|
m.SetValue(id[:])
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
// Encode encodes ID into 32 bytes of dst. Panics if
|
|
|
|
// dst length is less than 32.
|
2021-10-26 13:19:11 +00:00
|
|
|
//
|
2022-04-11 16:25:14 +00:00
|
|
|
// Zero ID is all zeros.
|
|
|
|
//
|
|
|
|
// See also Decode.
|
|
|
|
func (id ID) Encode(dst []byte) {
|
|
|
|
if l := len(dst); l < sha256.Size {
|
|
|
|
panic(fmt.Sprintf("destination length is less than %d bytes: %d", sha256.Size, l))
|
|
|
|
}
|
2021-10-26 13:19:11 +00:00
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
copy(dst, id[:])
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
// Decode decodes src bytes into ID.
|
2021-10-26 13:19:11 +00:00
|
|
|
//
|
2022-04-11 16:25:14 +00:00
|
|
|
// Decode expects that src has 32 bytes length. If the input is malformed,
|
|
|
|
// Decode returns an error describing format violation. In this case ID
|
|
|
|
// remains unchanged.
|
|
|
|
//
|
|
|
|
// Decode doesn't mutate src.
|
|
|
|
//
|
|
|
|
// See also Encode.
|
|
|
|
func (id *ID) Decode(src []byte) error {
|
|
|
|
if len(src) != sha256.Size {
|
|
|
|
return fmt.Errorf("invalid length %d", len(src))
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
copy(id[:], src)
|
2021-10-26 13:19:11 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
// SetSHA256 sets container identifier value to SHA256 checksum of container structure.
|
|
|
|
func (id *ID) SetSHA256(v [sha256.Size]byte) {
|
|
|
|
copy(id[:], v[:])
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equals defines a comparison relation between two ID instances.
|
|
|
|
//
|
|
|
|
// Note that comparison using '==' operator is not recommended since it MAY result
|
|
|
|
// in loss of compatibility.
|
|
|
|
func (id ID) Equals(id2 ID) bool {
|
|
|
|
return id == id2
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-12-29 10:46:18 +00:00
|
|
|
// EncodeToString encodes ID into FrostFS API protocol string.
|
2022-04-11 16:25:14 +00:00
|
|
|
//
|
|
|
|
// Zero ID is base58 encoding of 32 zeros.
|
|
|
|
//
|
|
|
|
// See also DecodeString.
|
|
|
|
func (id ID) EncodeToString() string {
|
|
|
|
return base58.Encode(id[:])
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-12-29 10:46:18 +00:00
|
|
|
// DecodeString decodes string into ID according to FrostFS API protocol. Returns
|
2022-04-11 16:25:14 +00:00
|
|
|
// an error if s is malformed.
|
|
|
|
//
|
|
|
|
// See also DecodeString.
|
|
|
|
func (id *ID) DecodeString(s string) error {
|
|
|
|
data, err := base58.Decode(s)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("decode base58: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return id.Decode(data)
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|
|
|
|
|
2022-04-11 16:25:14 +00:00
|
|
|
// 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
|
2022-12-29 10:46:18 +00:00
|
|
|
// be used to encode ID into FrostFS protocol string.
|
2022-04-11 16:25:14 +00:00
|
|
|
func (id ID) String() string {
|
|
|
|
return id.EncodeToString()
|
2021-10-26 13:19:11 +00:00
|
|
|
}
|