aboutsummaryrefslogtreecommitdiff
path: root/object/tree_parse.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-02-20 21:20:35 +0800
committerGravatar Runxi Yu2026-02-20 21:51:00 +0800
commitb5a545a3d883026d61beac5556fec2a45e9ec3d3 (patch)
tree6281f89df21cb4b63a16bbcb057c5f186c40b148 /object/tree_parse.go
parenttestgit: Add test harnesses (diff)
signatureNo signature
object: Add basic object code
Diffstat (limited to 'object/tree_parse.go')
-rw-r--r--object/tree_parse.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/object/tree_parse.go b/object/tree_parse.go
new file mode 100644
index 00000000..e1e560b6
--- /dev/null
+++ b/object/tree_parse.go
@@ -0,0 +1,57 @@
+package object
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+
+ "codeberg.org/lindenii/furgit/oid"
+)
+
+// ParseTree decodes a tree object body.
+func ParseTree(body []byte, algo oid.Algorithm) (*Tree, error) {
+ if algo.Size() == 0 {
+ return nil, ErrInvalidObject
+ }
+
+ var entries []TreeEntry
+ i := 0
+ for i < len(body) {
+ space := bytes.IndexByte(body[i:], ' ')
+ if space < 0 {
+ return nil, fmt.Errorf("object: tree: missing mode terminator")
+ }
+ modeBytes := body[i : i+space]
+ i += space + 1
+
+ nul := bytes.IndexByte(body[i:], 0)
+ if nul < 0 {
+ return nil, fmt.Errorf("object: tree: missing name terminator")
+ }
+ nameBytes := body[i : i+nul]
+ i += nul + 1
+
+ idEnd := i + algo.Size()
+ if idEnd > len(body) {
+ return nil, fmt.Errorf("object: tree: truncated child object id")
+ }
+ id, err := oid.FromBytes(algo, body[i:idEnd])
+ if err != nil {
+ return nil, err
+ }
+ i = idEnd
+
+ mode, err := strconv.ParseUint(string(modeBytes), 8, 32)
+ if err != nil {
+ return nil, fmt.Errorf("object: tree: parse mode: %w", err)
+ }
+
+ entries = append(entries, TreeEntry{
+ Mode: FileMode(mode),
+ Name: append([]byte(nil), nameBytes...),
+ ID: id,
+ })
+ }
+
+ return &Tree{Entries: entries}, nil
+}