~cypheon/ocaml-apfs

ref: 7615aa2c08b13051a09c4478826d44ea60bbe679 ocaml-apfs/lib/util.ml -rw-r--r-- 950 bytes
7615aa2c — Johann Rudloff Remove .merlin files. 1 year, 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let name_hash str =
  let len = ref 0 in
  let buf = Cstruct.create_unsafe (4 * (1 +String.length str)) in
  let dec = Uutf.(decoder ~encoding:`UTF_8 (`String str)) in
  (* TODO: normalize to NFD *)
  let rec loop d = match Uutf.decode d with
  | `Uchar uc -> (Cstruct.LE.set_uint32 buf (4 * !len) (Int32.of_int (Uchar.to_int uc))); len := (!len + 1); loop d
  | `End -> !len
  | `Await -> assert false
  | `Malformed _ -> assert false
  in
  let charcount = loop dec in
  let buf = Cstruct.sub buf 0 (4 * charcount) in
  let crc32c = Checkseum.Crc32c.unsafe_digest_bigstring (Cstruct.to_bigarray buf) 0 (Cstruct.len buf) Checkseum.Crc32c.default in
  Int32.lognot (Optint.to_int32 crc32c)

let name_len_and_hash str =
  let hash = Int32.logand 0x3fffffl (name_hash str) in
  let len = 0x3ff land (String.length str) |> Int32.of_int in
  let len = Int32.(add len 1l) in (* len includes the final NUL byte *)
  Int32.(logor (shift_left hash 10) len)