105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
// Copyright © 2019 Weald Technology Trading
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Package multicodec provides the ability to add and remove codec prefixes from data.
|
|
package multicodec
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
)
|
|
|
|
// AddCodec adds a codec prefix to a byte array.
|
|
// It returns a new byte array with the relevant codec prefixed.
|
|
func AddCodec(name string, data []byte) ([]byte, error) {
|
|
id, err := ID(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
buf := make([]byte, binary.MaxVarintLen64)
|
|
size := binary.PutUvarint(buf, id)
|
|
res := make([]byte, size+len(data))
|
|
copy(res, buf[0:size])
|
|
copy(res[size:], data)
|
|
return res, nil
|
|
}
|
|
|
|
// RemoveCodec removes a codec prefix from a byte array.
|
|
// It returns a slice of the input byte array without the codec prefix, along with the ID of the codec that has been removed.
|
|
func RemoveCodec(data []byte) ([]byte, uint64, error) {
|
|
id, size := binary.Uvarint(data)
|
|
if id == 0 {
|
|
return nil, 0, fmt.Errorf("failed to find codec prefix to remove")
|
|
}
|
|
return data[size:], id, nil
|
|
}
|
|
|
|
// GetCodec returns the ID of the codec prefix from a byte array
|
|
func GetCodec(data []byte) (uint64, error) {
|
|
id, _ := binary.Uvarint(data)
|
|
if id == 0 {
|
|
return 0, fmt.Errorf("failed to find codec prefix to remove")
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
// IsCodec returns true if the data is of the supplied codec prefix, otherwise false
|
|
func IsCodec(name string, data []byte) bool {
|
|
id, err := GetCodec(data)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
codecName, err := Name(id)
|
|
if err != nil {
|
|
// Failed to obtain name for ID
|
|
return false
|
|
}
|
|
return codecName == name
|
|
}
|
|
|
|
// ID obtains the ID of a codec from its name
|
|
func ID(name string) (uint64, error) {
|
|
codec, exists := codecs[name]
|
|
if !exists {
|
|
return 0, fmt.Errorf("unknown name %s", name)
|
|
}
|
|
return codec.id, nil
|
|
}
|
|
|
|
// MustID obtains the ID of a codec from its name, panicking if not present.
|
|
func MustID(name string) uint64 {
|
|
codec, exists := codecs[name]
|
|
if !exists {
|
|
panic(fmt.Errorf("unknown name %s", name))
|
|
}
|
|
return codec.id
|
|
}
|
|
|
|
// Name obtains the name of a codec from its ID
|
|
func Name(id uint64) (string, error) {
|
|
codec, exists := reverseCodecs[id]
|
|
if !exists {
|
|
return "", fmt.Errorf("unknown ID 0x%x", id)
|
|
}
|
|
return codec.name, nil
|
|
}
|
|
|
|
// MustName obtains the name of a codec from its ID, panicking if not present.
|
|
func MustName(id uint64) string {
|
|
codec, exists := reverseCodecs[id]
|
|
if !exists {
|
|
panic(fmt.Errorf("unknown ID 0x%x", id))
|
|
}
|
|
return codec.name
|
|
}
|