package bigstringaf
Bigstring intrinsics and fast blits based on memcpy/memmove
Install
Dune Dependency
Authors
Maintainers
Sources
0.3.0.tar.gz
sha256=cfaadf09e2ed9dc04a7c6cd55386ea2ca0f0296ad6d8b5777ff65b4bda7499d5
md5=739a2006067d7432743f777d7f5afcfd
doc/src/bigstringaf/bigstringaf.ml.html
Source file bigstringaf.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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
type bigstring = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t type t = bigstring let create size = Bigarray.(Array1.create char c_layout size) let empty = create 0 module BA1 = Bigarray.Array1 let length t = BA1.dim t external get : t -> int -> char = "%caml_ba_ref_1" external set : t -> int -> char -> unit = "%caml_ba_set_1" external unsafe_get : t -> int -> char = "%caml_ba_unsafe_ref_1" external unsafe_set : t -> int -> char -> unit = "%caml_ba_unsafe_set_1" external unsafe_blit : t -> src_off:int -> t -> dst_off:int -> len:int -> unit = "bigstringaf_blit_to_bigstring" [@@noalloc] external unsafe_blit_to_bytes : t -> src_off:int -> Bytes.t -> dst_off:int -> len:int -> unit = "bigstringaf_blit_to_bytes" [@@noalloc] external unsafe_blit_from_bytes : Bytes.t -> src_off:int -> t -> dst_off:int -> len:int -> unit = "bigstringaf_blit_from_bytes" [@@noalloc] external unsafe_blit_from_string : string -> src_off:int -> t -> dst_off:int -> len:int -> unit = "bigstringaf_blit_from_bytes" [@@noalloc] external unsafe_memcmp : t -> int -> t -> int -> int -> int = "bigstringaf_memcmp_bigstring" [@@noalloc] external unsafe_memcmp_string : t -> int -> string -> int -> int -> int = "bigstringaf_memcmp_string" [@@noalloc] let sub t ~off ~len = BA1.sub t off len let[@inline never] invalid_bounds op buffer_len off len = let message = Printf.sprintf "Bigstringaf.%s invalid range: { buffer_len: %d, off: %d, len: %d }" op buffer_len off len in raise (Invalid_argument message) ;; let[@inline never] invalid_bounds_blit op src_len src_off dst_len dst_off len = let message = Printf.sprintf "Bigstringaf.%s invalid range: { src_len: %d, src_off: %d, dst_len: %d, dst_off: %d, len: %d }" op src_len src_off dst_len dst_off len in raise (Invalid_argument message) ;; let[@inline never] invalid_bounds_memcmp op buf1_len buf1_off buf2_len buf2_off len = let message = Printf.sprintf "Bigstringaf.%s invalid range: { buf1_len: %d, buf1_off: %d, buf2_len: %d, buf2_off: %d, len: %d }" op buf1_len buf1_off buf2_len buf2_off len in raise (Invalid_argument message) ;; (* A note on bounds checking. * * The code should perform the following check to ensure that the blit doesn't * run off the end of the input buffer: * * {[off + len <= buffer_len]} * * However, this may lead to an interger overflow for large values of [off], * e.g., [max_int], which will cause the comparison to return [true] when it * should really return [false]. * * An equivalent comparison that does not run into this integer overflow * problem is: * * {[buffer_len - off => len]} * * This is checking that the input buffer, less the offset, is sufficiently * long to perform the blit. Since the expression is subtracting [off] rather * than adding it, it doesn't suffer from the overflow that the previous * inequality did. As long as there is check to ensure that [off] is not * negative, it won't underflow either. *) let copy t ~off ~len = let buffer_len = length t in if off < 0 || buffer_len - off < len then invalid_bounds "copy" buffer_len off len; let dst = create len in unsafe_blit t ~src_off:off dst ~dst_off:0 ~len; dst ;; let substring t ~off ~len = let buffer_len = length t in if off < 0 || buffer_len - off < len then invalid_bounds "substring" buffer_len off len; let b = Bytes.create len in unsafe_blit_to_bytes t ~src_off:off b ~dst_off:0 ~len; Bytes.unsafe_to_string b ;; let of_string ~off ~len s = let buffer_len = String.length s in if off < 0 || buffer_len - off < len then invalid_bounds "of_string" buffer_len off len; let b = create len in unsafe_blit_from_string s ~src_off:off b ~dst_off:0 ~len; b ;; let blit src ~src_off dst ~dst_off ~len = let src_len = length src in let dst_len = length dst in if src_off < 0 || src_len - src_off < len then invalid_bounds_blit "blit" src_len src_off dst_len dst_off len; if dst_off < 0 || dst_len - dst_off < len then invalid_bounds_blit "blit" src_len src_off dst_len dst_off len; unsafe_blit src ~src_off dst ~dst_off ~len ;; let blit_from_string src ~src_off dst ~dst_off ~len = let src_len = String.length src in let dst_len = length dst in if src_off < 0 || src_len - src_off < len then invalid_bounds_blit "blit_from_string" src_len src_off dst_len dst_off len; if dst_off < 0 || dst_len - dst_off < len then invalid_bounds_blit "blit_from_string" src_len src_off dst_len dst_off len; unsafe_blit_from_string src ~src_off dst ~dst_off ~len ;; let blit_from_bytes src ~src_off dst ~dst_off ~len = let src_len = Bytes.length src in let dst_len = length dst in if src_off < 0 || src_len - src_off < len then invalid_bounds_blit "blit_from_bytes" src_len src_off dst_len dst_off len; if dst_off < 0 || dst_len - dst_off < len then invalid_bounds_blit "blit_from_bytes" src_len src_off dst_len dst_off len; unsafe_blit_from_bytes src ~src_off dst ~dst_off ~len ;; let blit_to_bytes src ~src_off dst ~dst_off ~len = let src_len = length src in let dst_len = Bytes.length dst in if src_off < 0 || src_len - src_off < len then invalid_bounds_blit "blit_to_bytes" src_len src_off dst_len dst_off len; if dst_off < 0 || dst_len - dst_off < len then invalid_bounds_blit "blit_to_bytes" src_len src_off dst_len dst_off len; unsafe_blit_to_bytes src ~src_off dst ~dst_off ~len ;; let memcmp buf1 buf1_off buf2 buf2_off len = let buf1_len = length buf1 in let buf2_len = length buf2 in if buf1_off < 0 || buf1_len - buf1_off < len then invalid_bounds_memcmp "memcmp" buf1_len buf1_off buf2_len buf2_off len; if buf2_off < 0 || buf2_len - buf2_off < len then invalid_bounds_memcmp "memcmp" buf1_len buf1_off buf2_len buf2_off len; unsafe_memcmp buf1 buf1_off buf2 buf2_off len ;; let memcmp_string buf1 buf1_off buf2 buf2_off len = let buf1_len = length buf1 in let buf2_len = String.length buf2 in if buf1_off < 0 || buf1_len - buf1_off < len then invalid_bounds_memcmp "memcmp" buf1_len buf1_off buf2_len buf2_off len; if buf2_off < 0 || buf2_len - buf2_off < len then invalid_bounds_memcmp "memcmp" buf1_len buf1_off buf2_len buf2_off len; unsafe_memcmp_string buf1 buf1_off buf2 buf2_off len ;; (* Safe operations *) external caml_bigstring_set_16 : bigstring -> int -> int -> unit = "%caml_bigstring_set16" external caml_bigstring_set_32 : bigstring -> int -> int32 -> unit = "%caml_bigstring_set32" external caml_bigstring_set_64 : bigstring -> int -> int64 -> unit = "%caml_bigstring_set64" external caml_bigstring_get_16 : bigstring -> int -> int = "%caml_bigstring_get16" external caml_bigstring_get_32 : bigstring -> int -> int32 = "%caml_bigstring_get32" external caml_bigstring_get_64 : bigstring -> int -> int64 = "%caml_bigstring_get64" module Swap = struct external bswap16 : int -> int = "%bswap16" external bswap_int32 : int32 -> int32 = "%bswap_int32" external bswap_int64 : int64 -> int64 = "%bswap_int64" let caml_bigstring_set_16 bs off i = caml_bigstring_set_16 bs off (bswap16 i) let caml_bigstring_set_32 bs off i = caml_bigstring_set_32 bs off (bswap_int32 i) let caml_bigstring_set_64 bs off i = caml_bigstring_set_64 bs off (bswap_int64 i) let caml_bigstring_get_16 bs off = bswap16 (caml_bigstring_get_16 bs off) let caml_bigstring_get_32 bs off = bswap_int32 (caml_bigstring_get_32 bs off) let caml_bigstring_get_64 bs off = bswap_int64 (caml_bigstring_get_64 bs off) let get_int16_sign_extended x off = ((caml_bigstring_get_16 x off) lsl (Sys.int_size - 16)) asr (Sys.int_size - 16) end let set_int16_le, set_int16_be = if Sys.big_endian then Swap.caml_bigstring_set_16, caml_bigstring_set_16 else caml_bigstring_set_16 , Swap.caml_bigstring_set_16 let set_int32_le, set_int32_be = if Sys.big_endian then Swap.caml_bigstring_set_32, caml_bigstring_set_32 else caml_bigstring_set_32 , Swap.caml_bigstring_set_32 let set_int64_le, set_int64_be = if Sys.big_endian then Swap.caml_bigstring_set_64, caml_bigstring_set_64 else caml_bigstring_set_64 , Swap.caml_bigstring_set_64 let get_int16_le, get_int16_be = if Sys.big_endian then Swap.caml_bigstring_get_16, caml_bigstring_get_16 else caml_bigstring_get_16 , Swap.caml_bigstring_get_16 let get_int16_sign_extended_noswap x off = ((caml_bigstring_get_16 x off) lsl (Sys.int_size - 16)) asr (Sys.int_size - 16) let get_int16_sign_extended_le, get_int16_sign_extended_be = if Sys.big_endian then Swap.get_int16_sign_extended , get_int16_sign_extended_noswap else get_int16_sign_extended_noswap, Swap.get_int16_sign_extended let get_int32_le, get_int32_be = if Sys.big_endian then Swap.caml_bigstring_get_32, caml_bigstring_get_32 else caml_bigstring_get_32 , Swap.caml_bigstring_get_32 let get_int64_le, get_int64_be = if Sys.big_endian then Swap.caml_bigstring_get_64, caml_bigstring_get_64 else caml_bigstring_get_64 , Swap.caml_bigstring_get_64 (* Unsafe operations *) external caml_bigstring_unsafe_set_16 : bigstring -> int -> int -> unit = "%caml_bigstring_set16u" external caml_bigstring_unsafe_set_32 : bigstring -> int -> int32 -> unit = "%caml_bigstring_set32u" external caml_bigstring_unsafe_set_64 : bigstring -> int -> int64 -> unit = "%caml_bigstring_set64u" external caml_bigstring_unsafe_get_16 : bigstring -> int -> int = "%caml_bigstring_get16u" external caml_bigstring_unsafe_get_32 : bigstring -> int -> int32 = "%caml_bigstring_get32u" external caml_bigstring_unsafe_get_64 : bigstring -> int -> int64 = "%caml_bigstring_get64u" module USwap = struct external bswap16 : int -> int = "%bswap16" external bswap_int32 : int32 -> int32 = "%bswap_int32" external bswap_int64 : int64 -> int64 = "%bswap_int64" let caml_bigstring_unsafe_set_16 bs off i = caml_bigstring_unsafe_set_16 bs off (bswap16 i) let caml_bigstring_unsafe_set_32 bs off i = caml_bigstring_unsafe_set_32 bs off (bswap_int32 i) let caml_bigstring_unsafe_set_64 bs off i = caml_bigstring_unsafe_set_64 bs off (bswap_int64 i) let caml_bigstring_unsafe_get_16 bs off = bswap16 (caml_bigstring_unsafe_get_16 bs off) let caml_bigstring_unsafe_get_32 bs off = bswap_int32 (caml_bigstring_unsafe_get_32 bs off) let caml_bigstring_unsafe_get_64 bs off = bswap_int64 (caml_bigstring_unsafe_get_64 bs off) end let unsafe_set_int16_le, unsafe_set_int16_be = if Sys.big_endian then USwap.caml_bigstring_unsafe_set_16, caml_bigstring_unsafe_set_16 else caml_bigstring_unsafe_set_16 , USwap.caml_bigstring_unsafe_set_16 let unsafe_set_int32_le, unsafe_set_int32_be = if Sys.big_endian then USwap.caml_bigstring_unsafe_set_32, caml_bigstring_unsafe_set_32 else caml_bigstring_unsafe_set_32 , USwap.caml_bigstring_unsafe_set_32 let unsafe_set_int64_le, unsafe_set_int64_be = if Sys.big_endian then USwap.caml_bigstring_unsafe_set_64, caml_bigstring_unsafe_set_64 else caml_bigstring_unsafe_set_64 , USwap.caml_bigstring_unsafe_set_64 let unsafe_get_int16_le, unsafe_get_int16_be = if Sys.big_endian then USwap.caml_bigstring_unsafe_get_16, caml_bigstring_unsafe_get_16 else caml_bigstring_unsafe_get_16 , USwap.caml_bigstring_unsafe_get_16 let unsafe_get_int16_sign_extended_le x off = ((unsafe_get_int16_le x off) lsl (Sys.int_size - 16)) asr (Sys.int_size - 16) let unsafe_get_int16_sign_extended_be x off = ((unsafe_get_int16_be x off ) lsl (Sys.int_size - 16)) asr (Sys.int_size - 16) let unsafe_get_int32_le, unsafe_get_int32_be = if Sys.big_endian then USwap.caml_bigstring_unsafe_get_32, caml_bigstring_unsafe_get_32 else caml_bigstring_unsafe_get_32 , USwap.caml_bigstring_unsafe_get_32 let unsafe_get_int64_le, unsafe_get_int64_be = if Sys.big_endian then USwap.caml_bigstring_unsafe_get_64, caml_bigstring_unsafe_get_64 else caml_bigstring_unsafe_get_64 , USwap.caml_bigstring_unsafe_get_64
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>