ocaml-core / base / core / lib / unpack_buffer.mli

The branch 'bash' does not exist.
(* An [Unpack_buffer.t] is a buffer to which one can [feed] strings, and then [unpack] from
   the buffer to produce a queue of values. *)
open Std_internal

module Unpack_one : sig
  (** If [unpack_one : ('value, 'partial_unpack) unpack_one], then [unpack_one buf ?pos
      ?len ?partial_unpack] must unpack at most one value of type ['value] from [buf]
      starting at [pos], and not using more than [len] characters.  [unpack_one] must
      returns one the following:

      `Ok (value, n) -- unpacking succeeded and consumed [n] bytes
      `Not_enough_data (p, n) -- unpacking encountered a valid proper prefix of a packed
      value, and consumed [n] bytes (0 <= n <= len).  [p] is a "partial unpack" that can
      be supplied to a future call to [unpack_one] to continue unpacking
      `Invalid_data -- unpacking encountered an invalidly packed value

      A naive [unpack_one] that only succeeds on a fully packed value could lead to
      quadratic behavior if a packed value's bytes are input using a linear number of
      calls to [feed]. *)

  type ('value, 'partial_unpack) t =
    ?partial_unpack:'partial_unpack
    -> ?pos:int
    -> ?len:int
    -> Bigstring.t
    -> [ `Ok of 'value * int
       | `Not_enough_data of 'partial_unpack * int
       | `Invalid_data of Error.t
       ]

  (** [create_bin_prot reader] returns an unpacker that reads the "size-prefixed" bin-prot
      encoding, in which a value is encoded by first writing the length of the bin-prot
      data as a 64-bit int, and then writing the data itself.  This encoding makes it
      trivial to know if enough data is available in the buffer, so there is no need to
      represent partially unpacked values, and hence ['partial_unpack = unit]. *)
  val create_bin_prot : 'a Bin_prot.Type_class.reader -> ('a, unit) t
end

(* Note that [t] doesn't expose its type ['partial_unpack].  It is only here to allow the
   chosen implementation strategy in the .ml. *)
type ('value, 'partial_unpack) t with sexp_of

val invariant : (_, _) t -> unit

val create :
  ?partial_unpack:'partial_unpack
  -> ('value, 'partial_unpack) Unpack_one.t
  -> ('value, 'partial_unpack) t

(** [create_bin_prot reader] returns an unpack buffer that unpacks the "size-prefixed"
    bin-prot encoding, in which a value is encoded by first writing the length of the
    bin-prot data as a 64-bit int, and then writing the bin-prot data itself.  This
    encoding makes it trivial to know if enough data is available in the buffer, so there
    is no need to represent partially unpacked values, and hence ['partial_unpack =
    unit]. *)
val create_bin_prot : 'a Bin_prot.Type_class.reader -> ('a, unit) t

(** [is_empty t] returns [true] if [t] has no unconsumed bytes, and [false] if it does.
    [is_empty] returns an error if [t] has encountered an unpacking error. *)
val is_empty : (_, _) t -> bool Or_error.t

(** [feed t buf ?pos ?len] adds the specified substring of [buf] to [t]'s buffer.  It
    returns an error if [t] has encountered an unpacking error. *)
val feed : ?pos:int -> ?len:int -> (_, _) t -> Bigstring.t -> unit Or_error.t

(** [unpack t] unpacks all the values that it can from [t].  The resulting queue will be
    empty if nothing could be unpacked.  If there is an unpacking error, [unpack] returns
    an error, and subsequent [feed] and [unpack] operations on [t] will return that same
    error.  I.e. no more data can be fed to or unpacked from [t]. *)
val unpack : ('value, _) t -> 'value Queue.t Or_error.t

(** [debug] controls whether invariants are checked at each call.  Setting this to [true]
    can make things very slow. *)
val debug : bool ref
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.