forked from TrueCloudLab/frostfs-api-go
59858805a8
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
238 lines
5.1 KiB
Go
238 lines
5.1 KiB
Go
package container
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"math/bits"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// StableMarshal marshals auto-generated container structure into
|
|
// protobuf-compatible stable byte sequence.
|
|
func (m *Container) StableMarshal(buf []byte) ([]byte, error) {
|
|
if m == nil {
|
|
return []byte{}, nil
|
|
}
|
|
|
|
if buf == nil {
|
|
buf = make([]byte, m.StableSize())
|
|
}
|
|
|
|
var (
|
|
i, n, offset int
|
|
)
|
|
|
|
// Write owner id field.
|
|
|
|
if m.OwnerId != nil {
|
|
buf[i] = 0x0A // id:0x1 << 3 | wiretype:0x2
|
|
n = m.OwnerId.StableSize()
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(n))
|
|
|
|
_, err := m.OwnerId.StableMarshal(buf[i+1+offset:])
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "can't marshal owner id")
|
|
}
|
|
|
|
i += 1 + offset + n
|
|
}
|
|
|
|
// Write salt field.
|
|
|
|
buf[i] = 0x12 // id:0x2 << 3 | wiretype:0x2
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(len(m.Nonce)))
|
|
n = copy(buf[i+1+offset:], m.Nonce)
|
|
i += 1 + offset + n
|
|
|
|
// Write basic acl field.
|
|
|
|
buf[i] = 0x18 // id:0x3 << 3 | wiretype:0x0
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(m.BasicAcl))
|
|
i += 1 + offset
|
|
|
|
// Write attributes field.
|
|
|
|
for j := range m.Attributes {
|
|
buf[i] = 0x22 // id:0x4 << 3 | wiretype:0x2
|
|
n = m.Attributes[j].StableSize()
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(n))
|
|
|
|
_, err := m.Attributes[j].StableMarshal(buf[i+1+offset:])
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "can't marshal attribute %v",
|
|
m.Attributes[i].Key)
|
|
}
|
|
|
|
i += 1 + offset + n
|
|
}
|
|
|
|
// Write placement rule field.
|
|
|
|
if m.PlacementPolicy != nil {
|
|
buf[i] = 0x2A // id:0x5 << 3 | wiretype:0x2
|
|
n = m.PlacementPolicy.StableSize()
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(n))
|
|
|
|
_, err := m.PlacementPolicy.StableMarshal(buf[i+1+offset:])
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "can't marshal attribute %v",
|
|
m.Attributes[i].Key)
|
|
}
|
|
}
|
|
|
|
return buf, nil
|
|
}
|
|
|
|
func (m *Container) StableSize() int {
|
|
if m == nil {
|
|
return 0
|
|
}
|
|
|
|
var (
|
|
ln, size int
|
|
)
|
|
|
|
if m.OwnerId != nil {
|
|
ln = m.OwnerId.StableSize()
|
|
}
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + bytes length + bytes
|
|
|
|
ln = len(m.Nonce) // size of salt field
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + bytes length + bytes
|
|
|
|
// size of basic acl field
|
|
size += 1 + uvarIntSize(uint64(m.BasicAcl)) // wiretype + varint
|
|
|
|
// size of attributes
|
|
for i := range m.Attributes {
|
|
ln = m.Attributes[i].StableSize()
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of struct + struct
|
|
}
|
|
|
|
// size of placement rule
|
|
if m.PlacementPolicy != nil {
|
|
ln = m.PlacementPolicy.StableSize()
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of struct + struct
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
func (m *Container_Attribute) StableMarshal(buf []byte) ([]byte, error) {
|
|
if m == nil {
|
|
return []byte{}, nil
|
|
}
|
|
|
|
if buf == nil {
|
|
buf = make([]byte, m.StableSize())
|
|
}
|
|
|
|
var (
|
|
i, n, offset int
|
|
)
|
|
|
|
// Write key field.
|
|
|
|
buf[i] = 0x0A // id:0x1 << 3 | wiretype:0x2
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(len(m.Key)))
|
|
n = copy(buf[i+1+offset:], m.Key)
|
|
i += 1 + offset + n
|
|
|
|
// Write value field.
|
|
|
|
buf[i] = 0x12 // id:0x2 << 3 | wiretype:0x2
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(len(m.Value)))
|
|
copy(buf[i+1+offset:], m.Value)
|
|
|
|
return buf, nil
|
|
}
|
|
|
|
func (m *Container_Attribute) StableSize() int {
|
|
if m == nil {
|
|
return 0
|
|
}
|
|
|
|
var (
|
|
ln, size int
|
|
)
|
|
|
|
ln = len(m.Key) // size of key field
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of string + string
|
|
|
|
ln = len(m.Value) // size of value field
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of string + string
|
|
|
|
return size
|
|
}
|
|
|
|
func (m *PutRequest_Body) StableMarshal(buf []byte) ([]byte, error) {
|
|
if m == nil {
|
|
return []byte{}, nil
|
|
}
|
|
|
|
if buf == nil {
|
|
buf = make([]byte, m.StableSize())
|
|
}
|
|
|
|
var (
|
|
i, n, offset int
|
|
)
|
|
|
|
// Write container field.
|
|
|
|
if m.Container != nil {
|
|
buf[i] = 0x0A // id:0x1 << 3 | wiretype:0x2
|
|
n = m.Container.StableSize()
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(n))
|
|
|
|
_, err := m.Container.StableMarshal(buf[i+1+offset:])
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "can't marshal container")
|
|
}
|
|
|
|
i += 1 + offset + n
|
|
}
|
|
|
|
// Write public key field.
|
|
|
|
buf[i] = 0x12 // id:0x2 << 3 | wiretype:0x2
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(len(m.PublicKey)))
|
|
n = copy(buf[i+1+offset:], m.PublicKey)
|
|
i += 1 + offset + n
|
|
|
|
// Write signature field.
|
|
|
|
buf[i] = 0x1A // id:0x3 << 3 | wiretype:0x2
|
|
offset = binary.PutUvarint(buf[i+1:], uint64(len(m.Signature)))
|
|
copy(buf[i+1+offset:], m.Signature)
|
|
|
|
return buf, nil
|
|
}
|
|
|
|
func (m *PutRequest_Body) StableSize() int {
|
|
if m == nil {
|
|
return 0
|
|
}
|
|
|
|
var (
|
|
ln, size int
|
|
)
|
|
|
|
if m.Container != nil {
|
|
ln = m.Container.StableSize()
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of string + string
|
|
}
|
|
|
|
ln = len(m.PublicKey)
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of string + string
|
|
|
|
ln = len(m.Signature)
|
|
size += 1 + uvarIntSize(uint64(ln)) + ln // wiretype + size of string + string
|
|
|
|
return size
|
|
}
|
|
|
|
// uvarIntSize returns length of varint byte sequence for uint64 value 'x'.
|
|
func uvarIntSize(x uint64) int {
|
|
return (bits.Len64(x|1) + 6) / 7
|
|
}
|