Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vendor ocamlnet #21

Merged
merged 9 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion devkit.opam
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ depends: [
"camlzip"
"libevent" {>= "0.8.0"}
"ocurl" {>= "0.7.2"}
"ocamlnet"
"pcre"
"trace" {>= "0.4"}
"extunix" {>= "0.1.4"}
Expand Down
6 changes: 4 additions & 2 deletions dune
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
libevent
lwt
lwt.unix
netstring
ocamlnet_lite
pcre
stdlib-shims
str
trace.core
unix
yojson
(select
possibly_otel.ml
Expand Down Expand Up @@ -65,7 +67,7 @@

(executable
(name test)
(libraries devkit extlib extunix libevent netstring ounit2 yojson)
(libraries devkit extlib extunix libevent ocamlnet_lite ounit2 unix yojson)
(modules test test_httpev))

(rule
Expand Down
2 changes: 1 addition & 1 deletion httpev.ml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ let get_content_length headers =
| Some s -> try Some (int_of_string s) with _ -> failed Header (sprintf "content-length %S" s)

let decode_args s =
try Netencoding.Url.dest_url_encoded_parameters s with exn -> Exn.fail ~exn "decode_args : %S" s
try Ocamlnet_lite.Netencoding.Url.dest_url_encoded_parameters s with exn -> Exn.fail ~exn "decode_args : %S" s

let acceptable_encoding headers =
let split s c = List.map (String.strip ~chars:" \t\r\n") @@ Stre.nsplitc s c in
Expand Down
7 changes: 7 additions & 0 deletions ocamlnet_lite/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(library
(name ocamlnet_lite)
(public_name devkit.ocamlnet_lite)
(libraries
extlib ; just for Array.create
pcre
str))
34 changes: 34 additions & 0 deletions ocamlnet_lite/netaux.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module ArrayAux = struct
let int_blit_ref =
ref
(fun (src:int array) srcpos dest destpos len ->
(* A specialised version of Array.blit for int arrays.
* Faster than the polymorphic Array.blit for
* various reasons.
*)
if (len < 0 || srcpos < 0 ||
srcpos+len > Array.length src ||
destpos < 0 ||
destpos+len > Array.length dest) then
invalid_arg "Netaux.ArrayAux.int_blit";
if src != dest || destpos <= srcpos then (
for i = 0 to len-1 do
Array.unsafe_set
dest
(destpos+i)
(Array.unsafe_get src (srcpos+i))
done
) else (
for i = len-1 downto 0 do
Array.unsafe_set
dest
(destpos+i)
(Array.unsafe_get src (srcpos+i))
done
)
)

let int_blit src srcpos dest destpos len =
!int_blit_ref src srcpos dest destpos len

end
13 changes: 13 additions & 0 deletions ocamlnet_lite/netaux.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(** Internal auxiliary functions
*
* This is an internal module.
*)

(* Auxiliary stuff *)

module ArrayAux : sig
val int_blit : int array -> int -> int array -> int -> int -> unit
(** A specialisation of [Array.blit] for int arrays.
* (Performance reasons.)
*)
end
88 changes: 88 additions & 0 deletions ocamlnet_lite/netbuffer.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
type t = {
mutable buffer : Bytes.t;
mutable buffer_length : int; (* = String.length buffer *)
mutable length : int;
create_length : int;
}

(* To help the garbage collector:
* The 'buffer' has a minimum length of 31 bytes. This minimum can still
* be stored in the minor heap.
* The 'buffer' has a length which is always near a multiple of two. This
* limits the number of different bucket sizes, and simplifies reallocation
* of freed memory.
*)

(* Optimal string length:
* Every string takes: 1 word for the header, enough words for the
* contents + 1 Null byte (for C compatibility).
* If the buffer grows, it is best to use a new string length such
* that the number of words is exactly twice as large as for the previous
* string.
* n: length of the previous string in bytes
* w: storage size of the previous string in words
* n': length of the new string in bytes
* w' = 2*w: storage size of the new string in words
*
* w = (n+1) / word_length + 1
* [it is assumed that (n+1) is always a multiple of word_length]
*
* n' = (2*w - 1) * word_length - 1
*
* n' = [2 * ( [n+1] / word_length + 1) - 1] * word_length - 1
* = ...
* = (2*n + 2) + word_length - 1
* = 2 * n + word_length + 1
*
* n'+1 is again a multiple of word_length:
* n'+1 = 2*n + 2 + word_length
* = 2*(n+1) + word_length
* = a multiple of word_length because n+1 is a multiple of word_length
*)

let word_length = Sys.word_size / 8 (* in bytes *)

let create n =
let bl = max n 31 in
{
buffer = Bytes.create bl;
buffer_length = bl;
length = 0;
create_length = n;
}

let contents b = Bytes.sub_string b.buffer 0 b.length
let to_bytes b = Bytes.sub b.buffer 0 b.length

let to_tstring_poly : type s. t -> s Netstring_tstring.tstring_kind -> s =
fun b kind ->
match kind with
| Netstring_tstring.String_kind -> contents b
| Netstring_tstring.Bytes_kind -> to_bytes b

let alloc_space b n =
let rec new_size s =
if s >= n then s else new_size ((2 * s) + word_length + 1)
in
let size = min (new_size b.buffer_length) Sys.max_string_length in
if size < n then failwith "Netbuffer: string too large";
let buffer' = Bytes.create size in
Bytes.blit b.buffer 0 buffer' 0 b.length;
b.buffer <- buffer';
b.buffer_length <- size

let ensure_space b n =
(* Ensure that there are n bytes space in b *)
if n > b.buffer_length then alloc_space b n

let add_internal blit b s k l =
ensure_space b (l + b.length);
blit s k b.buffer b.length l;
b.length <- b.length + l

let add_substring b s k l =
if k < 0 || l < 0 || k > String.length s - l then
invalid_arg "Netbuffer.add_substring";
add_internal Bytes.blit_string b s k l

let add_string b s = add_substring b s 0 (String.length s)
19 changes: 19 additions & 0 deletions ocamlnet_lite/netbuffer.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(** A Netbuffer.t is a buffer that can grow and shrink dynamically. *)

type t

val create : int -> t
(** Creates a netbuffer which allocates initially this number of bytes.
* The logical length is zero.
*)

val to_tstring_poly : t -> 's Netstring_tstring.tstring_kind -> 's
(** Return the buffer in the format as selected by the arg *)

(** {2 Appending strings} *)

val add_string : t -> string -> unit
(** [add_string nb s]: Adds a copy of the string [s] to the logical end of
* the netbuffer [nb]. If necessary, [nb] grows.
*)

Loading
Loading