mldonkey-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Mldonkey-commits] mldonkey config/Makefile.in distrib/ChangeLog s...


From: mldonkey-commits
Subject: [Mldonkey-commits] mldonkey config/Makefile.in distrib/ChangeLog s...
Date: Sun, 07 Nov 2010 15:01:41 +0000

CVSROOT:        /sources/mldonkey
Module name:    mldonkey
Changes by:     spiralvoice <spiralvoice>       10/11/07 15:01:41

Modified files:
        config         : Makefile.in 
        distrib        : ChangeLog 
        src/utils/cdk  : gzip.ml gzip.mli tar.mlcpp unix2.ml 
        src/utils/net  : http_client.ml http_client.mli 
Added files:
        src/utils/extlib: IO.ml IO.mli 

Log message:
        patch #6012

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/mldonkey/config/Makefile.in?cvsroot=mldonkey&r1=1.196&r2=1.197
http://cvs.savannah.gnu.org/viewcvs/mldonkey/distrib/ChangeLog?cvsroot=mldonkey&r1=1.1498&r2=1.1499
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/cdk/gzip.ml?cvsroot=mldonkey&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/cdk/gzip.mli?cvsroot=mldonkey&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/cdk/tar.mlcpp?cvsroot=mldonkey&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/cdk/unix2.ml?cvsroot=mldonkey&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/extlib/IO.ml?cvsroot=mldonkey&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/extlib/IO.mli?cvsroot=mldonkey&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/net/http_client.ml?cvsroot=mldonkey&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/mldonkey/src/utils/net/http_client.mli?cvsroot=mldonkey&r1=1.11&r2=1.12

Patches:
Index: config/Makefile.in
===================================================================
RCS file: /sources/mldonkey/mldonkey/config/Makefile.in,v
retrieving revision 1.196
retrieving revision 1.197
diff -u -b -r1.196 -r1.197
--- config/Makefile.in  1 Nov 2010 17:19:23 -0000       1.196
+++ config/Makefile.in  7 Nov 2010 15:01:39 -0000       1.197
@@ -67,6 +67,7 @@
 endif
 
 
+EXTLIB=src/utils/extlib
 CDK=src/utils/cdk
 BITSTRING=src/utils/bitstring
 LIB=src/utils/lib
@@ -89,7 +90,7 @@
 SRC_DIRECTCONNECT=src/networks/direct_connect
 SRC_FILETP=src/networks/fileTP
 
-SUBDIRS=$(CDK) $(BITSTRING) $(LIB) $(RSS) $(XML) $(NET) tools \
+SUBDIRS=$(EXTLIB) $(CDK) $(BITSTRING) $(LIB) $(RSS) $(XML) $(NET) tools \
    $(COMMON) $(DRIVER) $(MP3) src/config/$(OS_FILES)
 
 INCLUDES += $(foreach file, $(SUBDIRS), -I $(file)) -I +camlp4
@@ -155,6 +156,8 @@
   $(CDK)/unix2.ml $(CDK)/file.ml \
   $(CDK)/heap_c.c $(CDK)/array2.ml
   
+EXTLIB_SRCS += $(EXTLIB)/IO.ml
+
 ifneq ("$(PTHREAD_CFLAGS)" , "")
   CFLAGS += $(PTHREAD_CFLAGS)
   LIBS_flags += -ccopt "$(PTHREAD_CFLAGS)"
@@ -508,33 +511,33 @@
 
 
 OBSERVER_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
   $(COMMON_SRCS) $(COMMON_CLIENT_SRCS) $(DONKEY_SRCS) \
   tools/observer.ml
 
 MLD_HASH_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
   tools/mld_hash.ml
 
 OCAMLPP_SRCS = \
   tools/ocamlpp.ml4
 
 COPYSOURCES_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) tools/copysources.ml
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) tools/copysources.ml
 
 SUBCONV_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) tools/subconv.ml
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) tools/subconv.ml
 
 MLSPLIT_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) tools/mlsplit.ml
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) tools/mlsplit.ml
 
 MAKE_TORRENT_SRCS = \
-  $(MAGIC_SRCS) $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
+  $(MAGIC_SRCS) $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) 
$(MP3TAG_SRCS) \
   $(COMMON_SRCS) $(COMMON_CLIENT_SRCS) $(BITSTRING_SRCS) $(BITTORRENT_SRCS) \
   tools/make_torrent.ml
 
 GET_RANGE_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS) \
   tools/get_range.ml
 
 ifeq ("$(OPENFT)" , "yes")
@@ -585,18 +588,18 @@
 BITSTRING_CMA=bitstring.cma
 endif
 MLNET_SRCS+= $(MAIN_SRCS)
-MLNET_CMXA=$(CDK_CMXA) $(BITSTRING_CMXA) magic.cmxa common.cmxa client.cmxa 
core.cmxa driver.cmxa
+MLNET_CMXA=extlib.cmxa $(CDK_CMXA) $(BITSTRING_CMXA) magic.cmxa common.cmxa 
client.cmxa core.cmxa driver.cmxa
 
 TESTS_CMXA=$(CDK_CMXA) magic.cmxa common.cmxa client.cmxa core.cmxa
 TESTS_SRCS=tools/tests.ml
 
 ifeq ("$(GUI)", "newgui2")
 mlnet+gui_CMXA= \
-  $(BITSTRING_CMXA) magic.cmxa cdk.cmxa common.cmxa client.cmxa core.cmxa 
driver.cmxa \
+  $(BITSTRING_CMXA) magic.cmxa extlib.cmxa cdk.cmxa common.cmxa client.cmxa 
core.cmxa driver.cmxa \
   icons.cmxa guibase.cmxa gui.cmxa
 else
 mlnet+gui_CMXA= \
-  $(BITSTRING_CMXA) magic.cmxa cdk.cmxa common.cmxa client.cmxa core.cmxa 
driver.cmxa \
+  $(BITSTRING_CMXA) magic.cmxa extlib.cmxa cdk.cmxa common.cmxa client.cmxa 
core.cmxa driver.cmxa \
   gmisc.cmxa icons.cmxa guibase.cmxa gui.cmxa
 endif
 
@@ -610,8 +613,7 @@
 #######################################################################
 
 
-TESTRSS_SRCS= \
-  $(CDK_SRCS) $(LIB_SRCS) tools/testrss.ml
+TESTRSS_SRCS= $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) tools/testrss.ml
 
 
 #######################################################################
@@ -658,7 +660,7 @@
   endif
 
 SVG_CONVERTER_SRCS = \
-  $(CDK_SRCS) $(LIB_SRCS) tools/svg_converter.ml
+  $(EXTLIB_SRCS) $(CDK_SRCS) $(LIB_SRCS) tools/svg_converter.ml
 
 CURSES_LIBS_byte=-cclib -lncurses
 CURSES_LIBS_opt=-cclib -lncurses
@@ -1080,25 +1082,25 @@
 GUI_SRCS= $($(GUI_CODE)_SRCS)
 
 ifeq ("$(GUI)", "newgui2")
-  MLDONKEYGUI_CMXA= cdk.cmxa common.cmxa icons.cmxa guibase.cmxa gui.cmxa
+  MLDONKEYGUI_CMXA= extlib.cmxa cdk.cmxa common.cmxa icons.cmxa guibase.cmxa 
gui.cmxa
 else
-  MLDONKEYGUI_CMXA= cdk.cmxa gmisc.cmxa common.cmxa icons.cmxa guibase.cmxa 
gui.cmxa
+  MLDONKEYGUI_CMXA= extlib.cmxa cdk.cmxa gmisc.cmxa common.cmxa icons.cmxa 
guibase.cmxa gui.cmxa
 endif
 
 MLDONKEYGUI_SRCS= $(MAIN_SRCS)
 
 ifeq ("$(GUI)", "newgui2")
-  STARTER_CMXA=cdk.cmxa common.cmxa icons.cmxa guibase.cmxa
+  STARTER_CMXA=extlib.cmxa cdk.cmxa common.cmxa icons.cmxa guibase.cmxa
   STARTER_SRCS= $(SRC_GUI)/guiStarter.ml
 else
-  STARTER_CMXA=cdk.cmxa
+  STARTER_CMXA=extlib.cmxa cdk.cmxa
   STARTER_SRCS= $(SRC_GUI)/gui_starter.ml
 endif
 
 ifeq ("$(GUI)", "newgui2")
