forked from dbuenzli/zipc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
examples.ml
54 lines (50 loc) · 2.1 KB
/
examples.ml
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
(*---------------------------------------------------------------------------
Copyright (c) 2023 The zipc programmers. All rights reserved.
SPDX-License-Identifier: CC0-1.0
---------------------------------------------------------------------------*)
let read_file file =
let read file ic = try Ok (In_channel.input_all ic) with
| Sys_error e -> Error (Printf.sprintf "%s: %s" file e)
in
let binary_stdin () = In_channel.set_binary_mode In_channel.stdin true in
try match file with
| "-" -> binary_stdin (); read file In_channel.stdin
| file -> In_channel.with_open_bin file (read file)
with Sys_error e -> Error e
let write_file file s =
let write file s oc = try Ok (Out_channel.output_string oc s) with
| Sys_error e -> Error (Printf.sprintf "%s: %s" file e)
in
let binary_stdout () = Out_channel.(set_binary_mode stdout true) in
try match file with
| "-" -> binary_stdout (); write file s Out_channel.stdout
| file -> Out_channel.with_open_bin file (write file s)
with Sys_error e -> Error e
let unzip_path ~path ~archive =
let ( let* ) = Result.bind in
let file_error file msg = Printf.sprintf "%s: %s" file msg in
let* s = read_file archive in
Result.map_error (file_error archive) @@
let* z = Zipc.of_binary_string s in
Result.map_error (file_error path) @@
match Option.map Zipc.Member.kind (Zipc.find path z) with
| None -> Error "No such path"
| Some Zipc.Member.Dir -> Error "Is a directory"
| Some Zipc.Member.File file ->
let* data = Zipc.File.to_binary_string file in
Ok (Zipc.Fpath.sanitize path, data)
let zip_file ?(compress = true) ~file ~archive () =
let ( let* ) = Result.bind in
let file_error file msg = Printf.sprintf "%s: %s" file msg in
let* s = read_file file in
let* m =
Result.map_error (file_error file) @@
let path = Filename.basename file in
let* file = match compress with
| true -> Zipc.File.deflate_of_binary_string s
| false -> Zipc.File.stored_of_binary_string s
in
Zipc.Member.make ~path (Zipc.Member.File file)
in
let* s = Zipc.to_binary_string (Zipc.add m Zipc.empty) in
write_file archive s