2024-01-03 13:36:23 +00:00
|
|
|
package encoding
|
2024-01-03 08:47:47 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-01-24 18:50:42 +00:00
|
|
|
"encoding/base32"
|
|
|
|
"encoding/base64"
|
2024-01-04 09:19:24 +00:00
|
|
|
"encoding/json"
|
2024-01-03 08:47:47 +00:00
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
2024-01-03 13:27:04 +00:00
|
|
|
"git.lumeweb.com/LumeWeb/libs5-go/utils"
|
2024-01-03 08:47:47 +00:00
|
|
|
)
|
|
|
|
|
2024-01-03 13:20:03 +00:00
|
|
|
type MultihashCode = int
|
|
|
|
|
2024-01-03 08:47:47 +00:00
|
|
|
type Multihash struct {
|
2024-01-06 12:11:51 +00:00
|
|
|
fullBytes []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) FullBytes() []byte {
|
|
|
|
return m.fullBytes
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
2024-01-04 09:19:24 +00:00
|
|
|
var _ json.Marshaler = (*Multihash)(nil)
|
|
|
|
var _ json.Unmarshaler = (*Multihash)(nil)
|
|
|
|
|
2024-01-03 13:36:23 +00:00
|
|
|
func NewMultihash(fullBytes []byte) *Multihash {
|
2024-01-06 12:11:51 +00:00
|
|
|
return &Multihash{fullBytes: fullBytes}
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) FunctionType() types.HashType {
|
2024-01-06 12:11:51 +00:00
|
|
|
return types.HashType(m.fullBytes[0])
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) HashBytes() []byte {
|
2024-01-06 12:11:51 +00:00
|
|
|
return m.fullBytes[1:]
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
2024-01-17 16:25:45 +00:00
|
|
|
func MultihashFromBytes(bytes []byte, kind types.HashType) *Multihash {
|
|
|
|
return NewMultihash(append([]byte{byte(kind)}, bytes...))
|
|
|
|
}
|
|
|
|
|
2024-01-03 13:36:23 +00:00
|
|
|
func MultihashFromBase64Url(hash string) (*Multihash, error) {
|
2024-01-24 18:55:56 +00:00
|
|
|
ret, err := base64.RawURLEncoding.DecodeString(hash)
|
2024-01-03 08:47:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-01-03 13:36:23 +00:00
|
|
|
return NewMultihash(ret), nil
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) ToBase64Url() (string, error) {
|
2024-01-24 18:55:56 +00:00
|
|
|
return base64.RawURLEncoding.EncodeToString(m.fullBytes), nil
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) ToBase32() (string, error) {
|
2024-01-24 18:50:42 +00:00
|
|
|
return base32.StdEncoding.EncodeToString(m.fullBytes), nil
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) ToString() (string, error) {
|
|
|
|
if m.FunctionType() == types.HashType(types.CIDTypeBridge) {
|
2024-01-06 12:11:51 +00:00
|
|
|
return string(m.fullBytes), nil // Assumes the bytes are valid UTF-8
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
return m.ToBase64Url()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Multihash) Equals(other *Multihash) bool {
|
2024-01-06 12:11:51 +00:00
|
|
|
return bytes.Equal(m.fullBytes, other.fullBytes)
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
2024-01-03 13:20:03 +00:00
|
|
|
func (m *Multihash) HashCode() MultihashCode {
|
2024-01-06 12:11:51 +00:00
|
|
|
return utils.HashCode(m.fullBytes[:4])
|
2024-01-03 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
2024-01-04 09:19:24 +00:00
|
|
|
func (b *Multihash) UnmarshalJSON(data []byte) error {
|
2024-01-24 18:50:42 +00:00
|
|
|
decodedData, err := MultihashFromBase64Url(string(data))
|
2024-01-04 09:19:24 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-01-24 18:50:42 +00:00
|
|
|
b.fullBytes = decodedData.fullBytes
|
2024-01-04 09:19:24 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (b Multihash) MarshalJSON() ([]byte, error) {
|
|
|
|
url, err := b.ToBase64Url()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return []byte(url), nil
|
|
|
|
|
|
|
|
}
|