|
rpm-build |
0f2925 |
(*
|
|
rpm-build |
0f2925 |
* IO - Abstract input/output
|
|
rpm-build |
0f2925 |
* Copyright (C) 2003 Nicolas Cannasse
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* This library is free software; you can redistribute it and/or
|
|
rpm-build |
0f2925 |
* modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0f2925 |
* License as published by the Free Software Foundation; either
|
|
rpm-build |
0f2925 |
* version 2.1 of the License, or (at your option) any later version,
|
|
rpm-build |
0f2925 |
* with the special exception on linking described in file LICENSE.
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
0f2925 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0f2925 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0f2925 |
* Lesser General Public License for more details.
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0f2925 |
* License along with this library; if not, write to the Free Software
|
|
rpm-build |
0f2925 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
rpm-build |
0f2925 |
*)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
open ExtBytes
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type input = {
|
|
rpm-build |
0f2925 |
mutable in_read : unit -> char;
|
|
rpm-build |
0f2925 |
mutable in_input : Bytes.t -> int -> int -> int;
|
|
rpm-build |
0f2925 |
mutable in_close : unit -> unit;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type 'a output = {
|
|
rpm-build |
0f2925 |
mutable out_write : char -> unit;
|
|
rpm-build |
0f2925 |
mutable out_output : Bytes.t -> int -> int -> int;
|
|
rpm-build |
0f2925 |
mutable out_close : unit -> 'a;
|
|
rpm-build |
0f2925 |
mutable out_flush : unit -> unit;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
exception No_more_input
|
|
rpm-build |
0f2925 |
exception Input_closed
|
|
rpm-build |
0f2925 |
exception Output_closed
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* -------------------------------------------------------------- *)
|
|
rpm-build |
0f2925 |
(* API *)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let default_close = (fun () -> ())
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let create_in ~read ~input ~close =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
in_read = read;
|
|
rpm-build |
0f2925 |
in_input = input;
|
|
rpm-build |
0f2925 |
in_close = close;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let create_out ~write ~output ~flush ~close =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
out_write = write;
|
|
rpm-build |
0f2925 |
out_output = output;
|
|
rpm-build |
0f2925 |
out_close = close;
|
|
rpm-build |
0f2925 |
out_flush = flush;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read i = i.in_read()
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let nread i n =
|
|
rpm-build |
0f2925 |
if n < 0 then invalid_arg "IO.nread";
|
|
rpm-build |
0f2925 |
if n = 0 then Bytes.empty
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
let s = Bytes.create n in
|
|
rpm-build |
0f2925 |
let l = ref n in
|
|
rpm-build |
0f2925 |
let p = ref 0 in
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
while !l > 0 do
|
|
rpm-build |
0f2925 |
let r = i.in_input s !p !l in
|
|
rpm-build |
0f2925 |
if r = 0 then raise No_more_input;
|
|
rpm-build |
0f2925 |
p := !p + r;
|
|
rpm-build |
0f2925 |
l := !l - r;
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
s
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
No_more_input as e ->
|
|
rpm-build |
0f2925 |
if !p = 0 then raise e;
|
|
rpm-build |
0f2925 |
Bytes.sub s 0 !p
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let nread_string i n =
|
|
rpm-build |
0f2925 |
(* [nread] transfers ownership of the returned string, so
|
|
rpm-build |
0f2925 |
[unsafe_to_string] is safe here *)
|
|
rpm-build |
0f2925 |
Bytes.unsafe_to_string (nread i n)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let really_output o s p l' =
|
|
rpm-build |
0f2925 |
let sl = Bytes.length s in
|
|
rpm-build |
0f2925 |
if p + l' > sl || p < 0 || l' < 0 then invalid_arg "IO.really_output";
|
|
rpm-build |
0f2925 |
let l = ref l' in
|
|
rpm-build |
0f2925 |
let p = ref p in
|
|
rpm-build |
0f2925 |
while !l > 0 do
|
|
rpm-build |
0f2925 |
let w = o.out_output s !p !l in
|
|
rpm-build |
0f2925 |
if w = 0 then raise Sys_blocked_io;
|
|
rpm-build |
0f2925 |
p := !p + w;
|
|
rpm-build |
0f2925 |
l := !l - w;
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
l'
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input i s p l =
|
|
rpm-build |
0f2925 |
let sl = Bytes.length s in
|
|
rpm-build |
0f2925 |
if p + l > sl || p < 0 || l < 0 then invalid_arg "IO.input";
|
|
rpm-build |
0f2925 |
if l = 0 then
|
|
rpm-build |
0f2925 |
0
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
i.in_input s p l
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let really_input i s p l' =
|
|
rpm-build |
0f2925 |
let sl = Bytes.length s in
|
|
rpm-build |
0f2925 |
if p + l' > sl || p < 0 || l' < 0 then invalid_arg "IO.really_input";
|
|
rpm-build |
0f2925 |
let l = ref l' in
|
|
rpm-build |
0f2925 |
let p = ref p in
|
|
rpm-build |
0f2925 |
while !l > 0 do
|
|
rpm-build |
0f2925 |
let r = i.in_input s !p !l in
|
|
rpm-build |
0f2925 |
if r = 0 then raise Sys_blocked_io;
|
|
rpm-build |
0f2925 |
p := !p + r;
|
|
rpm-build |
0f2925 |
l := !l - r;
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
l'
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let really_nread i n =
|
|
rpm-build |
0f2925 |
if n < 0 then invalid_arg "IO.really_nread";
|
|
rpm-build |
0f2925 |
if n = 0 then Bytes.empty
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
let s = Bytes.create n
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
ignore(really_input i s 0 n);
|
|
rpm-build |
0f2925 |
s
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let really_nread_string i n =
|
|
rpm-build |
0f2925 |
(* [really_nread] transfers ownership of the returned string,
|
|
rpm-build |
0f2925 |
so [unsafe_to_string] is safe here *)
|
|
rpm-build |
0f2925 |
Bytes.unsafe_to_string (really_nread i n)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let close_in i =
|
|
rpm-build |
0f2925 |
let f _ = raise Input_closed in
|
|
rpm-build |
0f2925 |
i.in_close();
|
|
rpm-build |
0f2925 |
i.in_read <- f;
|
|
rpm-build |
0f2925 |
i.in_input <- f;
|
|
rpm-build |
0f2925 |
i.in_close <- f
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write o x = o.out_write x
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let nwrite o s =
|
|
rpm-build |
0f2925 |
let p = ref 0 in
|
|
rpm-build |
0f2925 |
let l = ref (Bytes.length s) in
|
|
rpm-build |
0f2925 |
while !l > 0 do
|
|
rpm-build |
0f2925 |
let w = o.out_output s !p !l in
|
|
rpm-build |
0f2925 |
if w = 0 then raise Sys_blocked_io;
|
|
rpm-build |
0f2925 |
p := !p + w;
|
|
rpm-build |
0f2925 |
l := !l - w;
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let nwrite_string o s =
|
|
rpm-build |
0f2925 |
(* [nwrite] does not mutate or capture its [bytes] input,
|
|
rpm-build |
0f2925 |
so using [Bytes.unsafe_of_string] is safe here *)
|
|
rpm-build |
0f2925 |
nwrite o (Bytes.unsafe_of_string s)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output o s p l =
|
|
rpm-build |
0f2925 |
let sl = Bytes.length s in
|
|
rpm-build |
0f2925 |
if p + l > sl || p < 0 || l < 0 then invalid_arg "IO.output";
|
|
rpm-build |
0f2925 |
o.out_output s p l
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let scanf i fmt =
|
|
rpm-build |
0f2925 |
let ib = Scanf.Scanning.from_function (fun () -> try read i with No_more_input -> raise End_of_file) in
|
|
rpm-build |
0f2925 |
Scanf.kscanf ib (fun _ exn -> raise exn) fmt
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let printf o fmt =
|
|
rpm-build |
0f2925 |
Printf.kprintf (fun s -> nwrite_string o s) fmt
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let flush o = o.out_flush()
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let close_out o =
|
|
rpm-build |
0f2925 |
let f _ = raise Output_closed in
|
|
rpm-build |
0f2925 |
let r = o.out_close() in
|
|
rpm-build |
0f2925 |
o.out_write <- f;
|
|
rpm-build |
0f2925 |
o.out_output <- f;
|
|
rpm-build |
0f2925 |
o.out_close <- f;
|
|
rpm-build |
0f2925 |
o.out_flush <- f;
|
|
rpm-build |
0f2925 |
r
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_all i =
|
|
rpm-build |
0f2925 |
let maxlen = 1024 in
|
|
rpm-build |
0f2925 |
let str = ref [] in
|
|
rpm-build |
0f2925 |
let pos = ref 0 in
|
|
rpm-build |
0f2925 |
let rec loop() =
|
|
rpm-build |
0f2925 |
let s = nread i maxlen in
|
|
rpm-build |
0f2925 |
str := (s,!pos) :: !str;
|
|
rpm-build |
0f2925 |
pos := !pos + Bytes.length s;
|
|
rpm-build |
0f2925 |
loop()
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
loop()
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
No_more_input ->
|
|
rpm-build |
0f2925 |
let buf = Bytes.create !pos in
|
|
rpm-build |
0f2925 |
List.iter (fun (s,p) ->
|
|
rpm-build |
0f2925 |
Bytes.blit s 0 buf p (Bytes.length s)
|
|
rpm-build |
0f2925 |
) !str;
|
|
rpm-build |
0f2925 |
(* 'buf' doesn't escape, it won't be mutated again *)
|
|
rpm-build |
0f2925 |
Bytes.unsafe_to_string buf
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let pos_in i =
|
|
rpm-build |
0f2925 |
let p = ref 0 in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
in_read = (fun () ->
|
|
rpm-build |
0f2925 |
let c = i.in_read() in
|
|
rpm-build |
0f2925 |
incr p;
|
|
rpm-build |
0f2925 |
c
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_input = (fun s sp l ->
|
|
rpm-build |
0f2925 |
let n = i.in_input s sp l in
|
|
rpm-build |
0f2925 |
p := !p + n;
|
|
rpm-build |
0f2925 |
n
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_close = i.in_close
|
|
rpm-build |
0f2925 |
} , (fun () -> !p)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let pos_out o =
|
|
rpm-build |
0f2925 |
let p = ref 0 in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
out_write = (fun c ->
|
|
rpm-build |
0f2925 |
o.out_write c;
|
|
rpm-build |
0f2925 |
incr p
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_output = (fun s sp l ->
|
|
rpm-build |
0f2925 |
let n = o.out_output s sp l in
|
|
rpm-build |
0f2925 |
p := !p + n;
|
|
rpm-build |
0f2925 |
n
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_close = o.out_close;
|
|
rpm-build |
0f2925 |
out_flush = o.out_flush;
|
|
rpm-build |
0f2925 |
} , (fun () -> !p)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* -------------------------------------------------------------- *)
|
|
rpm-build |
0f2925 |
(* Standard IO *)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_bytes s =
|
|
rpm-build |
0f2925 |
let pos = ref 0 in
|
|
rpm-build |
0f2925 |
let len = Bytes.length s in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
in_read = (fun () ->
|
|
rpm-build |
0f2925 |
if !pos >= len then raise No_more_input;
|
|
rpm-build |
0f2925 |
let c = Bytes.unsafe_get s !pos in
|
|
rpm-build |
0f2925 |
incr pos;
|
|
rpm-build |
0f2925 |
c
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_input = (fun sout p l ->
|
|
rpm-build |
0f2925 |
if !pos >= len then raise No_more_input;
|
|
rpm-build |
0f2925 |
let n = (if !pos + l > len then len - !pos else l) in
|
|
rpm-build |
0f2925 |
Bytes.unsafe_blit s !pos sout p n;
|
|
rpm-build |
0f2925 |
pos := !pos + n;
|
|
rpm-build |
0f2925 |
n
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_close = (fun () -> ());
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_string s =
|
|
rpm-build |
0f2925 |
(* Bytes.unsafe_of_string is safe here as input_bytes does not
|
|
rpm-build |
0f2925 |
mutate the byte sequence *)
|
|
rpm-build |
0f2925 |
input_bytes (Bytes.unsafe_of_string s)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
open ExtBuffer
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_buffer close =
|
|
rpm-build |
0f2925 |
let b = Buffer.create 0 in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
out_write = (fun c -> Buffer.add_char b c);
|
|
rpm-build |
0f2925 |
out_output = (fun s p l -> Buffer.add_subbytes b s p l; l);
|
|
rpm-build |
0f2925 |
out_close = (fun () -> close b);
|
|
rpm-build |
0f2925 |
out_flush = (fun () -> ());
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_string () = output_buffer Buffer.contents
|
|
rpm-build |
0f2925 |
let output_bytes () = output_buffer Buffer.to_bytes
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_strings() =
|
|
rpm-build |
0f2925 |
let sl = ref [] in
|
|
rpm-build |
0f2925 |
let size = ref 0 in
|
|
rpm-build |
0f2925 |
let b = Buffer.create 0 in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
out_write = (fun c ->
|
|
rpm-build |
0f2925 |
if !size = Sys.max_string_length then begin
|
|
rpm-build |
0f2925 |
sl := Buffer.contents b :: !sl;
|
|
rpm-build |
0f2925 |
Buffer.clear b;
|
|
rpm-build |
0f2925 |
size := 0;
|
|
rpm-build |
0f2925 |
end else incr size;
|
|
rpm-build |
0f2925 |
Buffer.add_char b c
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_output = (fun s p l ->
|
|
rpm-build |
0f2925 |
if !size + l > Sys.max_string_length then begin
|
|
rpm-build |
0f2925 |
sl := Buffer.contents b :: !sl;
|
|
rpm-build |
0f2925 |
Buffer.clear b;
|
|
rpm-build |
0f2925 |
size := 0;
|
|
rpm-build |
0f2925 |
end else size := !size + l;
|
|
rpm-build |
0f2925 |
Buffer.add_subbytes b s p l;
|
|
rpm-build |
0f2925 |
l
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_close = (fun () -> sl := Buffer.contents b :: !sl; List.rev (!sl));
|
|
rpm-build |
0f2925 |
out_flush = (fun () -> ());
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_channel ch =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
in_read = (fun () ->
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
input_char ch
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
End_of_file -> raise No_more_input
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_input = (fun s p l ->
|
|
rpm-build |
0f2925 |
let n = Pervasives.input ch s p l in
|
|
rpm-build |
0f2925 |
if n = 0 then raise No_more_input;
|
|
rpm-build |
0f2925 |
n
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_close = (fun () -> Pervasives.close_in ch);
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_channel ch =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
out_write = (fun c -> output_char ch c);
|
|
rpm-build |
0f2925 |
out_output = (fun s p l -> Pervasives.output ch s p l; l);
|
|
rpm-build |
0f2925 |
out_close = (fun () -> Pervasives.close_out ch);
|
|
rpm-build |
0f2925 |
out_flush = (fun () -> Pervasives.flush ch);
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_enum e =
|
|
rpm-build |
0f2925 |
let pos = ref 0 in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
in_read = (fun () ->
|
|
rpm-build |
0f2925 |
match Enum.get e with
|
|
rpm-build |
0f2925 |
| None -> raise No_more_input
|
|
rpm-build |
0f2925 |
| Some c ->
|
|
rpm-build |
0f2925 |
incr pos;
|
|
rpm-build |
0f2925 |
c
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_input = (fun s p l ->
|
|
rpm-build |
0f2925 |
let rec loop p l =
|
|
rpm-build |
0f2925 |
if l = 0 then
|
|
rpm-build |
0f2925 |
0
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
match Enum.get e with
|
|
rpm-build |
0f2925 |
| None -> l
|
|
rpm-build |
0f2925 |
| Some c ->
|
|
rpm-build |
0f2925 |
Bytes.unsafe_set s p c;
|
|
rpm-build |
0f2925 |
loop (p + 1) (l - 1)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let k = loop p l in
|
|
rpm-build |
0f2925 |
if k = l then raise No_more_input;
|
|
rpm-build |
0f2925 |
l - k
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
in_close = (fun () -> ());
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_enum() =
|
|
rpm-build |
0f2925 |
let b = Buffer.create 0 in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
out_write = (fun x ->
|
|
rpm-build |
0f2925 |
Buffer.add_char b x
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_output = (fun s p l ->
|
|
rpm-build |
0f2925 |
Buffer.add_subbytes b s p l;
|
|
rpm-build |
0f2925 |
l
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_close = (fun () ->
|
|
rpm-build |
0f2925 |
let s = Buffer.contents b in
|
|
rpm-build |
0f2925 |
ExtString.String.enum s
|
|
rpm-build |
0f2925 |
);
|
|
rpm-build |
0f2925 |
out_flush = (fun () -> ());
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let pipe() =
|
|
rpm-build |
0f2925 |
let input = ref "" in
|
|
rpm-build |
0f2925 |
let inpos = ref 0 in
|
|
rpm-build |
0f2925 |
let output = Buffer.create 0 in
|
|
rpm-build |
0f2925 |
let flush() =
|
|
rpm-build |
0f2925 |
input := Buffer.contents output;
|
|
rpm-build |
0f2925 |
inpos := 0;
|
|
rpm-build |
0f2925 |
Buffer.reset output;
|
|
rpm-build |
0f2925 |
if String.length !input = 0 then raise No_more_input
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let read() =
|
|
rpm-build |
0f2925 |
if !inpos = String.length !input then flush();
|
|
rpm-build |
0f2925 |
let c = String.unsafe_get !input !inpos in
|
|
rpm-build |
0f2925 |
incr inpos;
|
|
rpm-build |
0f2925 |
c
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let input s p l =
|
|
rpm-build |
0f2925 |
if !inpos = String.length !input then flush();
|
|
rpm-build |
0f2925 |
let r = (if !inpos + l > String.length !input then String.length !input - !inpos else l) in
|
|
rpm-build |
0f2925 |
String.unsafe_blit !input !inpos s p r;
|
|
rpm-build |
0f2925 |
inpos := !inpos + r;
|
|
rpm-build |
0f2925 |
r
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let write c =
|
|
rpm-build |
0f2925 |
Buffer.add_char output c
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let output s p l =
|
|
rpm-build |
0f2925 |
Buffer.add_subbytes output s p l;
|
|
rpm-build |
0f2925 |
l
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let input = {
|
|
rpm-build |
0f2925 |
in_read = read;
|
|
rpm-build |
0f2925 |
in_input = input;
|
|
rpm-build |
0f2925 |
in_close = (fun () -> ());
|
|
rpm-build |
0f2925 |
} in
|
|
rpm-build |
0f2925 |
let output = {
|
|
rpm-build |
0f2925 |
out_write = write;
|
|
rpm-build |
0f2925 |
out_output = output;
|
|
rpm-build |
0f2925 |
out_close = (fun () -> ());
|
|
rpm-build |
0f2925 |
out_flush = (fun () -> ());
|
|
rpm-build |
0f2925 |
} in
|
|
rpm-build |
0f2925 |
input , output
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
external cast_output : 'a output -> unit output = "%identity"
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* -------------------------------------------------------------- *)
|
|
rpm-build |
0f2925 |
(* BINARY APIs *)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
exception Overflow of string
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_byte i = int_of_char (i.in_read())
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_signed_byte i =
|
|
rpm-build |
0f2925 |
let c = int_of_char (i.in_read()) in
|
|
rpm-build |
0f2925 |
if c land 128 <> 0 then
|
|
rpm-build |
0f2925 |
c - 256
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
c
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_string_into_buffer i =
|
|
rpm-build |
0f2925 |
let b = Buffer.create 8 in
|
|
rpm-build |
0f2925 |
let rec loop() =
|
|
rpm-build |
0f2925 |
let c = i.in_read() in
|
|
rpm-build |
0f2925 |
if c <> '\000' then begin
|
|
rpm-build |
0f2925 |
Buffer.add_char b c;
|
|
rpm-build |
0f2925 |
loop();
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop();
|
|
rpm-build |
0f2925 |
b
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_string i =
|
|
rpm-build |
0f2925 |
Buffer.contents
|
|
rpm-build |
0f2925 |
(read_string_into_buffer i)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_bytes i =
|
|
rpm-build |
0f2925 |
Buffer.to_bytes
|
|
rpm-build |
0f2925 |
(read_string_into_buffer i)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_line i =
|
|
rpm-build |
0f2925 |
let b = Buffer.create 8 in
|
|
rpm-build |
0f2925 |
let cr = ref false in
|
|
rpm-build |
0f2925 |
let rec loop() =
|
|
rpm-build |
0f2925 |
let c = i.in_read() in
|
|
rpm-build |
0f2925 |
match c with
|
|
rpm-build |
0f2925 |
| '\n' ->
|
|
rpm-build |
0f2925 |
()
|
|
rpm-build |
0f2925 |
| '\r' ->
|
|
rpm-build |
0f2925 |
cr := true;
|
|
rpm-build |
0f2925 |
loop()
|
|
rpm-build |
0f2925 |
| _ when !cr ->
|
|
rpm-build |
0f2925 |
cr := false;
|
|
rpm-build |
0f2925 |
Buffer.add_char b '\r';
|
|
rpm-build |
0f2925 |
Buffer.add_char b c;
|
|
rpm-build |
0f2925 |
loop();
|
|
rpm-build |
0f2925 |
| _ ->
|
|
rpm-build |
0f2925 |
Buffer.add_char b c;
|
|
rpm-build |
0f2925 |
loop();
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
loop();
|
|
rpm-build |
0f2925 |
Buffer.contents b
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
No_more_input ->
|
|
rpm-build |
0f2925 |
if !cr then Buffer.add_char b '\r';
|
|
rpm-build |
0f2925 |
if Buffer.length b > 0 then
|
|
rpm-build |
0f2925 |
Buffer.contents b
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
raise No_more_input
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_ui16 i =
|
|
rpm-build |
0f2925 |
let ch1 = read_byte i in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte i in
|
|
rpm-build |
0f2925 |
ch1 lor (ch2 lsl 8)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i16 i =
|
|
rpm-build |
0f2925 |
let ch1 = read_byte i in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte i in
|
|
rpm-build |
0f2925 |
let n = ch1 lor (ch2 lsl 8) in
|
|
rpm-build |
0f2925 |
if ch2 land 128 <> 0 then
|
|
rpm-build |
0f2925 |
n - 65536
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let sign_bit_i32 = lnot 0x7FFF_FFFF
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_32 ~i31 ch =
|
|
rpm-build |
0f2925 |
let ch1 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch3 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch4 = read_byte ch in
|
|
rpm-build |
0f2925 |
if ch4 land 128 <> 0 then begin
|
|
rpm-build |
0f2925 |
if i31 && ch4 land 64 = 0 then raise (Overflow "read_i31");
|
|
rpm-build |
0f2925 |
ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor ((ch4 land 127) lsl 24) lor sign_bit_i32
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
if i31 && ch4 land 64 <> 0 then raise (Overflow "read_i31");
|
|
rpm-build |
0f2925 |
ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor (ch4 lsl 24)
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i31 ch = read_32 ~i31:true ch
|
|
rpm-build |
0f2925 |
let read_i32_as_int ch = read_32 ~i31:false ch
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i32 = read_i31
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_real_i32 ch =
|
|
rpm-build |
0f2925 |
let ch1 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch3 = read_byte ch in
|
|
rpm-build |
0f2925 |
let base = Int32.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
|
|
rpm-build |
0f2925 |
let big = Int32.shift_left (Int32.of_int (read_byte ch)) 24 in
|
|
rpm-build |
0f2925 |
Int32.logor base big
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i64 ch =
|
|
rpm-build |
0f2925 |
let ch1 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch3 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch4 = read_byte ch in
|
|
rpm-build |
0f2925 |
let base = Int64.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
|
|
rpm-build |
0f2925 |
let small = Int64.logor base (Int64.shift_left (Int64.of_int ch4) 24) in
|
|
rpm-build |
0f2925 |
let big = Int64.of_int32 (read_real_i32 ch) in
|
|
rpm-build |
0f2925 |
Int64.logor (Int64.shift_left big 32) small
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_float32 ch =
|
|
rpm-build |
0f2925 |
Int32.float_of_bits (read_real_i32 ch)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_double ch =
|
|
rpm-build |
0f2925 |
Int64.float_of_bits (read_i64 ch)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_byte o n =
|
|
rpm-build |
0f2925 |
(* doesn't test bounds of n in order to keep semantics of Pervasives.output_byte *)
|
|
rpm-build |
0f2925 |
write o (Char.unsafe_chr (n land 0xFF))
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_string o s =
|
|
rpm-build |
0f2925 |
nwrite_string o s;
|
|
rpm-build |
0f2925 |
write o '\000'
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_bytes o s =
|
|
rpm-build |
0f2925 |
nwrite o s;
|
|
rpm-build |
0f2925 |
write o '\000'
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_line o s =
|
|
rpm-build |
0f2925 |
nwrite_string o s;
|
|
rpm-build |
0f2925 |
write o '\n'
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_ui16 ch n =
|
|
rpm-build |
0f2925 |
if n < 0 || n > 0xFFFF then raise (Overflow "write_ui16");
|
|
rpm-build |
0f2925 |
write_byte ch n;
|
|
rpm-build |
0f2925 |
write_byte ch (n lsr 8)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i16 ch n =
|
|
rpm-build |
0f2925 |
if n < -0x8000 || n > 0x7FFF then raise (Overflow "write_i16");
|
|
rpm-build |
0f2925 |
if n < 0 then
|
|
rpm-build |
0f2925 |
write_ui16 ch (65536 + n)
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
write_ui16 ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_32 ch n =
|
|
rpm-build |
0f2925 |
write_byte ch n;
|
|
rpm-build |
0f2925 |
write_byte ch (n lsr 8);
|
|
rpm-build |
0f2925 |
write_byte ch (n lsr 16);
|
|
rpm-build |
0f2925 |
write_byte ch (n asr 24)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i31 ch n =
|
|
rpm-build |
0f2925 |
#ifndef WORD_SIZE_32
|
|
rpm-build |
0f2925 |
if n < -0x4000_0000 || n > 0x3FFF_FFFF then raise (Overflow "write_i31");
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
write_32 ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i32 ch n =
|
|
rpm-build |
0f2925 |
#ifndef WORD_SIZE_32
|
|
rpm-build |
0f2925 |
if n < -0x8000_0000 || n > 0x7FFF_FFFF then raise (Overflow "write_i32");
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
write_32 ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_real_i32 ch n =
|
|
rpm-build |
0f2925 |
let base = Int32.to_int n in
|
|
rpm-build |
0f2925 |
let big = Int32.to_int (Int32.shift_right_logical n 24) in
|
|
rpm-build |
0f2925 |
write_byte ch base;
|
|
rpm-build |
0f2925 |
write_byte ch (base lsr 8);
|
|
rpm-build |
0f2925 |
write_byte ch (base lsr 16);
|
|
rpm-build |
0f2925 |
write_byte ch big
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i64 ch n =
|
|
rpm-build |
0f2925 |
write_real_i32 ch (Int64.to_int32 n);
|
|
rpm-build |
0f2925 |
write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical n 32))
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_float32 ch f =
|
|
rpm-build |
0f2925 |
write_real_i32 ch (Int32.bits_of_float f)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_double ch f =
|
|
rpm-build |
0f2925 |
write_i64 ch (Int64.bits_of_float f)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* -------------------------------------------------------------- *)
|
|
rpm-build |
0f2925 |
(* Big Endians *)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
module BigEndian = struct
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_ui16 i =
|
|
rpm-build |
0f2925 |
let ch2 = read_byte i in
|
|
rpm-build |
0f2925 |
let ch1 = read_byte i in
|
|
rpm-build |
0f2925 |
ch1 lor (ch2 lsl 8)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i16 i =
|
|
rpm-build |
0f2925 |
let ch2 = read_byte i in
|
|
rpm-build |
0f2925 |
let ch1 = read_byte i in
|
|
rpm-build |
0f2925 |
let n = ch1 lor (ch2 lsl 8) in
|
|
rpm-build |
0f2925 |
if ch2 land 128 <> 0 then
|
|
rpm-build |
0f2925 |
n - 65536
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let sign_bit_i32 = lnot 0x7FFF_FFFF
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_32 ~i31 ch =
|
|
rpm-build |
0f2925 |
let ch4 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch3 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch1 = read_byte ch in
|
|
rpm-build |
0f2925 |
if ch4 land 128 <> 0 then begin
|
|
rpm-build |
0f2925 |
if i31 && ch4 land 64 = 0 then raise (Overflow "read_i31");
|
|
rpm-build |
0f2925 |
ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor ((ch4 land 127) lsl 24) lor sign_bit_i32
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
if i31 && ch4 land 64 <> 0 then raise (Overflow "read_i31");
|
|
rpm-build |
0f2925 |
ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor (ch4 lsl 24)
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i31 ch = read_32 ~i31:true ch
|
|
rpm-build |
0f2925 |
let read_i32_as_int ch = read_32 ~i31:false ch
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i32 = read_i31
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_real_i32 ch =
|
|
rpm-build |
0f2925 |
let big = Int32.shift_left (Int32.of_int (read_byte ch)) 24 in
|
|
rpm-build |
0f2925 |
let ch3 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch1 = read_byte ch in
|
|
rpm-build |
0f2925 |
let base = Int32.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
|
|
rpm-build |
0f2925 |
Int32.logor base big
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_i64 ch =
|
|
rpm-build |
0f2925 |
let big = Int64.of_int32 (read_real_i32 ch) in
|
|
rpm-build |
0f2925 |
let ch4 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch3 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch2 = read_byte ch in
|
|
rpm-build |
0f2925 |
let ch1 = read_byte ch in
|
|
rpm-build |
0f2925 |
let base = Int64.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
|
|
rpm-build |
0f2925 |
let small = Int64.logor base (Int64.shift_left (Int64.of_int ch4) 24) in
|
|
rpm-build |
0f2925 |
Int64.logor (Int64.shift_left big 32) small
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_float32 ch =
|
|
rpm-build |
0f2925 |
Int32.float_of_bits (read_real_i32 ch)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let read_double ch =
|
|
rpm-build |
0f2925 |
Int64.float_of_bits (read_i64 ch)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_ui16 ch n =
|
|
rpm-build |
0f2925 |
if n < 0 || n > 0xFFFF then raise (Overflow "write_ui16");
|
|
rpm-build |
0f2925 |
write_byte ch (n lsr 8);
|
|
rpm-build |
0f2925 |
write_byte ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i16 ch n =
|
|
rpm-build |
0f2925 |
if n < -0x8000 || n > 0x7FFF then raise (Overflow "write_i16");
|
|
rpm-build |
0f2925 |
if n < 0 then
|
|
rpm-build |
0f2925 |
write_ui16 ch (65536 + n)
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
write_ui16 ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_32 ch n =
|
|
rpm-build |
0f2925 |
write_byte ch (n asr 24);
|
|
rpm-build |
0f2925 |
write_byte ch (n lsr 16);
|
|
rpm-build |
0f2925 |
write_byte ch (n lsr 8);
|
|
rpm-build |
0f2925 |
write_byte ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i31 ch n =
|
|
rpm-build |
0f2925 |
#ifndef WORD_SIZE_32
|
|
rpm-build |
0f2925 |
if n < -0x4000_0000 || n > 0x3FFF_FFFF then raise (Overflow "write_i31");
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
write_32 ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i32 ch n =
|
|
rpm-build |
0f2925 |
#ifndef WORD_SIZE_32
|
|
rpm-build |
0f2925 |
if n < -0x8000_0000 || n > 0x7FFF_FFFF then raise (Overflow "write_i32");
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
write_32 ch n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_real_i32 ch n =
|
|
rpm-build |
0f2925 |
let base = Int32.to_int n in
|
|
rpm-build |
0f2925 |
let big = Int32.to_int (Int32.shift_right_logical n 24) in
|
|
rpm-build |
0f2925 |
write_byte ch big;
|
|
rpm-build |
0f2925 |
write_byte ch (base lsr 16);
|
|
rpm-build |
0f2925 |
write_byte ch (base lsr 8);
|
|
rpm-build |
0f2925 |
write_byte ch base
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_i64 ch n =
|
|
rpm-build |
0f2925 |
write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical n 32));
|
|
rpm-build |
0f2925 |
write_real_i32 ch (Int64.to_int32 n)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_float32 ch f =
|
|
rpm-build |
0f2925 |
write_real_i32 ch (Int32.bits_of_float f)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let write_double ch f =
|
|
rpm-build |
0f2925 |
write_i64 ch (Int64.bits_of_float f)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* -------------------------------------------------------------- *)
|
|
rpm-build |
0f2925 |
(* Bits API *)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type 'a bc = {
|
|
rpm-build |
0f2925 |
ch : 'a;
|
|
rpm-build |
0f2925 |
mutable nbits : int;
|
|
rpm-build |
0f2925 |
mutable bits : int;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type in_bits = input bc
|
|
rpm-build |
0f2925 |
type out_bits = unit output bc
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
exception Bits_error
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_bits ch =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
ch = ch;
|
|
rpm-build |
0f2925 |
nbits = 0;
|
|
rpm-build |
0f2925 |
bits = 0;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_bits ch =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
ch = cast_output ch;
|
|
rpm-build |
0f2925 |
nbits = 0;
|
|
rpm-build |
0f2925 |
bits = 0;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let rec read_bits b n =
|
|
rpm-build |
0f2925 |
if b.nbits >= n then begin
|
|
rpm-build |
0f2925 |
let c = b.nbits - n in
|
|
rpm-build |
0f2925 |
let k = (b.bits asr c) land ((1 lsl n) - 1) in
|
|
rpm-build |
0f2925 |
b.nbits <- c;
|
|
rpm-build |
0f2925 |
k
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
let k = read_byte b.ch in
|
|
rpm-build |
0f2925 |
if b.nbits >= 24 then begin
|
|
rpm-build |
0f2925 |
if n >= 31 then raise Bits_error;
|
|
rpm-build |
0f2925 |
let c = 8 + b.nbits - n in
|
|
rpm-build |
0f2925 |
let d = b.bits land ((1 lsl b.nbits) - 1) in
|
|
rpm-build |
0f2925 |
let d = (d lsl (8 - c)) lor (k lsr c) in
|
|
rpm-build |
0f2925 |
b.bits <- k;
|
|
rpm-build |
0f2925 |
b.nbits <- c;
|
|
rpm-build |
0f2925 |
d
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
b.bits <- (b.bits lsl 8) lor k;
|
|
rpm-build |
0f2925 |
b.nbits <- b.nbits + 8;
|
|
rpm-build |
0f2925 |
read_bits b n;
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let drop_bits b =
|
|
rpm-build |
0f2925 |
b.nbits <- 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let rec write_bits b ~nbits x =
|
|
rpm-build |
0f2925 |
let n = nbits in
|
|
rpm-build |
0f2925 |
if n + b.nbits >= 32 then begin
|
|
rpm-build |
0f2925 |
if n > 31 then raise Bits_error;
|
|
rpm-build |
0f2925 |
let n2 = 32 - b.nbits - 1 in
|
|
rpm-build |
0f2925 |
let n3 = n - n2 in
|
|
rpm-build |
0f2925 |
write_bits b ~nbits:n2 (x asr n3);
|
|
rpm-build |
0f2925 |
write_bits b ~nbits:n3 (x land ((1 lsl n3) - 1));
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
if n < 0 then raise Bits_error;
|
|
rpm-build |
0f2925 |
if (x < 0 || x > (1 lsl n - 1)) && n <> 31 then raise Bits_error;
|
|
rpm-build |
0f2925 |
b.bits <- (b.bits lsl n) lor x;
|
|
rpm-build |
0f2925 |
b.nbits <- b.nbits + n;
|
|
rpm-build |
0f2925 |
while b.nbits >= 8 do
|
|
rpm-build |
0f2925 |
b.nbits <- b.nbits - 8;
|
|
rpm-build |
0f2925 |
write_byte b.ch (b.bits asr b.nbits)
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let flush_bits b =
|
|
rpm-build |
0f2925 |
if b.nbits > 0 then write_bits b (8 - b.nbits) 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* -------------------------------------------------------------- *)
|
|
rpm-build |
0f2925 |
(* Generic IO *)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
class in_channel ch =
|
|
rpm-build |
0f2925 |
object
|
|
rpm-build |
0f2925 |
method input s pos len = input ch s pos len
|
|
rpm-build |
0f2925 |
method close_in() = close_in ch
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
class out_channel ch =
|
|
rpm-build |
0f2925 |
object
|
|
rpm-build |
0f2925 |
method output s pos len = output ch s pos len
|
|
rpm-build |
0f2925 |
method flush() = flush ch
|
|
rpm-build |
0f2925 |
method close_out() = ignore(close_out ch)
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
class in_chars ch =
|
|
rpm-build |
0f2925 |
object
|
|
rpm-build |
0f2925 |
method get() = try read ch with No_more_input -> raise End_of_file
|
|
rpm-build |
0f2925 |
method close_in() = close_in ch
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
class out_chars ch =
|
|
rpm-build |
0f2925 |
object
|
|
rpm-build |
0f2925 |
method put t = write ch t
|
|
rpm-build |
0f2925 |
method flush() = flush ch
|
|
rpm-build |
0f2925 |
method close_out() = ignore(close_out ch)
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let from_in_channel ch =
|
|
rpm-build |
0f2925 |
let cbuf = Bytes.create 1 in
|
|
rpm-build |
0f2925 |
let read() =
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
if ch#input cbuf 0 1 = 0 then raise Sys_blocked_io;
|
|
rpm-build |
0f2925 |
Bytes.unsafe_get cbuf 0
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
End_of_file -> raise No_more_input
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let input s p l =
|
|
rpm-build |
0f2925 |
ch#input s p l
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
create_in
|
|
rpm-build |
0f2925 |
~read
|
|
rpm-build |
0f2925 |
~input
|
|
rpm-build |
0f2925 |
~close:ch#close_in
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let from_out_channel ch =
|
|
rpm-build |
0f2925 |
let cbuf = Bytes.create 1 in
|
|
rpm-build |
0f2925 |
let write c =
|
|
rpm-build |
0f2925 |
Bytes.unsafe_set cbuf 0 c;
|
|
rpm-build |
0f2925 |
if ch#output cbuf 0 1 = 0 then raise Sys_blocked_io;
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let output s p l =
|
|
rpm-build |
0f2925 |
ch#output s p l
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
create_out
|
|
rpm-build |
0f2925 |
~write
|
|
rpm-build |
0f2925 |
~output
|
|
rpm-build |
0f2925 |
~flush:ch#flush
|
|
rpm-build |
0f2925 |
~close:ch#close_out
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let from_in_chars ch =
|
|
rpm-build |
0f2925 |
let input s p l =
|
|
rpm-build |
0f2925 |
let i = ref 0 in
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
while !i < l do
|
|
rpm-build |
0f2925 |
Bytes.unsafe_set s (p + !i) (ch#get());
|
|
rpm-build |
0f2925 |
incr i
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
l
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
End_of_file when !i > 0 ->
|
|
rpm-build |
0f2925 |
!i
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
create_in
|
|
rpm-build |
0f2925 |
~read:ch#get
|
|
rpm-build |
0f2925 |
~input
|
|
rpm-build |
0f2925 |
~close:ch#close_in
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let from_out_chars ch =
|
|
rpm-build |
0f2925 |
let output s p l =
|
|
rpm-build |
0f2925 |
for i = p to p + l - 1 do
|
|
rpm-build |
0f2925 |
ch#put (Bytes.unsafe_get s i)
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
l
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
create_out
|
|
rpm-build |
0f2925 |
~write:ch#put
|
|
rpm-build |
0f2925 |
~output
|
|
rpm-build |
0f2925 |
~flush:ch#flush
|
|
rpm-build |
0f2925 |
~close:ch#close_out
|