-  INSTALLER_CMXA= cdk.cmxa common.cmxa icons.cmxa guibase.cmxa
+  INSTALLER_CMXA= extlib.cmxa cdk.cmxa common.cmxa icons.cmxa guibase.cmxa
 else
-  INSTALLER_CMXA= cdk.cmxa gmisc.cmxa common.cmxa icons.cmxa guibase.cmxa
+  INSTALLER_CMXA= extlib.cmxa cdk.cmxa gmisc.cmxa common.cmxa icons.cmxa 
guibase.cmxa
 endif
 
 ifeq ("$(GUI)", "newgui2")
@@ -1109,7 +1111,7 @@
     $(SRC_GUI)/gui_installer_base.zog $(SRC_GUI)/gui_installer.ml
 endif
 
-MLPROGRESS_CMXA= cdk.cmxa gmisc.cmxa common.cmxa icons.cmxa guibase.cmxa
+MLPROGRESS_CMXA= extlib.cmxa cdk.cmxa gmisc.cmxa common.cmxa icons.cmxa 
guibase.cmxa
 
 MLPROGRESS_SRCS = \
   $(PROGRESS_SRCS) $(MAIN_SRCS)
@@ -1127,7 +1129,7 @@
 runtop: top
        ./mldonkeytop $(INCLUDES)
 
