mirror of
https://github.com/c-cube/tiny_httpd.git
synced 2025-12-08 12:15:41 -05:00
feat: add IO.Out_channel.output_char function
This commit is contained in:
parent
29de702c55
commit
41be8908d3
3 changed files with 36 additions and 4 deletions
|
|
@ -56,6 +56,7 @@ end
|
||||||
(** Output channel (byte sink) *)
|
(** Output channel (byte sink) *)
|
||||||
module Out_channel = struct
|
module Out_channel = struct
|
||||||
type t = {
|
type t = {
|
||||||
|
output_char: char -> unit; (** Output a single char *)
|
||||||
output: bytes -> int -> int -> unit; (** Output slice *)
|
output: bytes -> int -> int -> unit; (** Output slice *)
|
||||||
flush: unit -> unit; (** Flush underlying buffer *)
|
flush: unit -> unit; (** Flush underlying buffer *)
|
||||||
close: unit -> unit; (** Close the output. Must be idempotent. *)
|
close: unit -> unit; (** Close the output. Must be idempotent. *)
|
||||||
|
|
@ -69,6 +70,7 @@ module Out_channel = struct
|
||||||
instead of [close_out] to close [oc] *)
|
instead of [close_out] to close [oc] *)
|
||||||
let of_out_channel ?(close_noerr = false) (oc : out_channel) : t =
|
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);
|
output = (fun buf i len -> output oc buf i len);
|
||||||
flush = (fun () -> flush oc);
|
flush = (fun () -> flush oc);
|
||||||
close =
|
close =
|
||||||
|
|
@ -82,7 +84,15 @@ module Out_channel = struct
|
||||||
(** [of_buffer buf] is an output channel that writes directly into [buf].
|
(** [of_buffer buf] is an output channel that writes directly into [buf].
|
||||||
[flush] and [close] have no effect. *)
|
[flush] and [close] have no effect. *)
|
||||||
let of_buffer (buf : Buffer.t) : t =
|
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 *)
|
(** Output the buffer slice into this channel *)
|
||||||
let[@inline] output (self : t) buf i len : unit = self.output buf i len
|
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"
|
output_string self "\r\n"
|
||||||
)
|
)
|
||||||
in
|
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
|
end
|
||||||
|
|
||||||
(** A writer abstraction. *)
|
(** A writer abstraction. *)
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,13 @@ let encode_deflate_writer_ ~buf_size (w : W.t) : W.t =
|
||||||
|
|
||||||
let write (oc : Out.t) : unit =
|
let write (oc : Out.t) : unit =
|
||||||
let output buf i len = write_zlib ~flush:Zlib.Z_NO_FLUSH oc buf i len in
|
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 () =
|
let flush () =
|
||||||
flush_zlib oc ~flush:Zlib.Z_FINISH;
|
flush_zlib oc ~flush:Zlib.Z_FINISH;
|
||||||
assert (!o_len = 0);
|
assert (!o_len = 0);
|
||||||
|
|
@ -100,7 +107,7 @@ let encode_deflate_writer_ ~buf_size (w : W.t) : W.t =
|
||||||
oc.close ()
|
oc.close ()
|
||||||
in
|
in
|
||||||
(* new output channel that compresses on the fly *)
|
(* 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';
|
w.write oc';
|
||||||
oc'.close ()
|
oc'.close ()
|
||||||
in
|
in
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,16 @@ let oc_of_flow ~buf_pool:oc_pool (flow : Eio.Net.stream_socket) :
|
||||||
if !offset = Bytes.length wbuf then flush ()
|
if !offset = Bytes.length wbuf then flush ()
|
||||||
done
|
done
|
||||||
in
|
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
|
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
|
let io_backend ?(addr = "127.0.0.1") ?(port = 8080) ?max_connections
|
||||||
~(stdenv : Eio_unix.Stdenv.base) ~(sw : Eio.Switch.t) () :
|
~(stdenv : Eio_unix.Stdenv.base) ~(sw : Eio.Switch.t) () :
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue