102 lines
1.9 KiB
Go
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
|
|
}
|