Skip to content
This repository was archived by the owner on Sep 18, 2024. It is now read-only.

Commit 977ba2b

Browse files
committed
Build FileTree header to be used when decompressing
1 parent c94069f commit 977ba2b

1 file changed

Lines changed: 63 additions & 0 deletions

File tree

lib/bakeware/file_tree.ex

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
defmodule Bakeware.FileTree do
2+
alias Bakeware.Assembler
3+
4+
@moduledoc """
5+
Builds a FileTree header for recreating decompressed files
6+
7+
Header structure:
8+
9+
`<<bw_ft_magic, bw_ft_version, header_length, file_tree_items>>`
10+
11+
where `file_tree_items` is a repeating structure of:
12+
13+
`<<file_type, size, path_len, relative_path::size(path_len)-unit(8)>>`
14+
"""
15+
16+
# ?F + ?T
17+
@bw_ft_magic 154
18+
@bw_ft_version 1
19+
20+
def build(%Assembler{} = assembler) do
21+
find_files(assembler.rel_path, assembler.rel_path)
22+
|> finalize_header()
23+
24+
# TODO: Do something with this
25+
26+
assembler
27+
end
28+
29+
def find_files(path, absolute, acc \\ <<>>) do
30+
for fp <- File.ls!(path), file_or_dir = Path.join(path, fp), into: acc do
31+
if File.dir?(file_or_dir) do
32+
acc = acc <> build_stat(file_or_dir, absolute)
33+
find_files(file_or_dir, absolute, acc)
34+
else
35+
build_stat(file_or_dir, absolute)
36+
end
37+
end
38+
end
39+
40+
def finalize_header(header) do
41+
len = byte_size(header)
42+
<<@bw_ft_magic, @bw_ft_version, len, header::binary>>
43+
end
44+
45+
defp build_stat(path, absolute) do
46+
relative = Path.relative_to(path, absolute)
47+
stat = File.lstat!(path)
48+
path_len = byte_size(path)
49+
<<type_val(stat.type), stat.size, path_len, relative::binary>>
50+
end
51+
52+
defp type_val(type) do
53+
case type do
54+
:device -> 1
55+
:directory -> 2
56+
:regular -> 3
57+
:symlink -> 4
58+
:other -> 5
59+
# unknown
60+
_ -> 0
61+
end
62+
end
63+
end

0 commit comments

Comments
 (0)