An OCaml webserver, but the allocating version (vs httpz which doesnt)
at main 113 lines 2.8 kB view raw
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;;