From 9a44cd8ccff143a112436c38bfe5581e74b68f07 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Sun, 25 Oct 2015 20:30:36 +0100 Subject: formats/packfile: new reader API --- formats/packfile/objects.go | 276 -------------------------------------------- 1 file changed, 276 deletions(-) delete mode 100644 formats/packfile/objects.go (limited to 'formats/packfile/objects.go') diff --git a/formats/packfile/objects.go b/formats/packfile/objects.go deleted file mode 100644 index 9286090..0000000 --- a/formats/packfile/objects.go +++ /dev/null @@ -1,276 +0,0 @@ -package packfile - -import ( - "bytes" - "crypto/sha1" - "encoding/hex" - "fmt" - "strconv" - "time" -) - -type ObjectType int8 - -const ( - CommitObject ObjectType = 1 - TreeObject ObjectType = 2 - BlobObject ObjectType = 3 - TagObject ObjectType = 4 - OFSDeltaObject ObjectType = 6 - REFDeltaObject ObjectType = 7 -) - -func (t ObjectType) String() string { - switch t { - case CommitObject: - return "commit" - case TreeObject: - return "tree" - case BlobObject: - return "blob" - default: - return "-" - } -} - -type RAWObject struct { - Hash Hash - Type ObjectType - Size uint64 - Bytes []byte -} - -// Object generic object interface -type Object interface { - Type() ObjectType - Hash() Hash -} - -// Hash SHA1 hased content -type Hash [20]byte - -// ComputeHash compute the hash for a given objType and content -func ComputeHash(t ObjectType, content []byte) Hash { - h := []byte(t.String()) - h = append(h, ' ') - h = strconv.AppendInt(h, int64(len(content)), 10) - h = append(h, 0) - h = append(h, content...) - - return Hash(sha1.Sum(h)) -} - -func NewHash(s string) Hash { - b, _ := hex.DecodeString(s) - - var h Hash - copy(h[:], b) - - return h -} - -func (h Hash) String() string { - return hex.EncodeToString(h[:]) -} - -// Commit points to a single tree, marking it as what the project looked like -// at a certain point in time. It contains meta-information about that point -// in time, such as a timestamp, the author of the changes since the last -// commit, a pointer to the previous commit(s), etc. -// http://schacon.github.io/gitbook/1_the_git_object_model.html -type Commit struct { - Tree Hash - Parents []Hash - Author Signature - Committer Signature - Message string - hash Hash -} - -// ParseCommit transform a byte slice into a Commit struct -func ParseCommit(b []byte) (*Commit, error) { - o := &Commit{hash: ComputeHash(CommitObject, b)} - - lines := bytes.Split(b, []byte{'\n'}) - for i := range lines { - if len(lines[i]) > 0 { - var err error - - split := bytes.SplitN(lines[i], []byte{' '}, 2) - switch string(split[0]) { - case "tree": - _, err = hex.Decode(o.Tree[:], split[1]) - case "parent": - var h Hash - _, err = hex.Decode(h[:], split[1]) - if err == nil { - o.Parents = append(o.Parents, h) - } - case "author": - o.Author = ParseSignature(split[1]) - case "committer": - o.Committer = ParseSignature(split[1]) - } - - if err != nil { - return nil, err - } - } else { - o.Message = string(bytes.Join(append(lines[i+1:]), []byte{'\n'})) - break - } - - } - - return o, nil -} - -// Type returns the object type -func (o *Commit) Type() ObjectType { - return CommitObject -} - -// Hash returns the computed hash of the commit -func (o *Commit) Hash() Hash { - return o.hash -} - -// Tree is basically like a directory - it references a bunch of other trees -// and/or blobs (i.e. files and sub-directories) -type Tree struct { - Entries []TreeEntry - hash Hash -} - -// TreeEntry represents a file -type TreeEntry struct { - Name string - Hash Hash -} - -// ParseTree transform a byte slice into a Tree struct -func ParseTree(b []byte) (*Tree, error) { - o := &Tree{hash: ComputeHash(TreeObject, b)} - - if len(b) == 0 { - return o, nil - } - - for { - split := bytes.SplitN(b, []byte{0}, 2) - split1 := bytes.SplitN(split[0], []byte{' '}, 2) - - entry := TreeEntry{} - entry.Name = string(split1[1]) - copy(entry.Hash[:], split[1][0:20]) - - o.Entries = append(o.Entries, entry) - - b = split[1][20:] - if len(split[1]) == 20 { - break - } - } - - return o, nil -} - -// Type returns the object type -func (o *Tree) Type() ObjectType { - return TreeObject -} - -// Hash returns the computed hash of the tree -func (o *Tree) Hash() Hash { - return o.hash -} - -// Blob is used to store file data - it is generally a file. -type Blob struct { - Len int - hash Hash -} - -// ParseBlob transform a byte slice into a Blob struct -func ParseBlob(b []byte) (*Blob, error) { - return &Blob{ - Len: len(b), - hash: ComputeHash(BlobObject, b), - }, nil -} - -// Type returns the object type -func (o *Blob) Type() ObjectType { - return BlobObject -} - -// Hash returns the computed hash of the blob -func (o *Blob) Hash() Hash { - return o.hash -} - -type ContentCallback func(hash Hash, content []byte) - -// Signature represents an action signed by a person -type Signature struct { - Name string - Email string - When time.Time -} - -// ParseSignature parse a byte slice returning a new action signature. -func ParseSignature(signature []byte) Signature { - ret := Signature{} - if len(signature) == 0 { - return ret - } - - from := 0 - state := 'n' // n: name, e: email, t: timestamp, z: timezone - for i := 0; ; i++ { - var c byte - var end bool - if i < len(signature) { - c = signature[i] - } else { - end = true - } - - switch state { - case 'n': - if c == '<' || end { - if i == 0 { - break - } - ret.Name = string(signature[from : i-1]) - state = 'e' - from = i + 1 - } - case 'e': - if c == '>' || end { - ret.Email = string(signature[from:i]) - i++ - state = 't' - from = i + 1 - } - case 't': - if c == ' ' || end { - t, err := strconv.ParseInt(string(signature[from:i]), 10, 64) - if err == nil { - ret.When = time.Unix(t, 0) - } - end = true - } - } - - if end { - break - } - } - - return ret -} - -func (s *Signature) String() string { - return fmt.Sprintf("%q <%s> @ %s", s.Name, s.Email, s.When) -} -- cgit