1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module In = Bytream.In
exception Not_supported_format
let input_magic in_stream =
match In.input_string in_stream 6 with
| "070701" -> ()
| _ -> raise Not_supported_format
let input_filename ~max_len in_stream =
let contents = In.input_while ~max_len (( <> ) '\x00') in_stream in
In.consume_bytes in_stream 1 ;
contents
let input_padding in_stream =
In.consume_bytes in_stream ((4 - (In.position in_stream mod 4)) mod 4)
let input_field in_stream = In.input_string in_stream 8
let input_int_field in_stream =
input_field in_stream |> ( ^ ) "0x" |> int_of_string
let in_stream =
input_magic in_stream;
let inode_number = input_int_field in_stream in
let permission_bits = input_int_field in_stream in
let user_id = input_int_field in_stream in
let group_id = input_int_field in_stream in
let nlink = input_int_field in_stream in
let modification_time = input_int_field in_stream in
let file_size = input_int_field in_stream in
let major_device_number = input_int_field in_stream in
let minor_device_number = input_int_field in_stream in
let major_raw_device_number = input_int_field in_stream in
let minor_raw_device_number = input_int_field in_stream in
let name_size = input_int_field in_stream in
let checksum = input_int_field in_stream in
Header.
{
inode_number;
permission_bits;
user_id;
group_id;
nlink;
modification_time;
file_size;
major_device_number;
minor_device_number;
major_raw_device_number;
minor_raw_device_number;
name_size;
checksum;
}
let input_entry_with ~input_payload in_stream =
let = input_header in_stream in
let filename = input_filename ~max_len:header.name_size in_stream in
input_padding in_stream;
let contents = input_payload in_stream header.file_size in
input_padding in_stream;
File_entry.{ metadata = header; filename; contents }
let input_entry_without_payload in_stream =
let input_payload in_stream size =
In.consume_bytes in_stream size;
None
in
input_entry_with ~input_payload in_stream
let input_payload_string in_stream size =
Option.some @@ `String (In.input_string in_stream size)
let input_entry in_stream =
input_entry_with ~input_payload:input_payload_string in_stream
let input_entries_with ~input_payload in_stream n =
In.take n (input_entry_with ~input_payload) in_stream
and input_entries_seq_with ~input_payload in_stream n =
Seq.init n @@ fun _ -> input_entry_with ~input_payload in_stream
let input_entries_without_payloads in_stream n =
let input_payload in_stream size =
In.consume_bytes in_stream size;
None
in
input_entries_with ~input_payload in_stream n
let input_entries in_stream n =
input_entries_with ~input_payload:input_payload_string in_stream n
let input_entries_seq in_stream n =
input_entries_seq_with ~input_payload:input_payload_string in_stream n