Module Bytes.Reader

Byte stream readers.

Byte streams are sequences of byte slices. 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.

Readers

type t

The type for byte stream readers.

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:

  • The slice returned by a call to read must remain valid for reading until the next call to read.
  • The reader guarantees to dereference 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 position. If the value is negative it is substracted from the latter, e.g. subtracting the length of the last slice would report an error at the first byte of the slice.

Reading

val read : t -> Slice.t

read r reads the next slice from r. The slice is valid for reading until the next call to read on r. Once Slice.eod is returned, Slice.eod is always returned.

val push_back : t -> Slice.t -> unit

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 trapped by 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.

val sniff : int -> t -> string

sniff n r sniffs at most n bytes from r. These bytes will still be returned by read calls. Less than n bytes are returned if the end of stream is reached before or if n <= 0.

Warning. This uses push_back and should not be used as a general lookahead mecanism by stream readers.

val skip : int -> t -> unit

skip n r is like skips at most n bytes from r. See also discard.

val discard : t -> unit

discard r reads and discards slices until Slice.eod is returned. See also skip.

Filters

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 filtering reader:

  • If pos is unspecfied, it should default to r's position only if the reads on the filtering reader are always in the same position space as r (e.g. sub or limit). Otherwise it should be 0 (e.g. on decompression filters) or anything else that makes sense for the filter.
  • If slice_length is unspecified, it should default to r's value or what makes more sense for the filter's reads.
  • If the filter reader does not read all of r's bytes, it must, after having returned Slice.eod, leave r at the position of the leftover data so that it can be used again to perform non-filtered reads. push_back can be used to achieve that.
  • If your filter is in a module 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

sub n r is a reader reading at most n bytes from r before returning Slice.eod. sub satisfies all the filter conventions and is not affected by push backs. See also limit.

val limit : ?action:(t -> int -> unit) -> 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.

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)

Appending

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.

Taps

val tap : (Slice.t -> unit) -> t -> t

tap f r invokes f with the slice read by r before returning them with read. Note that push_backs are not trapped, so this can be used reliably for checksumming.

Converting

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. Can 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 eq. pos defaults to 0 and slice_length defaults to None.

val to_string : t -> string

to_string r reads r until Slice.eod into a string s.

val to_slice_seq : t -> Slice.t Stdlib.Seq.t

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

output_to_out_channel oc r, sets oc in binary mode, reads r and outputs the slices on oc until Slice.eod. If flush_slices is true, oc is flushed after each slice except Slice.eod.

Formatting

val pp : Stdlib.Format.formatter -> t -> unit

pp formats readers for inspection.