mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-12 22:10:53 -05:00
48 lines
1.3 KiB
OCaml
48 lines
1.3 KiB
OCaml
type t = { mutable chunks: bytes (* TODO: use a in32vec with bigarray *) }
|
|
|
|
let create () : t = { chunks = Bytes.make 32 '\x00' }
|
|
let i2c = Char.chr
|
|
let c2i = Char.code
|
|
|
|
(* from index to offset in bytes *)
|
|
let[@inline] idx_bytes_ (i : int) : int = i lsr 3
|
|
|
|
(* from index to offset in a single char *)
|
|
let mask_ = 0b111
|
|
|
|
(* number of bytes *)
|
|
let[@inline] len_ (self : t) : int = Bytes.length self.chunks
|
|
|
|
let[@inline never] resize_ self idx : unit =
|
|
let new_size =
|
|
min Sys.max_string_length
|
|
(max (idx + 2)
|
|
(let l = len_ self in
|
|
l + 10 + (l / 2)))
|
|
in
|
|
let new_chunks = Bytes.make new_size (i2c 0) in
|
|
Bytes.blit self.chunks 0 new_chunks 0 (len_ self);
|
|
self.chunks <- new_chunks;
|
|
assert (len_ self > idx)
|
|
|
|
let[@inline] ensure_size self i =
|
|
let idx = idx_bytes_ i in
|
|
if idx >= len_ self then resize_ self idx
|
|
|
|
let[@inline] get self i : bool =
|
|
let idx = idx_bytes_ i in
|
|
let c = c2i (Bytes.get self.chunks idx) in
|
|
c land (1 lsl (i land mask_)) <> 0
|
|
|
|
let set self i b : unit =
|
|
let idx = idx_bytes_ i in
|
|
let c = c2i (Bytes.get self.chunks idx) in
|
|
let c =
|
|
if b then
|
|
c lor (1 lsl (i land mask_))
|
|
else
|
|
c land lnot (1 lsl (i land mask_))
|
|
in
|
|
Bytes.set self.chunks idx (i2c c)
|
|
|
|
let clear_all self = Bytes.fill self.chunks 0 (len_ self) '\x00'
|