ocaml-zim/bin/zim_header_inspect.ml
2025-01-27 14:49:18 +01:00

69 lines
2.5 KiB
OCaml

open Cmdliner
let print_zim_header zim =
Printf.printf "Zim Header:\n";
Printf.printf "\tmagic number: %lu\n" zim.Zim.Header.magic_number;
Printf.printf "\tmajor version: %d\n" zim.Zim.Header.major_version;
Printf.printf "\tminor version: %d\n" zim.Zim.Header.minor_version;
Printf.printf "\tuuid: %s\n" (Uuidm.to_string zim.Zim.Header.uuid);
Printf.printf "\tentry count: %lu\n" zim.Zim.Header.entry_count;
Printf.printf "\tcluster count: %lu\n" zim.Zim.Header.cluster_count;
Printf.printf "\tpath pointer position: %Lu\n" zim.Zim.Header.path_ptr_pos;
Printf.printf "\ttitle pointer position: %Lu\n" zim.Zim.Header.title_ptr_pos;
Printf.printf "\tcluster pointer position: %Lu\n"
zim.Zim.Header.cluster_ptr_pos;
Printf.printf "\tmime list position: %Lu\n" zim.Zim.Header.mime_list_pos;
Printf.printf "\tmain page: %lu\n" zim.Zim.Header.main_page;
Printf.printf "\tlayout page: %lu\n" zim.Zim.Header.layout_page;
Printf.printf "\tchecksum position: %Lu\n" zim.Zim.Header.checksum_pos
let print_int32_in_columns count lst =
List.iteri
(fun i zim ->
if i > 0 && i mod count = 0 then Printf.printf "\n";
Printf.printf "%10lu " zim)
lst;
Printf.printf "\n";
()
let print_zim zim =
print_zim_header zim.Zim.header;
Printf.printf "MIME Type List:\n";
List.iter (fun zim -> Printf.printf "\t%s\n" zim) zim.Zim.mime_type_list;
Printf.printf "Path Pointer List:\n";
print_int32_in_columns 10 zim.path_ptr_list;
Printf.printf "Title Pointer List:\n";
print_int32_in_columns 10 zim.title_ptr_list;
()
let really_input fd buf pos len =
let rec loop pos remaining =
if remaining > 0 then (
let len = Unix.read fd buf pos remaining in
if len = 0 then raise End_of_file;
loop (pos + len) (remaining - len))
in
loop pos len
let read_zims zims =
List.iter
(fun zim ->
let fd = Unix.openfile zim Unix.[ O_RDONLY; O_CLOEXEC ] 0 in
let f_stats = Unix.stat zim in
let size = f_stats.st_size in
let buf = Bytes.create size in
let () = really_input fd buf 0 size in
match Zim.unmarshal (Cstruct.of_bytes buf) with
| Ok zim -> print_zim zim
| Error err -> Printf.printf "%s" err)
zims
let zims = Arg.(non_empty & pos_all file [] & info [] ~docv:"zim files")
let cmd =
let doc = "Inspect the headers of one or more zim files." in
let info = Cmd.info "zim_header_inspect" ~version:"1.0.0" ~doc in
Cmd.v info Term.(const read_zims $ zims)
let main () = exit (Cmd.eval cmd)
let () = main ()