mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
more functions in B-encode, to compute the size of an
expression in bytes, and write it into an already-existing string
This commit is contained in:
parent
7e82adf973
commit
197f7eb786
2 changed files with 57 additions and 14 deletions
63
bencode.ml
63
bencode.ml
|
|
@ -54,24 +54,59 @@ let dict_of_list l =
|
||||||
|
|
||||||
(** {2 Serialization (encoding)} *)
|
(** {2 Serialization (encoding)} *)
|
||||||
|
|
||||||
let rec to_buf buf t = match t with
|
(* length of an encoded int, in bytes *)
|
||||||
| I i -> Printf.bprintf buf "i%de" i
|
let _len_int i =
|
||||||
| S s ->
|
match i with
|
||||||
Printf.bprintf buf "%d:" (String.length s);
|
| 0 -> 1
|
||||||
Buffer.add_string buf s
|
| _ when i < 0 -> 2 + int_of_float (log10 (float_of_int ~-i))
|
||||||
|
| _ -> 1 + int_of_float (log10 (float_of_int i))
|
||||||
|
|
||||||
|
(* length of an encoded string, in bytes *)
|
||||||
|
let _len_str s =
|
||||||
|
_len_int (String.length s) + 1 + String.length s
|
||||||
|
|
||||||
|
let rec size t = match t with
|
||||||
|
| I i -> 2 + _len_int i
|
||||||
|
| S s -> _len_str s
|
||||||
|
| L l -> List.fold_left (fun acc i -> acc + size i) 2 l
|
||||||
|
| D map -> SMap.fold (fun k v acc -> acc + _len_str k + size v) map 2
|
||||||
|
|
||||||
|
let write_in_string t buf o =
|
||||||
|
let pos = ref o in
|
||||||
|
let rec append t = match t with
|
||||||
|
| I i -> write_char 'i'; write_int i; write_char 'e'
|
||||||
|
| S s -> write_str s
|
||||||
| L l ->
|
| L l ->
|
||||||
Buffer.add_char buf 'l';
|
write_char 'l';
|
||||||
List.iter (fun t' -> to_buf buf t') l;
|
List.iter append l;
|
||||||
Buffer.add_char buf 'e'
|
write_char 'e';
|
||||||
| D m ->
|
| D m ->
|
||||||
Buffer.add_char buf 'd';
|
write_char 'd';
|
||||||
SMap.iter (fun key t' -> to_buf buf (S key); to_buf buf t') m;
|
SMap.iter (fun key t' -> write_str key; append t') m;
|
||||||
Buffer.add_char buf 'e'
|
write_char 'e'
|
||||||
|
and write_int i =
|
||||||
|
let s = string_of_int i in
|
||||||
|
String.blit s 0 buf !pos (String.length s);
|
||||||
|
pos := !pos + String.length s
|
||||||
|
and write_str s =
|
||||||
|
write_int (String.length s);
|
||||||
|
write_char ':';
|
||||||
|
String.blit s 0 buf !pos (String.length s);
|
||||||
|
pos := !pos + String.length s
|
||||||
|
and write_char c =
|
||||||
|
buf.[!pos] <- c;
|
||||||
|
incr pos
|
||||||
|
in
|
||||||
|
append t
|
||||||
|
|
||||||
let to_string t =
|
let to_string t =
|
||||||
let b = Buffer.create 25 in
|
let len = size t in
|
||||||
to_buf b t;
|
let s = String.create len in
|
||||||
Buffer.contents b
|
write_in_string t s 0;
|
||||||
|
s
|
||||||
|
|
||||||
|
let to_buf buf t =
|
||||||
|
Buffer.add_string buf (to_string t)
|
||||||
|
|
||||||
let to_chan ch t =
|
let to_chan ch t =
|
||||||
let b = Buffer.create 25 in
|
let b = Buffer.create 25 in
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,14 @@ val dict_of_list : (string * t) list -> t
|
||||||
|
|
||||||
(** {2 Serialization (encoding)} *)
|
(** {2 Serialization (encoding)} *)
|
||||||
|
|
||||||
|
val size : t -> int
|
||||||
|
(** Size needed for serialization *)
|
||||||
|
|
||||||
|
val write_in_string : t -> string -> int -> unit
|
||||||
|
(** [write_in_string v buf o] writes the value [v] in the string,
|
||||||
|
starting at offset [o]. The portion of the string starting from [o]
|
||||||
|
must be big enough (ie >= [size v]) *)
|
||||||
|
|
||||||
val to_buf : Buffer.t -> t -> unit
|
val to_buf : Buffer.t -> t -> unit
|
||||||
val to_string : t -> string
|
val to_string : t -> string
|
||||||
val to_chan : out_channel -> t -> unit
|
val to_chan : out_channel -> t -> unit
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue