2016-08-31 18:29:54 +00:00
|
|
|
package restic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2016-09-01 17:20:15 +00:00
|
|
|
|
2017-07-23 12:21:03 +00:00
|
|
|
"github.com/restic/restic/internal/errors"
|
2016-08-31 18:29:54 +00:00
|
|
|
)
|
|
|
|
|
2016-08-31 18:58:57 +00:00
|
|
|
// Blob is one part of a file or a tree.
|
2016-08-31 18:29:54 +00:00
|
|
|
type Blob struct {
|
2016-08-31 18:58:57 +00:00
|
|
|
Type BlobType
|
|
|
|
Length uint
|
|
|
|
ID ID
|
|
|
|
Offset uint
|
2016-08-31 18:29:54 +00:00
|
|
|
}
|
|
|
|
|
2017-02-06 18:50:27 +00:00
|
|
|
func (b Blob) String() string {
|
|
|
|
return fmt.Sprintf("<Blob (%v) %v, offset %v, length %v>",
|
|
|
|
b.Type, b.ID.Str(), b.Offset, b.Length)
|
|
|
|
}
|
|
|
|
|
2016-08-31 18:58:57 +00:00
|
|
|
// PackedBlob is a blob stored within a file.
|
|
|
|
type PackedBlob struct {
|
|
|
|
Blob
|
|
|
|
PackID ID
|
2016-08-31 18:29:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// BlobHandle identifies a blob of a given type.
|
|
|
|
type BlobHandle struct {
|
|
|
|
ID ID
|
|
|
|
Type BlobType
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h BlobHandle) String() string {
|
|
|
|
return fmt.Sprintf("<%s/%s>", h.Type, h.ID.Str())
|
|
|
|
}
|
|
|
|
|
|
|
|
// BlobType specifies what a blob stored in a pack is.
|
|
|
|
type BlobType uint8
|
|
|
|
|
|
|
|
// These are the blob types that can be stored in a pack.
|
|
|
|
const (
|
|
|
|
InvalidBlob BlobType = iota
|
|
|
|
DataBlob
|
|
|
|
TreeBlob
|
|
|
|
)
|
|
|
|
|
|
|
|
func (t BlobType) String() string {
|
|
|
|
switch t {
|
|
|
|
case DataBlob:
|
|
|
|
return "data"
|
|
|
|
case TreeBlob:
|
|
|
|
return "tree"
|
2016-09-21 18:45:18 +00:00
|
|
|
case InvalidBlob:
|
|
|
|
return "invalid"
|
2016-08-31 18:29:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("<BlobType %d>", t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalJSON encodes the BlobType into JSON.
|
|
|
|
func (t BlobType) MarshalJSON() ([]byte, error) {
|
|
|
|
switch t {
|
|
|
|
case DataBlob:
|
|
|
|
return []byte(`"data"`), nil
|
|
|
|
case TreeBlob:
|
|
|
|
return []byte(`"tree"`), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, errors.New("unknown blob type")
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON decodes the BlobType from JSON.
|
|
|
|
func (t *BlobType) UnmarshalJSON(buf []byte) error {
|
|
|
|
switch string(buf) {
|
|
|
|
case `"data"`:
|
|
|
|
*t = DataBlob
|
|
|
|
case `"tree"`:
|
|
|
|
*t = TreeBlob
|
|
|
|
default:
|
|
|
|
return errors.New("unknown blob type")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2016-08-31 18:58:57 +00:00
|
|
|
|
|
|
|
// BlobHandles is an ordered list of BlobHandles that implements sort.Interface.
|
|
|
|
type BlobHandles []BlobHandle
|
|
|
|
|
|
|
|
func (h BlobHandles) Len() int {
|
|
|
|
return len(h)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h BlobHandles) Less(i, j int) bool {
|
|
|
|
for k, b := range h[i].ID {
|
|
|
|
if b == h[j].ID[k] {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if b < h[j].ID[k] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return h[i].Type < h[j].Type
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h BlobHandles) Swap(i, j int) {
|
|
|
|
h[i], h[j] = h[j], h[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h BlobHandles) String() string {
|
|
|
|
elements := make([]string, 0, len(h))
|
|
|
|
for _, e := range h {
|
|
|
|
elements = append(elements, e.String())
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%v", elements)
|
|
|
|
}
|