An OCaml webserver, but the allocating version (vs httpz which doesnt)
1(* buf_write.ml - Low-level buffer writing primitives for HTTP response generation *)
2
3open Base
4
5let char dst ~off c =
6 Bigarray.Array1.unsafe_set dst off c;
7 off + 1
8;;
9
10let string dst ~off s =
11 let len = String.length s in
12 for i = 0 to len - 1 do
13 Bigarray.Array1.unsafe_set dst (off + i) (String.unsafe_get s i)
14 done;
15 off + len
16;;
17
18let crlf dst ~off =
19 Bigarray.Array1.unsafe_set dst off '\r';
20 Bigarray.Array1.unsafe_set dst (off + 1) '\n';
21 off + 2
22;;
23
24(* Count digits in a positive integer *)
25let count_digits n =
26 let temp = ref n in
27 let digits = ref 0 in
28 while !temp > 0 do
29 Int.incr digits;
30 temp := !temp / 10
31 done;
32 !digits
33;;
34
35let int dst ~off n =
36 if n = 0 then (
37 Bigarray.Array1.unsafe_set dst off '0';
38 off + 1
39 ) else (
40 let digits = count_digits n in
41 let p = ref (off + digits - 1) in
42 let remaining = ref n in
43 while !remaining > 0 do
44 Bigarray.Array1.unsafe_set dst !p (Char.of_int_exn (48 + Int.rem !remaining 10));
45 remaining := !remaining / 10;
46 Int.decr p
47 done;
48 off + digits
49 )
50;;
51
52let int64 dst ~off n =
53 if Int64.(n = 0L) then (
54 Bigarray.Array1.unsafe_set dst off '0';
55 off + 1
56 ) else (
57 (* Count digits *)
58 let temp = ref n in
59 let digits = ref 0 in
60 while Int64.(!temp > 0L) do
61 Int.incr digits;
62 temp := Int64.(!temp / 10L)
63 done;
64 (* Write digits in reverse *)
65 let p = ref (off + !digits - 1) in
66 let remaining = ref n in
67 while Int64.(!remaining > 0L) do
68 let digit = Int64.(!remaining % 10L) |> Int64.to_int_exn in
69 Bigarray.Array1.unsafe_set dst !p (Char.of_int_exn (48 + digit));
70 remaining := Int64.(!remaining / 10L);
71 Int.decr p
72 done;
73 off + !digits
74 )
75;;
76
77let hex_chars = "0123456789abcdef"
78
79let hex dst ~off n =
80 if n = 0 then (
81 Bigarray.Array1.unsafe_set dst off '0';
82 off + 1
83 ) else (
84 let temp = ref n in
85 let digits = ref 0 in
86 while !temp > 0 do
87 Int.incr digits;
88 temp := !temp lsr 4
89 done;
90 let p = ref (off + !digits - 1) in
91 let remaining = ref n in
92 while !remaining > 0 do
93 Bigarray.Array1.unsafe_set dst !p (String.unsafe_get hex_chars (!remaining land 0xf));
94 remaining := !remaining lsr 4;
95 Int.decr p
96 done;
97 off + !digits
98 )
99;;
100
101let digit2 dst ~off n =
102 Bigarray.Array1.unsafe_set dst off (Char.of_int_exn (48 + n / 10));
103 Bigarray.Array1.unsafe_set dst (off + 1) (Char.of_int_exn (48 + n % 10));
104 off + 2
105;;
106
107let digit4 dst ~off n =
108 Bigarray.Array1.unsafe_set dst off (Char.of_int_exn (48 + n / 1000));
109 Bigarray.Array1.unsafe_set dst (off + 1) (Char.of_int_exn (48 + (n / 100) % 10));
110 Bigarray.Array1.unsafe_set dst (off + 2) (Char.of_int_exn (48 + (n / 10) % 10));
111 Bigarray.Array1.unsafe_set dst (off + 3) (Char.of_int_exn (48 + n % 10));
112 off + 4
113;;