git-lfs/pointer/pointer.go

120 lines
2.4 KiB
Go
Raw Normal View History

package pointer
2013-09-27 17:08:19 +00:00
import (
2014-07-24 21:23:02 +00:00
"bufio"
2013-09-27 17:08:19 +00:00
"bytes"
"errors"
2014-07-24 22:02:27 +00:00
"fmt"
2014-07-24 21:23:02 +00:00
ini "github.com/glacjay/goini"
2013-09-27 17:08:19 +00:00
"io"
"regexp"
2014-07-24 21:23:02 +00:00
"strconv"
"strings"
2013-09-27 17:08:19 +00:00
)
var (
2014-07-24 20:49:47 +00:00
MediaWarning = []byte("# git-media\n")
alpha = "http://git-media.io/v/1"
latest = "http://git-media.io/v/2"
oidType = "sha256"
alphaHeaderRE = regexp.MustCompile(`\A# (.*git-media|external)`)
2014-07-24 22:02:27 +00:00
template = `[git-media]
version=%s
oid=sha256:%s
size=%d
`
)
type Pointer struct {
Version string
Oid string
Size int64
2014-07-24 20:49:47 +00:00
OidType string
}
2013-09-27 17:08:53 +00:00
func NewPointer(oid string, size int64) *Pointer {
2014-07-24 21:23:02 +00:00
return &Pointer{latest, oid, size, oidType}
}
func (p *Pointer) Smudge(writer io.Writer) error {
return Smudge(writer, p)
}
func (p *Pointer) Encode(writer io.Writer) (int, error) {
return Encode(writer, p)
}
func Encode(writer io.Writer, pointer *Pointer) (int, error) {
2014-07-24 22:02:27 +00:00
return writer.Write([]byte(fmt.Sprintf(template,
latest, pointer.Oid, pointer.Size)))
2013-09-27 17:08:19 +00:00
}
func Decode(reader io.Reader) (*Pointer, error) {
2014-07-24 20:49:47 +00:00
buf := make([]byte, 200)
2013-10-04 13:48:02 +00:00
written, err := reader.Read(buf)
if err != nil {
return nil, err
2013-10-04 13:48:02 +00:00
}
2013-09-27 17:08:19 +00:00
2014-07-24 20:49:47 +00:00
data := bytes.TrimSpace(buf[0:written])
2013-09-27 17:08:19 +00:00
2014-07-24 20:49:47 +00:00
if alphaHeaderRE.Match(data) {
return decodeAlpha(data)
} else {
2014-07-24 21:23:02 +00:00
return decodeIni(data)
}
2014-07-24 20:49:47 +00:00
}
2014-07-24 21:23:02 +00:00
func decodeIni(data []byte) (*Pointer, error) {
dict, err := ini.LoadReader(bufio.NewReader(bytes.NewReader(data)))
if err != nil {
return nil, err
}
v, ok := dict.GetString("git-media", "version")
if !ok || v != latest {
if len(v) == 0 {
v = "--"
}
return nil, errors.New("Invalid version: " + v)
}
oidValue, ok := dict.GetString("git-media", "oid")
if !ok {
return nil, errors.New("Invalid Oid")
}
oidParts := strings.SplitN(oidValue, ":", 2)
if len(oidParts) != 2 {
return nil, errors.New("Invalid Oid type in" + oidValue)
}
if oidParts[0] != oidType {
return nil, errors.New("Invalid Oid type: " + oidParts[0])
}
oid := oidParts[1]
var size int64
sizeStr, ok := dict.GetString("git-media", "size")
if !ok {
return nil, errors.New("Invalid Oid")
} else {
size, err = strconv.ParseInt(sizeStr, 10, 0)
if err != nil {
return nil, errors.New("Invalid size: " + sizeStr)
}
}
return NewPointer(oid, size), nil
}
2014-07-24 20:49:47 +00:00
func decodeAlpha(data []byte) (*Pointer, error) {
2014-07-24 21:23:02 +00:00
lines := bytes.Split(data, []byte("\n"))
2014-07-24 20:49:47 +00:00
last := len(lines) - 1
if last == 0 {
return nil, errors.New("No sha in pointer file")
2013-10-04 13:48:02 +00:00
}
2014-07-24 20:49:47 +00:00
return &Pointer{alpha, string(lines[last]), 0, oidType}, nil
2013-09-27 17:08:19 +00:00
}