package git
Git format and protocol in pure OCaml
Install
Dune Dependency
Authors
Maintainers
Sources
git-3.13.0.tbz
sha256=f7cc36026cdefc1f9837f10d7d26f457c236cb21547fcad210e71483561b55d3
sha512=728f21c3483bdead9420767cb3e57901be1cff428fceb814be3cad817b2d78511d35f559962469e85d3919c59577884d353cb883ac749e6e2b92fb7d0deec4f4
doc/src/git.loose-git/loose_git.ml.html
Source file loose_git.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
let src = Logs.Src.create "git.loose" ~doc:"logs git's loose event" module Log = (val Logs.src_log src : Logs.LOG) module type STORE = sig type t type uid type error type +'a fiber val pp_error : error Fmt.t val exists : t -> uid -> bool fiber val length : t -> uid -> (int64, error) result fiber val map : t -> uid -> pos:int64 -> int -> Bigstringaf.t fiber val append : t -> uid -> Bigstringaf.t -> (unit, error) result fiber val appendv : t -> uid -> Bigstringaf.t list -> (unit, error) result fiber val list : t -> uid list fiber val reset : t -> (unit, error) result fiber end module type IO = sig type +'a t val bind : 'a t -> ('a -> 'b t) -> 'b t val return : 'a -> 'a t end module Make (Scheduler : Carton.SCHEDULER) (IO : IO with type +'a t = 'a Scheduler.s) (Store : STORE with type +'a fiber = 'a Scheduler.s) (Uid : Loose.UID with type t = Store.uid) = struct let ( >>= ) = IO.bind let return = IO.return let io = let open Scheduler in { Carton.bind = (fun x f -> inj (prj x >>= fun x -> prj (f x))); Carton.return = (fun x -> inj (return x)); } (* XXX(dinosaure): at this layer, [loose] can ask something bigger than the length of [uid]. So we fix it with this process and return as much as we can. *) let store_map root uid ~pos len = if pos < 0L || len < 0 then invalid_arg "store_map: invalid bounds"; Store.length root uid >>= function | Error _ -> return Bigstringaf.empty | Ok max -> let len = min (Int64.add pos (Int64.of_int len)) (Int64.sub max pos) in let len = Int64.to_int len in Store.map root uid ~pos len let store_mem root uid = Store.exists root uid let store_append root uid payload = Store.append root uid payload let store_appendv root uid payloads = Store.appendv root uid payloads let store_list root = Store.list root let store = { Loose.map = (fun t uid ~pos len -> Scheduler.inj (store_map t uid ~pos len)); Loose.mem = (fun t uid -> Scheduler.inj (store_mem t uid)); Loose.append = (fun t uid v -> Scheduler.inj (store_append t uid v)); Loose.appendv = (fun t uid vs -> Scheduler.inj (store_appendv t uid vs)); Loose.list = (fun t -> Scheduler.inj (store_list t)); } let space = Cstruct.of_string " " let zero = Cstruct.of_string "\000" (* TODO(dinosaure): integrate it into [cstruct]. *) let cut ~sep:({ Cstruct.len = sep_len; _ } as sep) ({ Cstruct.len; _ } as t) = if sep_len = 0 then invalid_arg "cut: empty separator"; let max_sep_zidx = sep_len - 1 in let max_t_zidx = len - sep_len in let rec check_sep i k = if k > max_sep_zidx then Some (Cstruct.sub t 0 i, Cstruct.sub t (i + sep_len) (len - sep_len - i)) else if Cstruct.get_char t (i + k) = Cstruct.get_char sep k then check_sep i (succ k) else scan (succ i) and scan i = if i > max_t_zidx then None else if Cstruct.get_char t i = Cstruct.get_char sep 0 then check_sep i 1 else scan (succ i) in scan 0 let hdr_get raw = match cut ~sep:space raw with | None -> failwith "Invalid Git header" | Some (kind, rest) -> ( match cut ~sep:zero rest with | Some (length, contents) -> let length = Int64.of_string (Cstruct.to_string length) in let kind = match Cstruct.to_string kind with | "commit" -> `A | "blob" -> `C | "tag" -> `D | "tree" -> `B | v -> Fmt.failwith "Invalid type of Git object: %s" v in contents, kind, length | None -> failwith "Invalid Git header") let hdr_set ~buffer (kind, length) = let kind = match kind with | `Commit -> "commit" | `Tree -> "tree" | `Blob -> "blob" | `Tag -> "tag" in Cstruct.blit_from_string kind 0 buffer 0 (String.length kind); Cstruct.set_char buffer (String.length kind) ' '; let length = Int64.to_string length in Cstruct.blit_from_string length 0 buffer (String.length kind + 1) (String.length length); Cstruct.set_char buffer (String.length kind + 1 + String.length length) '\000'; Cstruct.sub buffer 0 (String.length kind + 1 + String.length length + 1) include Loose.Make (Uid) let list t = Scheduler.prj (store.list t) let exists t uid = Scheduler.prj (exists t store uid) let atomic_add t buffers v = let hdr_set ~buffer v = let kind = match Carton.Dec.kind v with | `A -> `Commit | `B -> `Tree | `C -> `Blob | `D -> `Tag in let length = Int64.of_int (Carton.Dec.len v) in hdr_set ~buffer (kind, length) in Scheduler.prj (atomic_add io t buffers store ~hdr:hdr_set v) let add t buffers (kind, length) stream = let hdr = hdr_set ~buffer:(Cstruct.create 30) (kind, length) in let stream () = Scheduler.inj (stream ()) in Scheduler.prj (add io t buffers store ~hdr stream) let atomic_get t buffer uid = Scheduler.prj (atomic_get io t buffer store ~hdr:hdr_get uid) let size_and_kind t buffers uid = Scheduler.prj (size_and_kind io t buffers store ~hdr:hdr_get uid) let get t buffer uid = Scheduler.prj (get io t buffer store ~hdr:hdr_get uid) end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>