package git

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

The non-blocking decoder of the PACK stream.

module Hash : sig ... end
module Inflate : sig ... end
module Hunk : H with module Hash := Hash
type error =
  1. | Invalid_byte of int
    (*

    Appears when the header of the PACK file is wrong.

    *)
  2. | Reserved_kind of int
    (*

    Appears when the kind of the current PACK object is 0.

    *)
  3. | Invalid_kind of int
    (*

    Appears when the kind of the current PACK object is undefined. TODO: this case does not appear, lol ...

    *)
  4. | Inflate_error of Inflate.error
    (*

    Appears when the Inflate module returns an error when it tries to inflate a PACK object.

    *)
  5. | Hunk_error of Hunk.error
    (*

    Appears when the H module returns an error.

    *)
  6. | Hunk_input of int * int
    (*

    The Hunk object is length-defined. So, when we try to decode this specific PACK object, if the decoder H.t expects some new bytes and we already get all input, this error appears (with respectively how many byte(s) we expected and how many byte(s) the decoder H.t computed).

    *)
  7. | Invalid_length of int * int
    (*

    Appears when the length of the inflated object does not correspond by what was it noticed by the PACK file.

    *)

The type error.

val pp_error : error Fmt.t

Pretty-printer for an error.

type t

The type of the decoder.

val pp : t Fmt.t

Pretty-printer for t.

type kind =
  1. | Commit
  2. | Tree
  3. | Blob
  4. | Tag
  5. | Hunk of Hunk.hunks
    (*

    The kind of the PACK object. It can be:

    • A Commit
    • A Tree
    • A Blob
    • A Tag
    • A Hunk: this is not a git object but a specific PCK object. The H.hunks refers to another PACK object by H.reference and it's just a result of a diff between the reference and the current object.
    *)
val default : Cstruct.t -> Inflate.window -> t

default tmp window makes a new decoder of a PACK file.

