From 0aca3bcfe7aaf83b22bdebceaf0209fa393d0c6b Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 14 Sep 2025 03:24:22 +0800 Subject: [PATCH] Primitive tree-parsing function --- git/obj_tree.ha | 40 ++++++++++++++++++++++++++++++++++++++++ diff --git a/git/obj_tree.ha b/git/obj_tree.ha index 4082b28e4a028dd1559574be571d14daf5b76a0a..58c3d41e50aa03121cf67230a7fa4e518c208381 100644 --- a/git/obj_tree.ha +++ b/git/obj_tree.ha @@ -1,3 +1,9 @@ +use bytes; +use crypto::sha256; +use errors; +use strconv; +use strings; + export type tree = struct { oid: oid, entries: []tree_entry, @@ -17,3 +23,37 @@ }; export fn tree_entry_finish(te: tree_entry) void = { free(te.name); }; + +export fn parse_tree(id: oid, body: []u8) (tree | errors::invalid | strconv::invalid | strconv::overflow | nomem) = { + let entries: []tree_entry = []; + let i = 0z; + + for (i < len(body)) { + const sp = match (bytes::index(body[i..], ' ')) { + case let j: size => yield j; + case void => return errors::invalid; + }; + const mode_b = body[i .. i+sp]; + i += sp + 1z; + + const nul = match (bytes::index(body[i..], 0u8)) { + case let j: size => yield j; + case void => return errors::invalid; + }; + const name_b = body[i .. i+nul]; + i += nul + 1z; + + if (i + sha256::SZ > len(body)) return errors::invalid; + let child: oid = [0...]; + child[..] = body[i .. i+sha256::SZ]; + i += sha256::SZ; + + const mode_s = strings::fromutf8_unsafe(mode_b); + const mode = strconv::stou32(mode_s, strconv::base::OCT)?; + + const name = name_b[..]; + append(entries, tree_entry { mode = mode, name = name, oid = child })!; + }; + + return tree { oid = id, entries = entries }; +}; -- 2.48.1