Lindenii Project Forge
Primitive tree-parsing function
use bytes; use crypto::sha256; use errors; use strconv; use strings;
export type tree = struct { oid: oid, entries: []tree_entry, }; export fn tree_finish(t: tree) void = { for (let entry .. t.entries) { tree_entry_finish(entry); }; free(t.entries); }; export type tree_entry = struct { mode: u32, name: []u8, oid: oid, }; 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 }; };