Last active
October 21, 2023 01:24
-
-
Save dbuenzli/68b92432afb2d167aa48162ff5782bcd to your computer and use it in GitHub Desktop.
Bigarray mmap RW
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* SPDX-License-Identifier: CC0-1.0 *) | |
let bigbytes_of_file ?(trunc = false) ?length access file = | |
let module Bigarray = Stdlib.Bigarray (* OCaml < 5 install woes *) in | |
let flags, shared = match access with | |
| `R -> Unix.[O_RDONLY], false | |
| `RW -> Unix.(O_CREAT :: O_RDWR :: if trunc then [O_TRUNC] else []), true | |
in | |
let fd = Unix.openfile file flags 0o644 in | |
let finally () = try Unix.close fd with Unix.Unix_error _ -> () in | |
Fun.protect ~finally @@ fun () -> | |
(* mmap on macOS returns EINVAL rather ENODEV on dirs so we check before *) | |
let stat = Unix.fstat fd in | |
if stat.st_kind <> S_REG | |
then raise (Unix.Unix_error (ENODEV, "bigbytes_of_file'", file)) else | |
let length = match length with | |
| None -> -1 | |
| Some length when access = `RW -> length | |
| Some length -> Int.min length (Unix.lseek fd 0 Unix.SEEK_END) | |
in | |
let typ = Bigarray.int8_unsigned and layout = Bigarray.C_layout in | |
let map = Unix.map_file fd typ layout shared [|length|] in | |
Bigarray.array1_of_genarray map | |
let bigbytes_of_file' ?trunc ?length access file = | |
try Ok (bigbytes_of_file ?trunc ?length access file) with | |
| Unix.Unix_error (ENODEV, _, _) -> Error "Not a file" | |
| Unix.Unix_error (e, _, _) -> Error (Unix.error_message e) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment