Files

102 lines
1.9 KiB
Go

package gitnaturalapi
import "encoding/hex"
type TreeEntry struct {
Path string
Mode string
IsDir bool
Hash string
}
type TreeFile struct {
Name string
Hash string
Content []byte
}
type TreeDirectory struct {
Name string
Hash string
Content *Tree
}
type Tree struct {
Directories []TreeDirectory
Files []TreeFile
}
func LoadTree(obj *ParsedObject, objects map[string]*ParsedObject, depth *int) *Tree {
directories := make([]TreeDirectory, 0)
files := make([]TreeFile, 0)
entries := ParseTree(obj.Data)
for _, entry := range entries {
child := objects[entry.Hash]
if entry.IsDir {
var content *Tree
if child != nil && (depth == nil || *depth > 0) {
var newDepth *int
if depth != nil {
d := *depth - 1
newDepth = &d
}
content = LoadTree(child, objects, newDepth)
}
directories = append(directories, TreeDirectory{
Name: entry.Path,
Hash: entry.Hash,
Content: content,
})
} else {
var content []byte
if child != nil {
content = child.Data
}
files = append(files, TreeFile{
Name: entry.Path,
Hash: entry.Hash,
Content: content,
})
}
}
return &Tree{Directories: directories, Files: files}
}
func ParseTree(treeData []byte) []TreeEntry {
entries := make([]TreeEntry, 0)
offset := 0
for offset < len(treeData) {
modeEnd := offset
for treeData[modeEnd] != 0x20 {
modeEnd++
}
mode := string(treeData[offset:modeEnd])
offset = modeEnd + 1
filenameEnd := offset
for treeData[filenameEnd] != 0x00 {
filenameEnd++
}
path := string(treeData[offset:filenameEnd])
offset = filenameEnd + 1
hash := hex.EncodeToString(treeData[offset : offset+20])
offset += 20
isDir := mode == "40000" || mode == "040000"
entries = append(entries, TreeEntry{
Mode: mode,
Path: path,
Hash: hash,
IsDir: isDir,
})
}
return entries
}