98 lines
2.2 KiB
Go
98 lines
2.2 KiB
Go
|
package meta
|
||
|
|
||
|
import (
|
||
|
"crypto/sha256"
|
||
|
"encoding/base64"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
type Meta struct {
|
||
|
Params
|
||
|
Name string `json:"name"`
|
||
|
ShardMerkle FileHash `json:"shardMerkle"`
|
||
|
ShardHashes HashList `json:"shardHashes"`
|
||
|
ParityMerkle FileHash `json:"parityMerkle"`
|
||
|
ParityHashes HashList `json:"parityHashes"`
|
||
|
}
|
||
|
|
||
|
type FileHash []byte
|
||
|
|
||
|
func (hash FileHash) MarshalJSON() ([]byte, error) {
|
||
|
text, err := hash.MarshalText()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return json.Marshal(string(text))
|
||
|
}
|
||
|
|
||
|
func (hash FileHash) MarshalText() ([]byte, error) {
|
||
|
return []byte(base64.StdEncoding.EncodeToString(hash)), nil
|
||
|
}
|
||
|
|
||
|
func (hash *FileHash) UnmarshalJSON(data []byte) error {
|
||
|
s := ""
|
||
|
json.Unmarshal(data, &s)
|
||
|
return hash.UnmarshalText([]byte(s))
|
||
|
}
|
||
|
|
||
|
func (hash *FileHash) UnmarshalText(text []byte) error {
|
||
|
raw, err := base64.StdEncoding.DecodeString(string(text))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if len(raw) != sha256.Size {
|
||
|
return fmt.Errorf("expected hash to be %d bytes (got %d)", sha256.Size, len(raw))
|
||
|
}
|
||
|
*hash = raw
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
type HashList [][]byte
|
||
|
|
||
|
func (hashes HashList) MarshalJSON() ([]byte, error) {
|
||
|
text, err := hashes.MarshalText()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return json.Marshal(string(text))
|
||
|
}
|
||
|
|
||
|
func (hashes HashList) MarshalText() ([]byte, error) {
|
||
|
// fmt.Printf("marshal hash list...\n")
|
||
|
hashesLen := len(hashes)
|
||
|
hashLen := 0
|
||
|
dataLen := 0
|
||
|
if hashesLen != 0 {
|
||
|
hashLen = len(hashes[0])
|
||
|
dataLen = hashesLen * hashLen
|
||
|
}
|
||
|
data := make([]byte, dataLen)
|
||
|
for i, hash := range hashes {
|
||
|
copy(data[i*hashLen:], hash)
|
||
|
}
|
||
|
return []byte(base64.StdEncoding.EncodeToString(data)), nil
|
||
|
}
|
||
|
|
||
|
func (hashes *HashList) UnmarshalJSON(data []byte) error {
|
||
|
s := ""
|
||
|
json.Unmarshal(data, &s)
|
||
|
return hashes.UnmarshalText([]byte(s))
|
||
|
}
|
||
|
|
||
|
func (hashes *HashList) UnmarshalText(text []byte) error {
|
||
|
raw, err := base64.StdEncoding.DecodeString(string(text))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if len(raw)%sha256.Size != 0 {
|
||
|
return fmt.Errorf("expected hash list to be multiple of %d bytes", sha256.Size)
|
||
|
}
|
||
|
split := make([][]byte, len(raw)/sha256.Size)
|
||
|
for i := 0; i < len(raw); i += sha256.Size {
|
||
|
split[i/sha256.Size] = raw[i : i+sha256.Size]
|
||
|
}
|
||
|
*hashes = split
|
||
|
return nil
|
||
|
}
|