tmp is a Cstruct.t used as an internal output of the inflated stream. We let the user to allocate the optimized length for this temporary buffer and we take the ownership (so, you don't use it to another compute).

window is the Inflate.window needed to inflate. We keep this window as long as we use have objects in the PACK stream and reset it for each object (and avoid any needed allocation). Then, we take the ownership so you are not able to use it for another process.

This state does not allocate any large caml value.

val many : t -> int32

many t returns how many objects will/did compute for the current stream.

val from_window : Window.t -> int -> Cstruct.t -> Inflate.window -> t

from_window pack_window off_in_window tmp window makes a new decoder of a PACK file specialized from a Window.t. This decoder compute only one object in a precise offset (noticed by pack_window and the relative offset off_in_window). Then tmp and window have the same purpose than default. For this state, eval has a different behaviour. Indeed, after the specified object de-serialized, eval returns directly `End even if it's not the last object in the PACK stream. Then, the hash produced is empty.

val process_length : Window.t -> int -> Cstruct.t -> Inflate.window -> t

process_length pack_window off_in_window tmp window makes a new specific decoder only to get the real length of the PACK object specified by pack_window and the relative offset off_in_window. This decoder is only able to be used with eval_length (and not eval). For all git object, we can catch the real inflated length of the expected object. For the Hunk _ object, we can get the real inflated length of the PACK object and call H.partial_hunks with the internal Hunk decoder state. This compute appear only when eval_length returns `Length.

This decoder is focused to only get the length of the PACK object. So we inflate for example only what it needed to get this information. So, obviously, it is more faster than eval and compute all of the object to get the information then.

val process_metadata : Window.t -> int -> Cstruct.t -> Inflate.window -> t

process_metadata same purpose than process_length but stop the decoder to a step to get some meta-data about the expected PACK object.

val refill : int -> int -> t -> t

refill off len t provides a new t with len bytes to read, starting at off. This byte range is read by calls to eval with t until `Await is returned.

val flush : int -> int -> t -> t

flush off len t provides t with len bytes to write, starting at off. This byte range is written by calls to eval with t until `Flush is returned. Use output to know how many byte t wrote.

val next_object : t -> t

next_object t provides a new t which continue the de-serialization of the PACK stream. Indeed, when the client catches a new `Object, the decoder sticks on the this situation. So to move to the next step, the client have to call next_object to continue the process.

val continue : t -> t

continue t defers H.continue to the internal state H.t. The client is able to use it only when eval/eval_length/eval_metadata returns `Hunk.

Meta-data information.

val kind : t -> kind

kind t returns the kind of the current object. The client is able to use this function only when eval returns `Object or `Hunk. Otherwise, we raise an Invalid_argument. This function is available when the client process the meta-data of the expected object and can call it when eval_metadata returns `Metadata.

val length : t -> int

length t returns the real inflated length of the current object in the PACK stream. The client is able to use this function only when eval returns `Object or `Hunk. Otherwise, we raise an Invalid_argument. This function is available when the client process the length of the expected object and can call it when eval_length returns `Length.

val offset : t -> int64

offset t returns the absolute offset of the current object in the PACK file. The client is able to use this function only when eval returns `Object or `Hunk. Otherwise, we raise an Invalid_argument. This function is available when the client process the meta-data of the expected object and can call it when eval_metadata returns `Metadata.

val consumed : t -> int

consumed t returns how many byte(s) the decoder consumed to de-serialize the current/expected object in the PACK stream. The client is able to use it only when eval returns `Object. Otherwise, we raise an Invalid_argument.

val crc : t -> Checkseum.Crc32.t

crc t returns the CRC-32 checksum computed when the decoder consumed all byte(s) needed to de-serialize the current/expected object. The client is able to use this function only when eval returns `Object. Otherwise, we raise an Invalid_argument.

val output : t -> Cstruct.t * int

output t returns the output produced by the decoder t when it inflates a git object. The Cstruct.t is physically the same than tmp noticed when the client makes the decoder t. Then, output returns how many byte(s) the decoder wrote inside tmp. The client is able to use this function only when the kind of the current pack object processed is different to Hunk. Otherwise, we raise an error.

val eval : Cstruct.t -> t -> [ `Object of t | `Hunk of t * Hunk.hunk | `Await of t | `Flush of t | `End of t * Hash.t | `Error of t * error ]

eval src t is:

  • `Await t iff t more input storage. The client muse use refill to provide a new buffer and then call eval with `Await until other value returned.
  • `Object t iff t finishes to compute one object. The client is able to use the meta-data functions (like kind or crc) and should use next_object to move the decoder to the next step. Otherwise, the decoder t sticks in this situation.
  • Hunk (t, hunk) defers the value returned by the internal H.t decoder. The client should use continue to move the decoder to the next step. In this situation, we ensure than the future kind of the current/expected object is Hunk_.
  • `Flush t iff t needs more output storage. The client must use flush to provide a new buffer and then call eval with `Flush until `Object is returned. In this situation, we ensure than the future kind of the current/expected object is different than the Hunk_.
  • `End (t, hash) when the decoder is done. t sticks to this situation. The client can remove it. We return the hash produced by the PACK stream.
  • `Error (t, exn) iff the decoder meet an error exn. The decoder can't continue and sticks in this situation.
val eval_length : Cstruct.t -> t -> [ `Length of t | `Await of t | `Flush of t | `End of t * Hash.t | `Error of t * error ]

eval_length src t has the same purpose than eval plus:

  • `Length t iff t can return the real inflated length of the current/expected object. The client should use length to get this information.
val eval_metadata : Cstruct.t -> t -> [ `Metadata of t | `Await of t | `Flush of t | `End of t * Hash.t | `Error of t * error ]

eval_length src t has the same purpose than eval plus:

  • `Metadata t iff t can be used with meta-data functions (like kind or length).
OCaml

Innovation. Community. Security.