Bytes.Reader
Byte stream readers.
Byte streams are sequences of non-empty byte slices ended by a single Slice.eod
slice. A byte stream reader provides read access to these slices in order, on demand, but only slice by slice: the slice you get is valid for reading only until the next slice is read from the reader.
See the quick start and read about stream readers in the tutorial.
val make :
?pos:Stream.pos ->
?slice_length:Slice.length ->
(unit -> Slice.t) ->
t
make read
is a reader from the function read
which enumerates the slices of a byte stream. The contract between the reader and read
is as follows:
read
must remain valid for reading until the next call to read
.read
and never call it again as soon as Slice.eod
is returned by read
.pos
defaults to 0
and slice_length
to Slice.default_length
.
val empty : ?pos:Stream.pos -> ?slice_length:Slice.length -> unit -> t
empty ()
is make (Fun.const Slice.eod)
, an empty byte stream.
val pos : t -> Stream.pos
pos r
is the stream position of the next byte to read. Alternatively it can be seen as the number of bytes returned by calls to read
(not including push back replays), see read_length
.
Warning. Due to push backs negative values can be returned.
val read_length : t -> int
read_length r
is an alternative name for pos
.
Warning. Due to push backs negative values can be returned.
val slice_length : t -> Slice.length
slice_length r
is a hint on the maximal length of slices that r
returns.
val error : 'e Stream.format_error -> t -> ?pos:Stream.pos -> 'e -> 'a
error fmt r e
raises a Stream.Error
e
of format fmt
for r
. pos
is the position reported for the error, it defaults to r
'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.
read r
reads the next slice from r
. The slice is only valid for reading until the next call to read
on r
. Once Slice.eod
is returned, Slice.eod
is always returned.
push_back r s
pushes the slice s
back on r
. If s
is Slice.eod
this has no effect. Otherwise the stream position is rewinded by Slice.length s
and the next read
on r
returns s
.
Note. If r
is the result of a call to tap
the tap function won't see the push backs. Good for your checksums.
Warning. This should not be used as a general lookahead mecanism by stream readers. Codecs should devise their own buffering structures. But it is useful for stream content sniffing and breaking streams into substreams at precise positions.
Warning. Currently it is possible to push back beyond the beginning of a stream. It is unclear whether this feature will be kept in the future. Please get in touch if you use that feature.
val sniff : int -> t -> string
val discard : t -> unit
Read more about filters in the tutorial.
type filter = ?pos:Stream.pos -> ?slice_length:Slice.length -> t -> t
The type for byte stream reader filters.
Given a reader r
, a filter f
returns a filtering reader f
r
, that reads the stream of r
and transforms it in some way. The following conventions should be followed for the resulting filtering reader:
pos
is unspecified, it should default to r
's position only if the reads on the filtering reader are always in the same position space as r
(see e.g. sub
or limit
). Otherwise it should be 0
(e.g. on decompression filters) or anything else that makes sense for the filter.slice_length
is unspecified, it should default to r
's slice_length
or what makes more sense for the filter's reads.r
's bytes, it must, after having returned Slice.eod
, leave r
at the position of the leftover data so that r
can be used again to perform non-filtered reads. This can be done by using push_back
on r
with the leftover data.M
, then its name should be M.{decode,encode}_reads
or another meaningful verb like M.{decompress,compress}_reads
, M.{encrypt,decrypt}_reads
, etc.val sub : int -> filter
limit n r
is like sub
except it invokes action
once with the filter reader before returning Slice.eod
. The default action
raises Stream.Limit
error. See an example.
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:
to_string (List.fold_left (fun r f -> f r) (of_string s) fs)
See an example.
val reslice : filter
reslice ?pos ?slice_length r
has the data of r
but ensures that all slices are of length slice_length
(defaults to slice_length
r
) except perhaps the last one.
val append : ?pos:Stream.pos -> ?slice_length:Slice.length -> t -> t -> t
append r0 r1
reads from r0
and then from r1
. pos
defaults to 0
and slice_length
defaults to the maximal length of r0
and r1
.
tap f r
invokes f
with the slice read by r
before returning them with read
. Note that push_back
s are not tapped, so this can be used reliably for checksumming the reads of r
. See also Slice.tracer
and an example.
equal r0 r1
asserts that the bytes of r0
are equal to those of r1
in bounded space. This may not fully consume the readers.
equal r0 r1
sorts the bytes of r0
and r1
in lexicographic order in bounded space. This may not fully consume the readers.
val of_bytes : ?pos:Stream.pos -> ?slice_length:Slice.length -> bytes -> t
of_bytes s
reads the bytes of b
with slices of maximal length slice_length
which defaults to Bytes.length s
. pos
defaults to 0
.
val of_string : ?pos:Stream.pos -> ?slice_length:Slice.length -> string -> t
of_string b
is like of_bytes
but reads the bytes of s
.
val of_in_channel :
?pos:Stream.pos ->
?slice_length:Slice.length ->
Stdlib.In_channel.t ->
t
of_in_channel ic
, sets ic
in binary mode and reads the bytes of ic
with slices of maximal length slice_length
which defaults to Slice.io_buffer_size
. pos
default to In_channel.pos
. This function and the resulting reader may raise Sys_error
.
val of_slice : ?pos:Stream.pos -> ?slice_length:Slice.length -> Slice.t -> t
of_slice s
reads r
with slice of maximal length slice_length
which default to Slice.length s
. pos
defaults to 0
.
val of_slice_seq :
?pos:Stream.pos ->
?slice_length:Slice.length ->
Slice.t Stdlib.Seq.t ->
t
of_slice_seq seq
reads the slices produced by seq
. pos
defaults to 0
and slice_length
defaults to None
.
to_slice_seq r
reads r
until Slice.eod
into a sequence. The latter is not enumerated.
Warning. A slice returned by the sequence is only valid for reading until the next slice is requested from the sequence.
val add_to_buffer : Stdlib.Buffer.t -> t -> unit
add_to_buffer b r
reads r
and adds its slices to b
until Slice.eod
.
val output_to_out_channel :
?flush_slices:bool ->
Stdlib.Out_channel.t ->
t ->
unit
val pp : Stdlib.Format.formatter -> t -> unit
pp
formats a readers's properties for inspection. It does not consume any input.