Bytes.Writer
Byte stream writers.
Byte streams are sequences of non-empty byte slices ended by a single Slice.eod
slice. A byte stream writer is given access to these slices in order but only slice by slice in its write function: the slice only remains valid for reading until the write function returns.
See the quick start and read more about stream writers in the tutorial.
val make :
?pos:Stream.pos ->
?slice_length:Slice.length ->
(Slice.t -> unit) ->
t
make write
is a writer from the function write
which iterates over the slices of a byte stream. The contract between the writer and write
is as follows:
write
are valid for reading only until the write
function returns.write
was called with Slice.eod
, write
is dereferenced by the writer and will never be called again.pos
defaults to 0
and slice_length to Slice.default_length
.
val ignore : ?pos:Stream.pos -> ?slice_length:Slice.length -> unit -> t
ignore ()
is make (fun _ -> ())
, a writer that ignores the writes that are pushed on it.
val pos : t -> Stream.pos
pos w
is the stream position of the next byte to write. Alternatively it can be seen as the number of bytes written on w
, see written_length
.
val slice_length : t -> Slice.length
slice_length w
is a hint on the maximal length of slices that w
would like to receive.
val error : 'e Stream.format_error -> t -> ?pos:Stream.pos -> 'e -> 'a
error fmt w e
raises a Stream.Error
e
of format fmt
for w
. pos
is the position reported for the error it defaults to w
's pos
. If the value is negative it is added to the latter, e.g. using the negated length of the last slice would report an error at the first byte of the last slice.
Note. All these functions raise Invalid_argument
if a slice other than Slice.eod
is written after a Slice.eod
was written.
write w s
writes the slice s
on w
. The slice s
must remain valid for reading until the function returns.
The function raises Invalid_argument
is s
is written after a Slice.eod
and s
is not Slice.eod
.
val write_eod : t -> unit
write_eod w
is write w Slice.eod
. Only Slice.eod
can be written on w
aftewards.
val write_bytes : t -> bytes -> unit
write_bytes w b
writes the bytes b
on w
in slice_length
slices, except perhaps the last one. The bytes of b
must not change until the function returns.
val write_string : t -> string -> unit
write_string
is like write_bytes
but writes a string.
write_reader w r
writes the slices of r
on w
. Slice.eod
is only written if eod
is true
. Note that the slices are written as given by r
and may not respect w
's desired slice_length
.
val write_in_channel : eod:bool -> t -> Stdlib.In_channel.t -> unit
write_in_channel w ic
sets ic
to binary mode and writes slices to w
until the end of file is reached at which point Slice.eod
is written iff eod
is true. The maximal length of written slices are w
's slice_length
.
Read more about filters in the tutorial.
type filter =
?pos:Stream.pos ->
?slice_length:Slice.length ->
eod:bool ->
t ->
t
The type for byte stream writer filters.
Given a writer w
, a filter f
returns a filtering writer f
~eod w
, that transforms the writes made on it in some way and then writes them to w
. The following conventions should be followed for the filtering writer:
Slice.eod
, it must stop and, if applicable, report an error if there was leftover data that it couldn't write. It must only write Slice.eod
on w
if eod
is true
. Otherwise it should leave w
as is so that w
can be used again to perform other non-filtered writes.pos
is unspecified it should default to w
's position only if the writes are in the same position space as w
. Otherwise it should be 0
(e.g. on compression filters).slice_length
is unspecified it should default to w
's value or a value that makes more sense for the filter's needs.w
that respects its slice_length
desires.M
, then its name should be M.{decode,encode}_writes
or an other meaningful verb like M.{decompress,compress}_writes
, M.{encrypt,decrypt}_writes
, etc.limit n w ~eod
is a writer that writes at most n
bytes on w
. Any leftover in the slice that exceeds the n
bytes is lost. If the n
bytes are exceeded, Slice.eod
is written if eod
is true
, the action action
is invoked once and the filtering writer accepts only Slice.eod
afterwards. As per filter semantics Slice.eod
is only written on w
if eod
is true. The default action
raises Stream.Limit
error.
val filter_string : filter list -> string -> string
filter_string fs s
is a convenience function that applies the filters fs
, from left to right to the string s
it is equivalent to:
let b = Buffer.create (String.length s) in
let w = List.fold_left (fun w f -> f ~eod:true w) (of_buffer w) fs in
write_string w s; write_eod w; Buffer.contents b
See an example.
tap f w
is a writer that invokes f
with the slice before writing it on w
. See also Slice.tracer
and an example.
val of_out_channel :
?pos:Stream.pos ->
?slice_length:Slice.length ->
?flush_slices:bool ->
Stdlib.Out_channel.t ->
t
of_out_channel oc
sets oc
to binary mode and writes slices to oc
. If flush_slices
is true
(defaults to false
), oc
is flushed after each slice except Slice.eod
. pos
defaults to Out_channel.pos
. The hinted slice_length
defaults to Slice.io_buffer_size
. This function and the resulting writer may raise Sys_error
.
val of_buffer :
?pos:Stream.pos ->
?slice_length:Slice.length ->
Stdlib.Buffer.t ->
t
of_buffer b
writes slices to b
.
slice_length
is not that important but we default it to Slice.io_buffer_size
, so that channel and fd readers that may ajust their own buffers on writers adjust nicely for themselves.
val pp : Stdlib.Format.formatter -> t -> unit
pp
formats a writer's properties for inspection.