feat: add IO.Out_channel.output_char function

This commit is contained in:
Simon Cruanes 2023-07-18 14:14:05 -04:00
parent 29de702c55
commit 41be8908d3
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
3 changed files with 36 additions and 4 deletions

View file

@ -56,6 +56,7 @@ end
(** Output channel (byte sink) *)
module Out_channel = struct
type t = {
output_char: char -> unit; (** Output a single char *)
output: bytes -> int -> int -> unit; (** Output slice *)
flush: unit -> unit; (** Flush underlying buffer *)
close: unit -> unit; (** Close the output. Must be idempotent. *)
@ -69,6 +70,7 @@ module Out_channel = struct
instead of [close_out] to close [oc] *)
let of_out_channel ?(close_noerr = false) (oc : out_channel) : t =
{
output_char = (fun c -> output_char oc c);
output = (fun buf i len -> output oc buf i len);
flush = (fun () -> flush oc);
close =
@ -82,7 +84,15 @@ module Out_channel = struct
(** [of_buffer buf] is an output channel that writes directly into [buf].
[flush] and [close] have no effect. *)
let of_buffer (buf : Buffer.t) : t =
{ output = Buffer.add_subbytes buf; flush = ignore; close = ignore }
{
output_char = Buffer.add_char buf;
output = Buffer.add_subbytes buf;
flush = ignore;
close = ignore;
}
(** Output the buffer slice into this channel *)
let[@inline] output_char (self : t) c : unit = self.output_char c
(** Output the buffer slice into this channel *)
let[@inline] output (self : t) buf i len : unit = self.output buf i len
@ -121,7 +131,14 @@ module Out_channel = struct
output_string self "\r\n"
)
in
{ flush; close; output }
(* terrible terrible. *)
let bchar = Bytes.create 1 in
let output_char c =
Bytes.set bchar 0 c;
output bchar 0 1
in
{ output_char; flush; close; output }
end
(** A writer abstraction. *)

View file

@ -89,6 +89,13 @@ let encode_deflate_writer_ ~buf_size (w : W.t) : W.t =
let write (oc : Out.t) : unit =
let output buf i len = write_zlib ~flush:Zlib.Z_NO_FLUSH oc buf i len in
let bchar = Bytes.create 1 in
let output_char c =
Bytes.set bchar 0 c;
output bchar 0 1
in
let flush () =
flush_zlib oc ~flush:Zlib.Z_FINISH;
assert (!o_len = 0);
@ -100,7 +107,7 @@ let encode_deflate_writer_ ~buf_size (w : W.t) : W.t =
oc.close ()
in
(* new output channel that compresses on the fly *)
let oc' = { Out.flush; close; output } in
let oc' = { Out.flush; close; output; output_char } in
w.write oc';
oc'.close ()
in

View file

@ -93,8 +93,16 @@ let oc_of_flow ~buf_pool:oc_pool (flow : Eio.Net.stream_socket) :
if !offset = Bytes.length wbuf then flush ()
done
in
let output_char c =
if !offset = Bytes.length wbuf then flush ();
Bytes.set wbuf !offset c;
incr offset;
if !offset = Bytes.length wbuf then flush ()
in
let close () = flow#shutdown `Send in
{ IO.Out_channel.close; flush; output }
{ IO.Out_channel.close; flush; output; output_char }
let io_backend ?(addr = "127.0.0.1") ?(port = 8080) ?max_connections
~(stdenv : Eio_unix.Stdenv.base) ~(sw : Eio.Switch.t) () :