Skip to content

Commit

Permalink
Add tar-eio.gz
Browse files Browse the repository at this point in the history
  • Loading branch information
samoht committed Nov 4, 2023
1 parent 04d1215 commit 24ba3be
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
7 changes: 7 additions & 0 deletions eio/dune
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
(library
(name tar_eio)
(public_name tar-eio)
(modules tar_eio)
(libraries tar eio))

(library
(name tar_eio_gz)
(public_name tar-eio.gz)
(modules tar_eio_gz)
(libraries tar.gz tar_eio))
33 changes: 33 additions & 0 deletions eio/tar_eio_gz.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
open Eio

module Monad = struct
type 'a t = 'a
let (>>=) a f = f a
let return = Fun.id
end

module Reader = struct
type in_channel = Flow.source_ty Resource.t
type 'a t = 'a
let read = Flow.single_read
let really_read f b = Flow.read_exact f b
let skip f (n: int) =
let buffer_size = 32768 in
let buffer = Cstruct.create buffer_size in
let rec loop (n: int) =
if n <= 0 then ()
else
let amount = min n buffer_size in
let block = Cstruct.sub buffer 0 amount in
really_read f block;
loop (n - amount) in
loop n
end

module Writer = struct
type out_channel = Flow.sink_ty Resource.t
type 'a t = 'a
let really_write f b = Flow.write f [ b ]
end

include Tar_gz.Make(Monad)(Writer)(Reader)
51 changes: 51 additions & 0 deletions eio/tar_eio_gz.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
open Eio

(** Read tar.gz files with eio *)

type in_channel

val of_in_channel : internal:Cstruct.t -> Flow.source_ty Resource.t -> in_channel

(** Returns the next header block or fails with {!Tar.Header.End_of_stream}
if two consecutive zero-filled blocks are discovered. Assumes stream is
positioned at the possible start of a header block.
@raise Stdlib.End_of_file if the stream unexpectedly fails. *)
val get_next_header : ?level:Tar.Header.compatibility -> global:Tar.Header.Extended.t option
-> in_channel -> (Tar.Header.t * Tar.Header.Extended.t option)

val really_read : in_channel -> Cstruct.t -> unit
(** [really_read fd buf] fills [buf] with data from [fd] or raises
{!Stdlib.End_of_file}. *)

val skip : in_channel -> int -> unit

type out_channel

val of_out_channel : ?bits:int -> ?q:int -> level:int ->
mtime:int32 -> Gz.os -> Flow.sink_ty Resource.t -> out_channel

val write_block : ?level:Tar.Header.compatibility -> ?global:Tar.Header.Extended.t ->
Tar.Header.t -> out_channel -> (unit -> string option) -> unit
(** [write_block hdr oc stream] writes [hdr], then {i deflate} the given
[stream], then zero-pads so the stream is positionned for the next
block.
A simple usage to write a file:
{[
let stream_of_fd fd =
let buf = Bytes.create 0x1000 in
fun () -> match Unix.read fd buf 0 (Bytes.length buf) with
| 0 -> None
| len -> Some (Bytes.sub_string buf 0 len)
| exception End_of_file -> None
let add_file oc filename =
let fd = Unix.openfile filename Unix.[ O_RDONLY ] 0o644 in
let hdr = Tar.Header.make ... in
write_block hdr oc (stream_of_fd fd) ;
Unix.close fd
]} *)

val write_end : out_channel -> unit
(** [write_end oc] writes a stream terminator to [oc]. *)

0 comments on commit 24ba3be

Please sign in to comment.