(* buf_write.ml - Low-level buffer writing primitives for HTTP response generation *) open Base let char dst ~off c = Bigarray.Array1.unsafe_set dst off c; off + 1 ;; let string dst ~off s = let len = String.length s in for i = 0 to len - 1 do Bigarray.Array1.unsafe_set dst (off + i) (String.unsafe_get s i) done; off + len ;; let crlf dst ~off = Bigarray.Array1.unsafe_set dst off '\r'; Bigarray.Array1.unsafe_set dst (off + 1) '\n'; off + 2 ;; (* Count digits in a positive integer *) let count_digits n = let temp = ref n in let digits = ref 0 in while !temp > 0 do Int.incr digits; temp := !temp / 10 done; !digits ;; let int dst ~off n = if n = 0 then ( Bigarray.Array1.unsafe_set dst off '0'; off + 1 ) else ( let digits = count_digits n in let p = ref (off + digits - 1) in let remaining = ref n in while !remaining > 0 do Bigarray.Array1.unsafe_set dst !p (Char.of_int_exn (48 + Int.rem !remaining 10)); remaining := !remaining / 10; Int.decr p done; off + digits ) ;; let int64 dst ~off n = if Int64.(n = 0L) then ( Bigarray.Array1.unsafe_set dst off '0'; off + 1 ) else ( (* Count digits *) let temp = ref n in let digits = ref 0 in while Int64.(!temp > 0L) do Int.incr digits; temp := Int64.(!temp / 10L) done; (* Write digits in reverse *) let p = ref (off + !digits - 1) in let remaining = ref n in while Int64.(!remaining > 0L) do let digit = Int64.(!remaining % 10L) |> Int64.to_int_exn in Bigarray.Array1.unsafe_set dst !p (Char.of_int_exn (48 + digit)); remaining := Int64.(!remaining / 10L); Int.decr p done; off + !digits ) ;; let hex_chars = "0123456789abcdef" let hex dst ~off n = if n = 0 then ( Bigarray.Array1.unsafe_set dst off '0'; off + 1 ) else ( let temp = ref n in let digits = ref 0 in while !temp > 0 do Int.incr digits; temp := !temp lsr 4 done; let p = ref (off + !digits - 1) in let remaining = ref n in while !remaining > 0 do Bigarray.Array1.unsafe_set dst !p (String.unsafe_get hex_chars (!remaining land 0xf)); remaining := !remaining lsr 4; Int.decr p done; off + !digits ) ;; let digit2 dst ~off n = Bigarray.Array1.unsafe_set dst off (Char.of_int_exn (48 + n / 10)); Bigarray.Array1.unsafe_set dst (off + 1) (Char.of_int_exn (48 + n % 10)); off + 2 ;; let digit4 dst ~off n = Bigarray.Array1.unsafe_set dst off (Char.of_int_exn (48 + n / 1000)); Bigarray.Array1.unsafe_set dst (off + 1) (Char.of_int_exn (48 + (n / 100) % 10)); Bigarray.Array1.unsafe_set dst (off + 2) (Char.of_int_exn (48 + (n / 10) % 10)); Bigarray.Array1.unsafe_set dst (off + 3) (Char.of_int_exn (48 + n % 10)); off + 4 ;;