84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package codec
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math"
|
|
)
|
|
|
|
// MaxBytesKeyNonTerminalSize defines the maximum length of a bytes key encoded
|
|
// using the BytesKey KeyCodec.
|
|
const MaxBytesKeyNonTerminalSize = math.MaxUint8
|
|
|
|
func NewBytesKey[T ~[]byte]() NameableKeyCodec[T] { return bytesKey[T]{} }
|
|
|
|
type bytesKey[T ~[]byte] struct{}
|
|
|
|
func (b bytesKey[T]) Encode(buffer []byte, key T) (int, error) {
|
|
return copy(buffer, key), nil
|
|
}
|
|
|
|
func (bytesKey[T]) Decode(buffer []byte) (int, T, error) {
|
|
// todo: should we copy it? collections will just discard the buffer, so from coll POV is not needed.
|
|
return len(buffer), buffer, nil
|
|
}
|
|
|
|
func (bytesKey[T]) Size(key T) int {
|
|
return len(key)
|
|
}
|
|
|
|
func (bytesKey[T]) EncodeJSON(value T) ([]byte, error) {
|
|
return json.Marshal(value)
|
|
}
|
|
|
|
func (bytesKey[T]) DecodeJSON(b []byte) (T, error) {
|
|
var t T
|
|
err := json.Unmarshal(b, &t)
|
|
return t, err
|
|
}
|
|
|
|
func (b bytesKey[T]) Stringify(key T) string {
|
|
return fmt.Sprintf("hexBytes:%x", key)
|
|
}
|
|
|
|
func (b bytesKey[T]) KeyType() string {
|
|
return "bytes"
|
|
}
|
|
|
|
func (b bytesKey[T]) EncodeNonTerminal(buffer []byte, key T) (int, error) {
|
|
if len(key) > MaxBytesKeyNonTerminalSize {
|
|
return 0, fmt.Errorf(
|
|
"%w: bytes key non terminal size cannot exceed: %d, got: %d",
|
|
ErrEncoding, MaxBytesKeyNonTerminalSize, len(key),
|
|
)
|
|
}
|
|
|
|
buffer[0] = uint8(len(key))
|
|
written := copy(buffer[1:], key)
|
|
return written + 1, nil
|
|
}
|
|
|
|
func (bytesKey[T]) DecodeNonTerminal(buffer []byte) (int, T, error) {
|
|
l := len(buffer)
|
|
if l == 0 {
|
|
return 0, nil, fmt.Errorf("%w: bytes key non terminal decoding cannot have an empty buffer", ErrEncoding)
|
|
}
|
|
|
|
keyLength := int(buffer[0])
|
|
if len(buffer[1:]) < keyLength {
|
|
return 0, nil, fmt.Errorf(
|
|
"%w: bytes key non terminal decoding isn't big enough, want at least: %d, got: %d",
|
|
ErrEncoding, keyLength, len(buffer[1:]),
|
|
)
|
|
}
|
|
return 1 + keyLength, buffer[1 : keyLength+1], nil
|
|
}
|
|
|
|
func (bytesKey[T]) SizeNonTerminal(key T) int {
|
|
return len(key) + 1
|
|
}
|
|
|
|
func (b bytesKey[T]) WithName(name string) KeyCodec[T] {
|
|
return NamedKeyCodec[T]{KeyCodec: b, Name: name}
|
|
}
|