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:
Simon Cruanes 2013-08-29 14:30:42 +02:00
parent 7e82adf973
commit 197f7eb786
2 changed files with 57 additions and 14 deletions

View file

@ -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

View file

@ -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