-TOP_CMXA+=$(BITSTRING_CMA) cdk.cmxa magic.cmxa common.cmxa client.cmxa 
core.cmxa
+TOP_CMXA+=$(BITSTRING_CMA) extlib.cmxa cdk.cmxa magic.cmxa common.cmxa 
client.cmxa core.cmxa
 TOP_SRCS= 
 
 define([[EXPAND_LIB]],[[
@@ -1180,18 +1182,18 @@
 endif
 endif
 
-$1_CMXA+= cdk.cmxa magic.cmxa common.cmxa client.cmxa $1.cmxa driver.cmxa
+$1_CMXA+= extlib.cmxa cdk.cmxa magic.cmxa common.cmxa client.cmxa $1.cmxa 
driver.cmxa
 
 $1_SRCS+= $(MAIN_SRCS)
 
 EXPAND_LIB($2,$1)
 
 ifeq ("$(GUI)", "newgui2")
-$1+gui_CMXA+=cdk.cmxa \
+$1+gui_CMXA+=extlib.cmxa cdk.cmxa \
    magic.cmxa common.cmxa client.cmxa $1.cmxa driver.cmxa \
    icons.cmxa guibase.cmxa gui.cmxa
 else
-$1+gui_CMXA+=cdk.cmxa \
+$1+gui_CMXA+=extlib.cmxa cdk.cmxa \
    magic.cmxa common.cmxa client.cmxa $1.cmxa driver.cmxa \
    gmisc.cmxa icons.cmxa guibase.cmxa gui.cmxa
 endif
@@ -1210,6 +1212,7 @@
 EXPAND_DRIVER(mldonkey,DONKEY,donkey)
 EXPAND_DRIVER(mlslsk,SOULSEEK,soulseek)
 
+libextlib_SRCS= $(EXTLIB_SRCS)
 libcdk_SRCS=  $(CDK_SRCS) $(LIB_SRCS) $(NET_SRCS) $(MP3TAG_SRCS)
 libmagic_SRCS= $(MAGIC_SRCS)
 libbitstring_SRCS= $(BITSTRING_SRCS)
@@ -1225,6 +1228,7 @@
 libgui3_SRCS=   $(GUI3_SRCS)
 libicons_SRCS= $(ALL_ICONS_SRCS)
 
+EXPAND_LIB(libextlib,extlib)
 EXPAND_LIB(libicons,icons)
 EXPAND_LIB(libcdk,cdk)
 EXPAND_LIB(libmagic,magic)

Index: distrib/ChangeLog
===================================================================
RCS file: /sources/mldonkey/mldonkey/distrib/ChangeLog,v
retrieving revision 1.1498
retrieving revision 1.1499
diff -u -b -r1.1498 -r1.1499
--- distrib/ChangeLog   3 Nov 2010 06:07:39 -0000       1.1498
+++ distrib/ChangeLog   7 Nov 2010 15:01:40 -0000       1.1499
@@ -14,6 +14,9 @@
 ChangeLog
 =========
 
+2010/11/07
+6012: http_client: Support gzip accept-encoding + content-encoding (ygrek)
+
 2010/11/03
 7372: GTK2 GUI: Compile with lablgtk-2.14.2 by default
 

Index: src/utils/cdk/gzip.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/gzip.ml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- src/utils/cdk/gzip.ml       5 Mar 2006 10:41:06 -0000       1.2
+++ src/utils/cdk/gzip.ml       7 Nov 2010 15:01:40 -0000       1.3
@@ -6,62 +6,64 @@
 (*                                                                     *)
 (*  Copyright 2001 Institut National de Recherche en Informatique et   *)
 (*  en Automatique.  All rights reserved.  This file is distributed    *)
-(*  under the terms of the GNU Library General Public License.         *)
+(*  under the terms of the GNU Library General Public License, with    *)
+(*  the special exception on linking described in file LICENSE.        *)
 (*                                                                     *)
 (***********************************************************************)
 
-(* $Id: gzip.ml,v 1.2 2006/03/05 10:41:06 spiralvoice Exp $ *)
+(* Origin: $ Id: gzip.ml,v 1.2 2006/04/04 08:29:07 xleroy Exp $ *)
 
-(* Module [Gzip]: reading and writing to/from [gzip] compressed files *)
+(* Module [Gzip]: reading and writing to/from [gzip] compressed streams *)
 
 exception Error of string
 
 let buffer_size = 1024
 
 type in_channel =
-  { in_chan: Pervasives.in_channel;
+  { in_chan: IO.input;
     in_buffer: string;
     mutable in_pos: int;
     mutable in_avail: int;
     mutable in_eof: bool;
     in_stream: Zlib.stream;
     mutable in_size: int32;
-    mutable in_crc: int32 }
+    mutable in_crc: int32;
+    char_buffer: string }
 
-let open_in_chan ic =
+let open_in ic =
   (* Superficial parsing of header *)
   begin try
-    let id1 = input_byte ic in
-    let id2 = input_byte ic in
+    let id1 = IO.read_byte ic in
+    let id2 = IO.read_byte ic in
     if id1 <> 0x1F || id2 <> 0x8B then 
       raise(Error("bad magic number, not a gzip file"));
-    let cm = input_byte ic in
+    let cm = IO.read_byte ic in
     if cm <> 8 then
       raise(Error("unknown compression method"));
-    let flags = input_byte ic in
+    let flags = IO.read_byte ic in
     if flags land 0xE0 <> 0 then
       raise(Error("bad flags, not a gzip file"));
-    for i = 1 to 6 do ignore(input_byte ic) done;
+    for i = 1 to 6 do ignore(IO.read_byte ic) done;
     if flags land 0x04 <> 0 then begin
       (* Skip extra data *)
-      let len1 = input_byte ic in
-      let len2 = input_byte ic in
-      for i = 1 to len1 + len2 lsl 8 do ignore(input_byte ic) done
+      let len1 = IO.read_byte ic in
+      let len2 = IO.read_byte ic in
+      for i = 1 to len1 + len2 lsl 8 do ignore(IO.read_byte ic) done
     end;
     if flags land 0x08 <> 0 then begin
       (* Skip original file name *)
-      while input_byte ic <> 0 do () done
+      while IO.read_byte ic <> 0 do () done
     end;
     if flags land 0x10 <> 0 then begin
       (* Skip comment *)
-      while input_byte ic <> 0 do () done
+      while IO.read_byte ic <> 0 do () done
     end;
     if flags land 0x02 <> 0 then begin
       (* Skip header CRC *)
-      ignore(input_byte ic); ignore(input_byte ic)
+      ignore(IO.read_byte ic); ignore(IO.read_byte ic)
     end
-  with End_of_file ->
-    raise(Error("premature end of file, not a gzip file"))
+  with IO.No_more_input ->
+    raise(Error("premature end of input, not a gzip stream"))
   end;
   { in_chan = ic;
     in_buffer = String.create buffer_size;
@@ -70,19 +72,19 @@
     in_eof = false;
     in_stream = Zlib.inflate_init false;
     in_size = Int32.zero;
-    in_crc = Int32.zero }
+    in_crc = Int32.zero;
+    char_buffer = String.create 1 }
 
-let open_in filename =
+let open_in_file filename =
   let ic = Pervasives.open_in_bin filename in
   try
-    open_in_chan ic
+    open_in (IO.input_channel ic)
   with e -> Pervasives.close_in ic; raise e
 
 let read_byte iz =
   if iz.in_avail = 0 then begin
-    let n = Pervasives.input iz.in_chan iz.in_buffer 0
+    let n = IO.input iz.in_chan iz.in_buffer 0
                              (String.length iz.in_buffer) in
-    if n = 0 then raise End_of_file;
     iz.in_pos <- 0;
     iz.in_avail <- n
   end;
@@ -103,12 +105,13 @@
 
 let rec input iz buf pos len =
   if pos < 0 || len < 0 || pos + len > String.length buf then
-    invalid_arg "Gzip.input";
+    invalid_arg "Gzip_stream.input";
   if iz.in_eof then 0 else begin
     if iz.in_avail = 0 then begin
-      let n = Pervasives.input iz.in_chan iz.in_buffer 0
-                               (String.length iz.in_buffer) in
-      if n = 0 then raise(Error("truncated file"));
+      let n = try IO.input iz.in_chan iz.in_buffer 0
+                               (String.length iz.in_buffer) 
+              with IO.No_more_input -> raise(Error("truncated stream"))
+      in
       iz.in_pos <- 0;
       iz.in_avail <- n
     end;
@@ -132,8 +135,8 @@
           raise(Error("size mismatch, data corrupted"));
         iz.in_eof <- true;
         used_out
-      with End_of_file ->
-        raise(Error("truncated file"))
+      with IO.No_more_input ->
+        raise(Error("truncated stream"))
     end
     else if used_out = 0 then
       input iz buf pos len
@@ -148,10 +151,8 @@
     really_input iz buf (pos + n) (len - n)
   end
 
-let char_buffer = String.create 1
-
 let input_char iz =
-  if input iz char_buffer 0 1 = 0 then raise End_of_file else char_buffer.[0]
+  if input iz iz.char_buffer 0 1 = 0 then raise End_of_file else 
iz.char_buffer.[0]
 
 let input_byte iz =
   Char.code (input_char iz)
@@ -162,44 +163,50 @@
 
 let close_in iz =
   dispose iz;
-  Pervasives.close_in iz.in_chan
+  IO.close_in iz.in_chan
 
-type out_channel =
-  { out_chan: Pervasives.out_channel;
+type 'a out_channel =
+  { out_chan: 'a IO.output;
     out_buffer: string;
     mutable out_pos: int;
     mutable out_avail: int;
     out_stream: Zlib.stream;
     mutable out_size: int32;
-    mutable out_crc: int32 }
+    mutable out_crc: int32;
+    char_buffer: string }
 
-let open_out_chan ?(level = 6) oc =
-  if level < 1 || level > 9 then invalid_arg "Gzip.open_out: bad level";
+let open_out ?(level = 6) oc =
+  if level < 1 || level > 9 then invalid_arg "Gzip_stream.open_output: bad 
level";
   (* Write minimal header *)
-  output_byte oc 0x1F;                  (* ID1 *)
-  output_byte oc 0x8B;                  (* ID2 *)
-  output_byte oc 8;                     (* compression method *)
-  output_byte oc 0;                     (* flags *)
-  for i = 1 to 4 do output_byte oc 0 done; (* mtime *)
-  output_byte oc 0;                     (* xflags *)
-  output_byte oc 0xFF;                  (* OS (unknown) *)
+  IO.write_byte oc 0x1F;                  (* ID1 *)
+  IO.write_byte oc 0x8B;                  (* ID2 *)
+  IO.write_byte oc 8;                     (* compression method *)
+  IO.write_byte oc 0;                     (* flags *)
+  for i = 1 to 4 do IO.write_byte oc 0 done; (* mtime *)
+  IO.write_byte oc 0;                     (* xflags *)
+  IO.write_byte oc 0xFF;                  (* OS (unknown) *)
   { out_chan = oc;
     out_buffer = String.create buffer_size;
     out_pos = 0;
     out_avail = buffer_size;
     out_stream = Zlib.deflate_init level false;
     out_size = Int32.zero;
-    out_crc = Int32.zero }
+    out_crc = Int32.zero;
+    char_buffer = String.create 1 }
 
-let open_out ?(level = 6) filename =
-  open_out_chan ~level (Pervasives.open_out_bin filename)
+let open_out_file ?level filename =
+  let oc = Pervasives.open_out_bin filename in
+  try
+    open_out ?level (IO.output_channel oc)
+  with
+    exn -> Pervasives.close_out oc; raise exn
 
 let rec output oz buf pos len =
   if pos < 0 || len < 0 || pos + len > String.length buf then
-    invalid_arg "Gzip.output";
+    invalid_arg "Gzip_stream.output";
   (* If output buffer is full, flush it *)
   if oz.out_avail = 0 then begin
-    Pervasives.output oz.out_chan oz.out_buffer 0 oz.out_pos;
+    ignore (IO.really_output oz.out_chan oz.out_buffer 0 oz.out_pos);
     oz.out_pos <- 0;
     oz.out_avail <- String.length oz.out_buffer
   end;
@@ -217,8 +224,8 @@
   if used_in < len then output oz buf (pos + used_in) (len - used_in)
 
 let output_char oz c =
-  char_buffer.[0] <- c;
-  output oz char_buffer 0 1
+  oz.char_buffer.[0] <- c;
+  output oz oz.char_buffer 0 1
 
 let output_byte oz b =
   output_char oz (Char.unsafe_chr b)
@@ -226,7 +233,7 @@
 let write_int32 oc n =
   let r = ref n in
   for i = 1 to 4 do
-    Pervasives.output_byte oc (Int32.to_int !r);
+    IO.write_byte oc (Int32.to_int !r);
     r := Int32.shift_right_logical !r 8
   done
 
@@ -234,7 +241,7 @@
   let rec do_flush () =
     (* If output buffer is full, flush it *)
     if oz.out_avail = 0 then begin
-      Pervasives.output oz.out_chan oz.out_buffer 0 oz.out_pos;
+      ignore (IO.really_output oz.out_chan oz.out_buffer 0 oz.out_pos);
       oz.out_pos <- 0;
       oz.out_avail <- String.length oz.out_buffer
     end;
@@ -248,7 +255,7 @@
   do_flush();
   (* Final data flush *)
   if oz.out_pos > 0 then
-    Pervasives.output oz.out_chan oz.out_buffer 0 oz.out_pos;
+    ignore (IO.really_output oz.out_chan oz.out_buffer 0 oz.out_pos);
   (* Write CRC and size *)
   write_int32 oz.out_chan oz.out_crc;
   write_int32 oz.out_chan oz.out_size;
@@ -257,5 +264,23 @@
 
 let close_out oz =
   flush oz;
-  Pervasives.close_out oz.out_chan
+  IO.close_out oz.out_chan
+
+let input_io io =
+  let iz = open_in io in
+  IO.create_in 
+    ~read:(fun () -> input_char iz)
+    ~input:(input iz)
+    ~close:(fun () -> close_in iz)
+
+let output_io io =
+  let oz = open_out io in
+  IO.create_out
+    ~write:(output_char oz)
+    ~output:(fun s o l -> output oz s o l; l)
+    ~flush:(fun () -> IO.flush io)
+    ~close:(fun () -> close_out oz)
+
+let input_channel ch = input_io (IO.input_channel ch)
+let output_channel ch = output_io (IO.output_channel ch)
 

Index: src/utils/cdk/gzip.mli
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/gzip.mli,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- src/utils/cdk/gzip.mli      23 Jul 2005 14:19:48 -0000      1.1
+++ src/utils/cdk/gzip.mli      7 Nov 2010 15:01:40 -0000       1.2
@@ -10,7 +10,7 @@
 (*                                                                     *)
 (***********************************************************************)
 
-(* $Id: gzip.mli,v 1.1 2005/07/23 14:19:48 spiralvoice Exp $ *)
+(* $Id: gzip.mli,v 1.2 2010/11/07 15:01:40 spiralvoice Exp $ *)
 
 (* Module [Gzip]: reading and writing to/from [gzip] compressed files *)
 
@@ -22,12 +22,12 @@
 type in_channel
         (* Abstract type representing a channel opened for reading
            from a compressed file. *)
-val open_in: string -> in_channel
-        (* Open a compressed file for reading.  The argument is the file
-           name. *)
-val open_in_chan: Pervasives.in_channel -> in_channel
+val open_in: IO.input -> in_channel
         (* Open a compressed file for reading.  The argument is a
            regular file channel already opened on the compressed file. *)
+val open_in_file: string -> in_channel
+        (* Open a compressed file for reading.  The argument is the file
+           name. *)
 val input_char: in_channel -> char
         (* Uncompress one character from the given channel, and return it.
            Raise [End_of_file] if no more compressed data is available. *)
@@ -73,10 +73,10 @@
 
 (*** Writing to compressed files *)
 
-type out_channel
+type 'a out_channel
         (* Abstract type representing a channel opened for writing
            to a compressed file. *)
-val open_out: ?level:int -> string -> out_channel
+val open_out_file: ?level:int -> string -> unit out_channel
         (* Open a compressed file for writing.  The argument is the file
            name.  The file is created if it does not exist, or
            truncated to zero length if it exists. 
@@ -85,28 +85,28 @@
            (but fastest) compression and 9 being the strongest
            (but slowest) compression.  The default level is 6
            (medium compression). *)
-val open_out_chan: ?level:int -> Pervasives.out_channel -> out_channel
+val open_out: ?level:int -> 'a IO.output -> 'a out_channel
         (* Open a compressed file for writing.  The argument is a
            regular file channel already opened on the compressed file.
            The optional [level] argument sets the compression level
            as documented for [Gzip.open_out]. *)
-val output_char: out_channel -> char -> unit
+val output_char: 'a out_channel -> char -> unit
         (* Output one character to the given compressed channel. *)
-val output_byte: out_channel -> int -> unit
+val output_byte: 'a out_channel -> int -> unit
         (* Same as [Gzip.output_char], but the output character is given
            by its code.  The given integer is taken modulo 256. *)
-val output: out_channel -> string -> int -> int -> unit
+val output: 'a out_channel -> string -> int -> int -> unit
         (* [output oc buf pos len] compresses and writes [len] characters
            from string [buf], starting at offset [pos], and writes the
            compressed data to the channel [oc].
            Raise [Invalid_argument "Gzip.output"] if
            [pos] and [len] do not designate a valid substring of [buf]. *)
-val close_out: out_channel -> unit
+val close_out: 'a out_channel -> 'a
         (* Close the given output channel.  If the channel was created with
            [Gzip.open_out_chan], the underlying regular file channel
            (of type [Pervasives.out_channel]) is also closed.
            Do not apply any of the functions above to a closed channel. *)
-val flush: out_channel -> unit
+val flush: 'a out_channel -> unit
         (* Same as [Gzip.close_out], but do not close the underlying
            regular file channel (of type [Pervasives.out_channel]);
            just flush all pending compressed data and
@@ -119,3 +119,7 @@
 exception Error of string
         (* Exception raised by the functions above to signal errors during
            compression or decompression, or ill-formed input files. *)
+
+val input_io : IO.input -> IO.input
+val output_io : 'a IO.output -> 'a IO.output
+

Index: src/utils/cdk/tar.mlcpp
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/tar.mlcpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- src/utils/cdk/tar.mlcpp     6 Feb 2006 12:54:58 -0000       1.2
+++ src/utils/cdk/tar.mlcpp     7 Nov 2010 15:01:40 -0000       1.3
@@ -75,7 +75,7 @@
 let open_inchan comp chan = 
   match comp with
     | `Plain -> new in_chan chan
-    | `Gzip -> new gzin_chan (Gzip.open_in_chan chan)
+    | `Gzip -> new gzin_chan (Gzip.open_in (IO.input_channel chan))
     | `Bzip2 -> 
 #ifdef USE_BZIP2
        new bzin_chan (Bzip2.open_in_chan chan)
@@ -286,7 +286,7 @@
 class gzout_chan o = object
   method output str pos len = Gzip.output o str pos len
   method flush () = Gzip.flush o
-  method close () = Gzip.close_out o
+  method close () = (Gzip.close_out o : unit)
 end
 
 #ifdef USE_BZIP2
@@ -301,7 +301,7 @@
 let open_outchan comp chan = 
   match comp with
     | `Plain -> new out_chan chan
-    | `Gzip -> new gzout_chan (Gzip.open_out_chan chan)
+    | `Gzip -> new gzout_chan (Gzip.open_out (IO.output_channel chan))
     | `Bzip2 -> 
 #ifdef USE_BZIP2
        new bzout_chan (Bzip2.open_out_chan chan)

Index: src/utils/cdk/unix2.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/cdk/unix2.ml,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- src/utils/cdk/unix2.ml      23 Oct 2010 18:21:13 -0000      1.38
+++ src/utils/cdk/unix2.ml      7 Nov 2010 15:01:40 -0000       1.39
@@ -52,9 +52,9 @@
 let tryopen_write_tar ?compress fn f = 
   tryopen (Tar.open_out ?compress) Tar.close_out fn f
 let tryopen_read_gzip fn f = 
-  tryopen Gzip.open_in Gzip.close_in fn f
+  tryopen Gzip.open_in_file Gzip.close_in fn f
 let tryopen_write_gzip ?level fn f = 
-  tryopen (Gzip.open_out ?level) Gzip.close_out fn f
+  tryopen (Gzip.open_out_file ?level) Gzip.close_out fn f
 let tryopen_umask temp_umask f =
   (* Unix.umask is not implemented on MinGW *)
   let safe_umask umask = try Unix.umask umask with Invalid_argument _ -> 0 in

Index: src/utils/net/http_client.ml
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/net/http_client.ml,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- src/utils/net/http_client.ml        8 Aug 2010 18:37:41 -0000       1.43
+++ src/utils/net/http_client.ml        7 Nov 2010 15:01:40 -0000       1.44
@@ -46,6 +46,7 @@
     req_accept : string;
     req_proxy : (string * int * (string * string) option) option; (* 
(host,port,(login,password)) *)
     mutable req_url : url;
+    mutable req_gzip : bool;
     mutable req_save_to_file_time : float;
     req_request : http_request;
     req_referer : Url.url option;
@@ -68,6 +69,7 @@
     req_referer = None;
     req_save_to_file_time = 0.;
     req_request = GET;
+    req_gzip = false;
     req_proxy = None;
     req_headers = [];
     req_user_agent = "Wget 1.4";
@@ -103,6 +105,7 @@
   List.iter (fun (a,b) ->
       Printf.bprintf res "%s: %s\r\n" a b
   ) r.req_headers;
+  Printf.bprintf res "Accept-Encoding: gzip\r\n";
   Printf.bprintf res "User-Agent: %s\r\n" r.req_user_agent;
   Printf.bprintf res "Accept: %s\r\n" r.req_accept;
   Printf.bprintf res "Connection: close\r\n";
@@ -274,9 +277,15 @@
         ok := true;
         let content_length = ref (-1L) in
         List.iter (fun (name, content) ->
-            if String.lowercase name = "content-length" then
-            try content_length := Int64.of_string content
-            with _ -> lprintf_nl "bad content length [%s]" content;
+            match String.lowercase name with
+            | "content-length" ->
+                (try
+                  content_length := Int64.of_string content
+                with _ ->
+                  lprintf_nl "bad content length [%s]" content)
+            | "content-encoding" ->
+                if String.lowercase content = "gzip" then r.req_gzip <- true
+            | _ -> ()
         ) headers;
         let location = "Location", Url.to_string old_url in
         let content_handler = content_handler !content_length 
(location::headers) in
@@ -367,6 +376,18 @@
   in
   get_url 0 r
   
+(** Copy all data from [input] to [output] *)
+let io_copy input output =
+  try
+    let size = 16 * 1024 in
+    let s = String.create size in
+    while true do
+      let n = IO.input input s 0 size in
+      if n = 0 then raise IO.No_more_input;
+      ignore (IO.really_output output s 0 n)
+    done
+  with IO.No_more_input -> ()
+
 let wget r f = 
   
   let file_buf = Buffer.create 1000 in
@@ -413,6 +434,19 @@
 
       let filename = Filename.concat webinfos_dir base in
       if !verbose then lprintf_nl "Filename: %s" filename;
+      if r.req_gzip then
+      begin
+        try
+          Unix2.tryopen_write_bin filename begin fun oc ->
+            let gz = Gzip.input_io (IO.input_string s) in
+            io_copy gz (IO.output_channel oc)
+          end
+        with e ->
+          lprintf_nl "Exception %s while uncompressing content from %s" 
(Printexc2.to_string e) (Url.to_string r.req_url);
+          Sys.remove filename;
+          raise Not_found
+      end
+      else
       Unix2.tryopen_write_bin filename (fun oc -> output_string oc s);
       if r.req_save_to_file_time <> 0. then
         Unix.utimes filename r.req_save_to_file_time r.req_save_to_file_time;
@@ -463,7 +497,18 @@
             TcpBufferedSocket.close sock Closed_by_user
         end)
   (fun _ ->  
-      f (Buffer.contents file_buf)
+      let content = 
+        if r.req_gzip then
+          try
+            let io = IO.input_string (Buffer.contents file_buf) in
+            IO.read_all io
+          with e -> 
+            lprintf_nl "Exception %s while uncompressing content from %s" 
(Printexc2.to_string e) (Url.to_string r.req_url);
+            raise Not_found
+        else
+          Buffer.contents file_buf
+      in
+      f content
   ) ferr
 
 

Index: src/utils/net/http_client.mli
===================================================================
RCS file: /sources/mldonkey/mldonkey/src/utils/net/http_client.mli,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- src/utils/net/http_client.mli       8 Aug 2010 18:37:41 -0000       1.11
+++ src/utils/net/http_client.mli       7 Nov 2010 15:01:41 -0000       1.12
@@ -37,6 +37,7 @@
     req_accept : string;
     req_proxy : (string * int * (string * string) option) option; (** 
(host,port,(login,password)) *)
     mutable req_url : Url.url;
+    mutable req_gzip : bool;
     mutable req_save_to_file_time : float;
 (* re-download a saved file only if newer *)
     req_request : http_request;

Index: src/utils/extlib/IO.ml
===================================================================
RCS file: src/utils/extlib/IO.ml
diff -N src/utils/extlib/IO.ml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/utils/extlib/IO.ml      7 Nov 2010 15:01:40 -0000       1.1
@@ -0,0 +1,771 @@
+(*
+ * IO - Abstract input/output
+ * Copyright (C) 2003 Nicolas Cannasse
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version,
+ * with the special exception on linking described in file LICENSE.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+
+type input = {
+       mutable in_read : unit -> char;
+       mutable in_input : string -> int -> int -> int;
+       mutable in_close : unit -> unit;
+}
+
+type 'a output = {
+       mutable out_write : char -> unit;
+       mutable out_output : string -> int -> int -> int;
+       mutable out_close : unit -> 'a;
+       mutable out_flush : unit -> unit;
+}
+
+exception No_more_input
+exception Input_closed
+exception Output_closed
+
+(* -------------------------------------------------------------- *)
+(* API *)
+
+let default_close = (fun () -> ())
+
+let create_in ~read ~input ~close =
+       {
+               in_read = read;
+               in_input = input;
+               in_close = close;
+       }
+
+let create_out ~write ~output ~flush ~close =
+       {
+               out_write = write;
+               out_output = output;
+               out_close = close;
+               out_flush = flush;
+       }
+
+let read i = i.in_read()
+
+let nread i n =
+       if n < 0 then invalid_arg "IO.nread";
+       if n = 0 then
+               ""
+       else
+       let s = String.create n in
+       let l = ref n in
+       let p = ref 0 in
+       try
+               while !l > 0 do
+                       let r = i.in_input s !p !l in
+                       if r = 0 then raise No_more_input;
+                       p := !p + r;
+                       l := !l - r;
+               done;
+               s
+       with
+               No_more_input as e ->
+                       if !p = 0 then raise e;
+                       String.sub s 0 !p
+
+let really_output o s p l' =
+       let sl = String.length s in
+       if p + l' > sl || p < 0 || l' < 0 then invalid_arg "IO.really_output";
+       let l = ref l' in
+       let p = ref p in
+       while !l > 0 do 
+               let w = o.out_output s !p !l in
+               if w = 0 then raise Sys_blocked_io;
+               p := !p + w;
+               l := !l - w;
+       done;
+       l'
+
+let input i s p l =
+       let sl = String.length s in
+       if p + l > sl || p < 0 || l < 0 then invalid_arg "IO.input";
+       if l = 0 then
+               0
+       else
+               i.in_input s p l
+
+let really_input i s p l' =
+       let sl = String.length s in
+       if p + l' > sl || p < 0 || l' < 0 then invalid_arg "IO.really_input";
+       let l = ref l' in
+       let p = ref p in
+       while !l > 0 do
+               let r = i.in_input s !p !l in
+               if r = 0 then raise Sys_blocked_io;
+               p := !p + r;
+               l := !l - r;
+       done;
+       l'
+
+let really_nread i n =
+       if n < 0 then invalid_arg "IO.really_nread";
+       if n = 0 then ""
+       else
+       let s = String.create n 
+       in
+       ignore(really_input i s 0 n);
+       s
+
+let close_in i =
+       let f _ = raise Input_closed in
+       i.in_close();
+       i.in_read <- f;
+       i.in_input <- f;
+       i.in_close <- f
+
+let write o x = o.out_write x
+
+let nwrite o s =
+       let p = ref 0 in
+       let l = ref (String.length s) in
+       while !l > 0 do
+               let w = o.out_output s !p !l in
+               if w = 0 then raise Sys_blocked_io;
+               p := !p + w;
+               l := !l - w;
+       done
+
+let output o s p l =
+       let sl = String.length s in
+       if p + l > sl || p < 0 || l < 0 then invalid_arg "IO.output";
+       o.out_output s p l
+
+let printf o fmt =
+       Printf.kprintf (fun s -> nwrite o s) fmt
+
+let flush o = o.out_flush()
+
+let close_out o =
+       let f _ = raise Output_closed in
+       let r = o.out_close() in
+       o.out_write <- f;
+       o.out_output <- f;
+       o.out_close <- f;
+       o.out_flush <- f;
+       r
+
+let read_all i =
+       let maxlen = 1024 in
+       let str = ref [] in
+       let pos = ref 0 in
+       let rec loop() =
+               let s = nread i maxlen in
+               str := (s,!pos) :: !str;
+               pos := !pos + String.length s;
+               loop()
+       in
+       try
+               loop()
+       with
+               No_more_input ->
+                       let buf = String.create !pos in
+                       List.iter (fun (s,p) ->
+                               String.unsafe_blit s 0 buf p (String.length s)
+                       ) !str;
+                       buf
+
+let pos_in i =
+       let p = ref 0 in
+       {
+               in_read = (fun () ->
+                       let c = i.in_read() in
+                       incr p;
+                       c
+               );
+               in_input = (fun s sp l ->
+                       let n = i.in_input s sp l in
+                       p := !p + n;
+                       n
+               );
+               in_close = i.in_close
+       } , (fun () -> !p)
+
+let pos_out o =
+       let p = ref 0 in
+       {
+               out_write = (fun c ->
+                       o.out_write c;
+                       incr p
+               );
+               out_output = (fun s sp l ->
+                       let n = o.out_output s sp l in
+                       p := !p + n;
+                       n
+               );
+               out_close = o.out_close;
+               out_flush = o.out_flush;
+       } , (fun () -> !p)
+
+(* -------------------------------------------------------------- *)
+(* Standard IO *)
+
+let input_string s =
+       let pos = ref 0 in
+       let len = String.length s in
+       {
+               in_read = (fun () ->
+                       if !pos >= len then raise No_more_input;
+                       let c = String.unsafe_get s !pos in
+                       incr pos;
+                       c
+               );
+               in_input = (fun sout p l ->
+                       if !pos >= len then raise No_more_input;
+                       let n = (if !pos + l > len then len - !pos else l) in
+                       String.unsafe_blit s !pos sout p n;
+                       pos := !pos + n;
+                       n
+               );
+               in_close = (fun () -> ());
+       }
+
+let output_string() =
+       let b = Buffer.create 0 in
+       {
+               out_write = (fun c ->
+                       Buffer.add_char b c
+               );
+               out_output = (fun s p l ->
+                       Buffer.add_substring b s p l;
+                       l
+               );
+               out_close = (fun () -> Buffer.contents b);
+               out_flush = (fun () -> ());
+       }
+
+let input_channel ch =
+       {
+               in_read = (fun () ->
+                       try
+                               input_char ch
+                       with
+                               End_of_file -> raise No_more_input
+               );
+               in_input = (fun s p l ->
+                       let n = Pervasives.input ch s p l in
+                       if n = 0 then raise No_more_input;
+                       n
+               );
+               in_close = (fun () -> Pervasives.close_in ch);
+       }
+
+let output_channel ch =
+       {
+               out_write = (fun c -> output_char ch c);
+               out_output = (fun s p l -> Pervasives.output ch s p l; l);
+               out_close = (fun () -> Pervasives.close_out ch);
+               out_flush = (fun () -> Pervasives.flush ch);
+       }
+
+(*
+let input_enum e =
+       let pos = ref 0 in
+       {
+               in_read = (fun () ->
+                       match Enum.get e with
+                       | None -> raise No_more_input
+                       | Some c ->
+                               incr pos;
+                               c
+               );
+               in_input = (fun s p l ->
+                       let rec loop p l =
+                               if l = 0 then
+                                       0
+                               else
+                                       match Enum.get e with
+                                       | None -> l
+                                       | Some c ->
+                                               String.unsafe_set s p c;
+                                               loop (p + 1) (l - 1)
+                       in
+                       let k = loop p l in
+                       if k = l then raise No_more_input;
+                       l - k
+               );
+               in_close = (fun () -> ());
+       }
+
+let output_enum() =
+       let b = Buffer.create 0 in
+       {
+               out_write = (fun x ->
+                       Buffer.add_char b x
+               );
+               out_output = (fun s p l ->
+                       Buffer.add_substring b s p l;
+                       l
+               );
+               out_close = (fun () ->
+                       let s = Buffer.contents b in
+                       ExtString.String.enum s
+               );
+               out_flush = (fun () -> ());
+       }
+*)
+
+let pipe() =
+       let input = ref "" in
+       let inpos = ref 0 in
+       let output = Buffer.create 0 in
+       let flush() =
+               input := Buffer.contents output;
+               inpos := 0;
+               Buffer.reset output;
+               if String.length !input = 0 then raise No_more_input
+       in
+       let read() =
+               if !inpos = String.length !input then flush();
+               let c = String.unsafe_get !input !inpos in
+               incr inpos;
+               c
+       in
+       let input s p l =
+               if !inpos = String.length !input then flush();
+               let r = (if !inpos + l > String.length !input then 
String.length !input - !inpos else l) in
+               String.unsafe_blit !input !inpos s p r;
+               inpos := !inpos + r;
+               r
+       in
+       let write c =
+               Buffer.add_char output c
+       in
+       let output s p l =
+               Buffer.add_substring output s p l;
+               l
+       in
+       let input = {
+               in_read = read;
+               in_input = input;
+               in_close = (fun () -> ());
+       } in
+       let output = {
+               out_write = write;
+               out_output = output;
+               out_close = (fun () -> ());
+               out_flush = (fun () -> ());
+       } in
+       input , output
+
+external cast_output : 'a output -> unit output = "%identity"
+
+(* -------------------------------------------------------------- *)
+(* BINARY APIs *)
+
+exception Overflow of string
+
+let read_byte i = int_of_char (i.in_read())
+
+let read_signed_byte i =
+       let c = int_of_char (i.in_read()) in
+       if c land 128 <> 0 then
+               c - 256
+       else
+               c
+
+let read_string i =
+       let b = Buffer.create 8 in
+       let rec loop() =
+               let c = i.in_read() in
+               if c <> '\000' then begin
+                       Buffer.add_char b c;
+                       loop();
+               end;
+       in
+       loop();
+       Buffer.contents b
+
+let read_line i =
+       let b = Buffer.create 8 in
+       let cr = ref false in
+       let rec loop() =
+               let c = i.in_read() in
+               match c with
+               | '\n' ->
+                       ()
+               | '\r' ->
+                       cr := true;
+                       loop()
+               | _ when !cr ->
+                       cr := false;
+                       Buffer.add_char b '\r';
+                       Buffer.add_char b c;
+                       loop();
+               | _ ->
+                       Buffer.add_char b c;
+                       loop();
+       in
+       try
+               loop();
+               Buffer.contents b
+       with
+               No_more_input ->
+                       if !cr then Buffer.add_char b '\r';
+                       if Buffer.length b > 0 then
+                               Buffer.contents b
+                       else
+                               raise No_more_input
+
+let read_ui16 i =
+       let ch1 = read_byte i in
+       let ch2 = read_byte i in
+       ch1 lor (ch2 lsl 8)
+
+let read_i16 i =
+       let ch1 = read_byte i in
+       let ch2 = read_byte i in
+       let n = ch1 lor (ch2 lsl 8) in
+       if ch2 land 128 <> 0 then
+               n - 65536
+       else
+               n
+
+let read_i32 ch =
+       let ch1 = read_byte ch in
+       let ch2 = read_byte ch in
+       let ch3 = read_byte ch in
+       let ch4 = read_byte ch in
+       if ch4 land 128 <> 0 then begin
+               if ch4 land 64 = 0 then raise (Overflow "read_i32");
+               ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor ((ch4 land 127) lsl 24)
+       end else begin
+               if ch4 land 64 <> 0 then raise (Overflow "read_i32");
+               ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor (ch4 lsl 24)
+       end
+
+let read_real_i32 ch =
+       let ch1 = read_byte ch in
+       let ch2 = read_byte ch in
+       let ch3 = read_byte ch in
+       let base = Int32.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
+       let big = Int32.shift_left (Int32.of_int (read_byte ch)) 24 in
+       Int32.logor base big
+
+let read_i64 ch =
+       let ch1 = read_byte ch in
+       let ch2 = read_byte ch in
+       let ch3 = read_byte ch in
+       let ch4 = read_byte ch in
+       let base = Int64.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
+       let small = Int64.logor base (Int64.shift_left (Int64.of_int ch4) 24) in
+       let big = Int64.of_int32 (read_real_i32 ch) in
+       Int64.logor (Int64.shift_left big 32) small
+
+let read_double ch =
+       Int64.float_of_bits (read_i64 ch)
+
+let write_byte o n =
+       (* doesn't test bounds of n in order to keep semantics of 
Pervasives.output_byte *)
+       write o (Char.unsafe_chr (n land 0xFF))
+
+let write_string o s =
+       nwrite o s;
+       write o '\000'
+
+let write_line o s =
+       nwrite o s;
+       write o '\n'
+
+let write_ui16 ch n =
+       if n < 0 || n > 0xFFFF then raise (Overflow "write_ui16");
+       write_byte ch n;
+       write_byte ch (n lsr 8)
+
+let write_i16 ch n =
+       if n < -0x8000 || n > 0x7FFF then raise (Overflow "write_i16");
+       if n < 0 then
+               write_ui16 ch (65536 + n)
+       else
+               write_ui16 ch n
+
+let write_i32 ch n =
+       write_byte ch n;
+       write_byte ch (n lsr 8);
+       write_byte ch (n lsr 16);
+       write_byte ch (n asr 24)
+
+let write_real_i32 ch n =
+       let base = Int32.to_int n in
+       let big = Int32.to_int (Int32.shift_right_logical n 24) in
+       write_byte ch base;
+       write_byte ch (base lsr 8);
+       write_byte ch (base lsr 16);
+       write_byte ch big
+
+let write_i64 ch n =
+       write_real_i32 ch (Int64.to_int32 n);
+       write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical n 32))
+
+let write_double ch f =
+       write_i64 ch (Int64.bits_of_float f)
+
+(* -------------------------------------------------------------- *)
+(* Big Endians *)
+
+module BigEndian = struct
+
+let read_ui16 i =
+       let ch2 = read_byte i in
+       let ch1 = read_byte i in
+       ch1 lor (ch2 lsl 8)
+
+let read_i16 i =
+       let ch2 = read_byte i in
+       let ch1 = read_byte i in
+       let n = ch1 lor (ch2 lsl 8) in
+       if ch2 land 128 <> 0 then
+               n - 65536
+       else
+               n
+
+let read_i32 ch =
+       let ch4 = read_byte ch in
+       let ch3 = read_byte ch in
+       let ch2 = read_byte ch in
+       let ch1 = read_byte ch in
+       if ch4 land 128 <> 0 then begin
+               if ch4 land 64 = 0 then raise (Overflow "read_i32");
+               ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor ((ch4 land 127) lsl 24)
+       end else begin
+               if ch4 land 64 <> 0 then raise (Overflow "read_i32");
+               ch1 lor (ch2 lsl 8) lor (ch3 lsl 16) lor (ch4 lsl 24)
+       end
+
+let read_real_i32 ch =
+       let big = Int32.shift_left (Int32.of_int (read_byte ch)) 24 in
+       let ch3 = read_byte ch in
+       let ch2 = read_byte ch in
+       let ch1 = read_byte ch in
+       let base = Int32.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
+       Int32.logor base big
+
+let read_i64 ch =
+       let big = Int64.of_int32 (read_real_i32 ch) in
+       let ch4 = read_byte ch in
+       let ch3 = read_byte ch in
+       let ch2 = read_byte ch in
+       let ch1 = read_byte ch in
+       let base = Int64.of_int (ch1 lor (ch2 lsl 8) lor (ch3 lsl 16)) in
+       let small = Int64.logor base (Int64.shift_left (Int64.of_int ch4) 24) in
+       Int64.logor (Int64.shift_left big 32) small
+
+let read_double ch =
+       Int64.float_of_bits (read_i64 ch)
+
+let write_ui16 ch n =
+       if n < 0 || n > 0xFFFF then raise (Overflow "write_ui16");
+       write_byte ch (n lsr 8);
+       write_byte ch n
+
+let write_i16 ch n =
+       if n < -0x8000 || n > 0x7FFF then raise (Overflow "write_i16");
+       if n < 0 then
+               write_ui16 ch (65536 + n)
+       else
+               write_ui16 ch n
+
+let write_i32 ch n =
+       write_byte ch (n asr 24);
+       write_byte ch (n lsr 16);
+       write_byte ch (n lsr 8);
+       write_byte ch n
+
+let write_real_i32 ch n =
+       let base = Int32.to_int n in
+       let big = Int32.to_int (Int32.shift_right_logical n 24) in
+       write_byte ch big;
+       write_byte ch (base lsr 16);
+       write_byte ch (base lsr 8);
+       write_byte ch base
+
+let write_i64 ch n =
+       write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical n 32));
+       write_real_i32 ch (Int64.to_int32 n)
+
+let write_double ch f =
+       write_i64 ch (Int64.bits_of_float f)
+
+end
+
+(* -------------------------------------------------------------- *)
+(* Bits API *)
+
+type 'a bc = {
+       ch : 'a;
+       mutable nbits : int;
+       mutable bits : int;
+}
+
+type in_bits = input bc
+type out_bits = unit output bc
+
+exception Bits_error
+
+let input_bits ch =
+       {
+               ch = ch;
+               nbits = 0;
+               bits = 0;
+       }
+
+let output_bits ch =
+       {
+               ch = cast_output ch;
+               nbits = 0;
+               bits = 0;
+       }
+
+let rec read_bits b n =
+       if b.nbits >= n then begin
+               let c = b.nbits - n in
+               let k = (b.bits asr c) land ((1 lsl n) - 1) in
+               b.nbits <- c;
+               k
+       end else begin
+               let k = read_byte b.ch in
+               if b.nbits >= 24 then begin
+                       if n >= 31 then raise Bits_error;
+                       let c = 8 + b.nbits - n in
+                       let d = b.bits land ((1 lsl b.nbits) - 1) in
+                       let d = (d lsl (8 - c)) lor (k lsr c) in
+                       b.bits <- k;
+                       b.nbits <- c;
+                       d
+               end else begin                  
+                       b.bits <- (b.bits lsl 8) lor k;
+                       b.nbits <- b.nbits + 8;
+                       read_bits b n;
+               end
+       end
+
+let drop_bits b =
+       b.nbits <- 0
+
+let rec write_bits b ~nbits x =
+       let n = nbits in
+       if n + b.nbits >= 32 then begin
+               if n > 31 then raise Bits_error;
+               let n2 = 32 - b.nbits - 1 in
+               let n3 = n - n2 in
+               write_bits b ~nbits:n2 (x asr n3);
+               write_bits b ~nbits:n3 (x land ((1 lsl n3) - 1));
+       end else begin
+               if n < 0 then raise Bits_error;
+               if (x < 0 || x > (1 lsl n - 1)) && n <> 31 then raise 
Bits_error;
+               b.bits <- (b.bits lsl n) lor x;
+               b.nbits <- b.nbits + n;
+               while b.nbits >= 8 do
+                       b.nbits <- b.nbits - 8;
+                       write_byte b.ch (b.bits asr b.nbits)
+               done
+       end
+
+let flush_bits b =
+       if b.nbits > 0 then write_bits b (8 - b.nbits) 0
+
+(* -------------------------------------------------------------- *)
+(* Generic IO *)
+
+class in_channel ch =
+  object
+       method input s pos len = input ch s pos len
+       method close_in() = close_in ch
+  end
+
+class out_channel ch =
+  object
+       method output s pos len = output ch s pos len
+       method flush() = flush ch
+       method close_out() = ignore(close_out ch)
+  end
+
+class in_chars ch =
+  object
+       method get() = try read ch with No_more_input -> raise End_of_file
+       method close_in() = close_in ch
+  end
+
+class out_chars ch =
+  object
+       method put t = write ch t
+       method flush() = flush ch
+       method close_out() = ignore(close_out ch)
+  end
+
+let from_in_channel ch =
+       let cbuf = String.create 1 in
+       let read() =
+               try
+                       if ch#input cbuf 0 1 = 0 then raise Sys_blocked_io;
+                       String.unsafe_get cbuf 0
+               with
+                       End_of_file -> raise No_more_input
+       in
+       let input s p l =
+               ch#input s p l
+       in
+       create_in
+               ~read
+               ~input
+               ~close:ch#close_in
+
+let from_out_channel ch =
+       let cbuf = String.create 1 in
+       let write c =
+               String.unsafe_set cbuf 0 c;
+               if ch#output cbuf 0 1 = 0 then raise Sys_blocked_io;
+       in
+       let output s p l =
+               ch#output s p l
+       in
+       create_out
+               ~write
+               ~output
+               ~flush:ch#flush
+               ~close:ch#close_out
+
+let from_in_chars ch =
+       let input s p l =
+               let i = ref 0 in
+               try
+                       while !i < l do
+                               String.unsafe_set s (p + !i) (ch#get());
+                               incr i
+                       done;
+                       l
+               with
+                       End_of_file when !i > 0 ->
+                               !i
+       in
+       create_in
+               ~read:ch#get
+               ~input
+               ~close:ch#close_in
+
+let from_out_chars ch =
+       let output s p l =
+               for i = p to p + l - 1 do
+                       ch#put (String.unsafe_get s i)
+               done;
+               l
+       in
+       create_out
+               ~write:ch#put
+               ~output
+               ~flush:ch#flush
+               ~close:ch#close_out

Index: src/utils/extlib/IO.mli
===================================================================
RCS file: src/utils/extlib/IO.mli
diff -N src/utils/extlib/IO.mli
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/utils/extlib/IO.mli     7 Nov 2010 15:01:40 -0000       1.1
@@ -0,0 +1,323 @@
+(* 
+ * IO - Abstract input/output
+ * Copyright (C) 2003 Nicolas Cannasse
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version,
+ * with the special exception on linking described in file LICENSE.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+
+(** High-order abstract I/O.
+
+       IO module simply deals with abstract inputs/outputs. It provides a
+       set of methods for working with these IO as well as several
+       constructors that enable to write to an underlying channel, buffer,
+       or enum.
+*)
+
+type input
+(** The abstract input type. *)
+
+type 'a output
+(** The abstract output type, ['a] is the accumulator data, it is returned
+       when the [close_out] function is called. *)
+
+exception No_more_input
+(** This exception is raised when reading on an input with the [read] or
+  [nread] functions while there is no available token to read. *)
+
+exception Input_closed
+(** This exception is raised when reading on a closed input. *)
+
+exception Output_closed
+(** This exception is raised when reading on a closed output. *)
+
+(** {6 Standard API} *)
+
+val read : input -> char
+(** Read a single char from an input or raise [No_more_input] if
+  no input available. *)
+
+val nread : input -> int -> string
+(** [nread i n] reads a string of size up to [n] from an input.
+  The function will raise [No_more_input] if no input is available.
+  It will raise [Invalid_argument] if [n] < 0. *)
+
+val really_nread : input -> int -> string
+(** [really_nread i n] reads a string of exactly [n] characters
+  from the input. Raises [No_more_input] if at least [n] characters are
+  not available. Raises [Invalid_argument] if [n] < 0. *)
+
+val input : input -> string -> int -> int -> int
+(** [input i s p l] reads up to [l] characters from the given input, storing
+  them in string [s], starting at character number [p]. It returns the actual
+  number of characters read or raise [No_more_input] if no character can be
+  read. It will raise [Invalid_argument] if [p] and [l] do not designate a
+  valid substring of [s]. *)
+
+val really_input : input -> string -> int -> int -> int
+(** [really_input i s p l] reads exactly [l] characters from the given input,
+  storing them in the string [s], starting at position [p]. For consistency 
with
+  {!IO.input} it returns [l]. Raises [No_more_input] if at [l] characters are
+  not available. Raises [Invalid_argument] if [p] and [l] do not designate a
+  valid substring of [s]. *)
+
+val close_in : input -> unit
+(** Close the input. It can no longer be read from. *)
+
+val write : 'a output -> char -> unit
+(** Write a single char to an output. *)
+
+val nwrite : 'a output -> string -> unit
+(** Write a string to an output. *)
+
+val output : 'a output -> string -> int -> int -> int
+(** [output o s p l] writes up to [l] characters from string [s], starting at
+  offset [p]. It returns the number of characters written. It will raise
+  [Invalid_argument] if [p] and [l] do not designate a valid substring of [s]. 
*)
+
+val really_output : 'a output -> string -> int -> int -> int
+(** [really_output o s p l] writes exactly [l] characters from string [s] onto
+  the the output, starting with the character at offset [p]. For consistency 
with
+  {!IO.output} it returns [l]. Raises [Invalid_argument] if [p] and [l] do not
+  designate a valid substring of [s]. *)
+
+val flush : 'a output -> unit
+(** Flush an output. *)
+
+val close_out : 'a output -> 'a
+(** Close the output and return its accumulator data.
+  It can no longer be written. *)
+
+(** {6 Creation of IO Inputs/Outputs} *)
+
+val input_string : string -> input
+(** Create an input that will read from a string. *)
+
+val output_string : unit -> string output
+(** Create an output that will write into a string in an efficient way.
+  When closed, the output returns all the data written into it. *)
+
+val input_channel : in_channel -> input
+(** Create an input that will read from a channel. *)
+
+val output_channel : out_channel -> unit output
+(** Create an output that will write into a channel. *) 
+
+(*
+val input_enum : char Enum.t -> input
+(** Create an input that will read from an [enum]. *)
+
+val output_enum : unit -> char Enum.t output
+(** Create an output that will write into an [enum]. The 
+  final enum is returned when the output is closed. *)
+*)
+
+val create_in :
+  read:(unit -> char) ->
+  input:(string -> int -> int -> int) -> close:(unit -> unit) -> input
+(** Fully create an input by giving all the needed functions. *)
+
+val create_out :
+  write:(char -> unit) ->
+  output:(string -> int -> int -> int) ->   
+  flush:(unit -> unit) -> close:(unit -> 'a) -> 'a output
+(** Fully create an output by giving all the needed functions. *)
+
+(** {6 Utilities} *)
+
+val printf : 'a output -> ('b, unit, string, unit) format4 -> 'b
+(** The printf function works for any output. *)
+
+val read_all : input -> string
+(** read all the contents of the input until [No_more_input] is raised. *)
+
+val pipe : unit -> input * unit output
+(** Create a pipe between an input and an ouput. Data written from
+  the output can be read from the input. *)
+
+val pos_in : input -> input * (unit -> int)
+(** Create an input that provide a count function of the number of bytes
+  read from it. *)
+
+val pos_out : 'a output -> 'a output * (unit -> int)
+(** Create an output that provide a count function of the number of bytes
+  written through it. *)
+
+external cast_output : 'a output -> unit output = "%identity"
+(** You can safely transform any output to an unit output in a safe way 
+  by using this function. *)
+
+(** {6 Binary files API}
+
+       Here is some API useful for working with binary files, in particular
+       binary files generated by C applications. By default, encoding of
+       multibyte integers is low-endian. The BigEndian module provide multibyte
+       operations with other encoding.
+*)
+
+exception Overflow of string
+(** Exception raised when a read or write operation cannot be completed. *)
+
+val read_byte : input -> int
+(** Read an unsigned 8-bit integer. *)
+
+val read_signed_byte : input -> int
+(** Read an signed 8-bit integer. *)
+
+val read_ui16 : input -> int
+(** Read an unsigned 16-bit word. *)
+
+val read_i16 : input -> int
+(** Read a signed 16-bit word. *)
+
+val read_i32 : input -> int
+(** Read a signed 32-bit integer. Raise [Overflow] if the
+  read integer cannot be represented as a Caml 31-bit integer. *)
+
+val read_real_i32 : input -> int32
+(** Read a signed 32-bit integer as an OCaml int32. *)
+
+val read_i64 : input -> int64
+(** Read a signed 64-bit integer as an OCaml int64. *)
+
+val read_double : input -> float
+(** Read an IEEE double precision floating point value. *)
+
+val read_string : input -> string
+(** Read a null-terminated string. *)
+
+val read_line : input -> string
+(** Read a LF or CRLF terminated string. *)
+
+val write_byte : 'a output -> int -> unit
+(** Write an unsigned 8-bit byte. *)
+
+val write_ui16 : 'a output -> int -> unit
+(** Write an unsigned 16-bit word. *)
+
+val write_i16 : 'a output -> int -> unit
+(** Write a signed 16-bit word. *)
+
+val write_i32 : 'a output -> int -> unit
+(** Write a signed 32-bit integer. *) 
+
+val write_real_i32 : 'a output -> int32 -> unit
+(** Write an OCaml int32. *)
+
+val write_i64 : 'a output -> int64 -> unit
+(** Write an OCaml int64. *)
+
+val write_double : 'a output -> float -> unit
+(** Write an IEEE double precision floating point value. *)
+
+val write_string : 'a output -> string -> unit
+(** Write a string and append an null character. *)
+
+val write_line : 'a output -> string -> unit
+(** Write a line and append a LF (it might be converted
+       to CRLF on some systems depending on the underlying IO). *)
+
+(** Same as operations above, but use big-endian encoding *)
+module BigEndian :
+sig
+
+       val read_ui16 : input -> int
+       val read_i16 : input -> int
+       val read_i32 : input -> int
+       val read_real_i32 : input -> int32
+       val read_i64 : input -> int64
+       val read_double : input -> float
+       
+       val write_ui16 : 'a output -> int -> unit
+       val write_i16 : 'a output -> int -> unit
+       val write_i32 : 'a output -> int -> unit
+       val write_real_i32 : 'a output -> int32 -> unit
+       val write_i64 : 'a output -> int64 -> unit
+       val write_double : 'a output -> float -> unit
+
+end
+
+(** {6 Bits API}
+
+       This enable you to read and write from an IO bit-by-bit or several bits
+       at the same time.
+*)
+
+type in_bits
+type out_bits
+
+exception Bits_error
+
+val input_bits : input -> in_bits
+(** Read bits from an input *)
+
+val output_bits : 'a output -> out_bits
+(** Write bits to an output *)
+
+val read_bits : in_bits -> int -> int
+(** Read up to 31 bits, raise Bits_error if n < 0 or n > 31 *)
+
+val write_bits : out_bits -> nbits:int -> int -> unit
+(** Write up to 31 bits represented as a value, raise Bits_error if nbits < 0
+ or nbits > 31 or the value representation excess nbits. *)
+
+val flush_bits : out_bits -> unit
+(** Flush remaining unwritten bits, adding up to 7 bits which values 0. *)
+
+val drop_bits : in_bits -> unit
+(** Drop up to 7 buffered bits and restart to next input character. *)
+
+(** {6 Generic IO Object Wrappers}
+
+       Theses OO Wrappers have been written to provide easy support of ExtLib
+       IO by external librairies. If you want your library to support ExtLib
+       IO without actually requiring ExtLib to compile, you can should 
implement
+       the classes [in_channel], [out_channel], [poly_in_channel] and/or
+       [poly_out_channel] which are the common IO specifications established
+       for ExtLib, OCamlNet and Camomile.
+
+       (see http://www.ocaml-programming.de/tmp/IO-Classes.html for more 
details).
+*)
+
+class in_channel : input ->
+  object
+       method input : string -> int -> int -> int
+       method close_in : unit -> unit
+  end
+
+class out_channel : 'a output ->
+  object
+       method output : string -> int -> int -> int
+       method flush : unit -> unit
+       method close_out : unit -> unit
+  end
+
+class in_chars : input ->
+  object
+       method get : unit -> char
+       method close_in : unit -> unit
+  end
+
+class out_chars : 'a output ->
+  object
+       method put : char -> unit
+       method flush : unit -> unit
+       method close_out : unit -> unit
+  end
+
+val from_in_channel : #in_channel -> input
+val from_out_channel : #out_channel -> unit output
+val from_in_chars : #in_chars -> input
+val from_out_chars : #out_chars -> unit output



reply via email to

[Prev in Thread] Current Thread [Next in Thread]