bitstring_of_string and bitstring_of_*_max functions.
authorRichard W.M. Jones <rich@annexia.org>
Sat, 26 Apr 2008 20:35:02 +0000 (20:35 +0000)
committerRichard W.M. Jones <rich@annexia.org>
Sat, 26 Apr 2008 20:35:02 +0000 (20:35 +0000)
bitmatch.ml
bitmatch.mli

index 861cd5a..1b98c57 100644 (file)
@@ -15,7 +15,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *
- * $Id: bitmatch.ml,v 1.9 2008-04-15 13:40:51 rjones Exp $
+ * $Id: bitmatch.ml,v 1.10 2008-04-26 20:35:02 rjones Exp $
  *)
 
 open Printf
@@ -41,6 +41,8 @@ let make_bitstring len c = String.make ((len+7) lsr 3) c, 0, len
 
 let create_bitstring len = make_bitstring len '\000'
 
+let bitstring_of_string str = str, 0, String.length str lsl 3
+
 let bitstring_of_chan chan =
   let tmpsize = 16384 in
   let buf = Buffer.create tmpsize in
@@ -51,6 +53,54 @@ let bitstring_of_chan chan =
   done;
   Buffer.contents buf, 0, Buffer.length buf lsl 3
 
+let bitstring_of_chan_max chan max =
+  let tmpsize = 16384 in
+  let buf = Buffer.create tmpsize in
+  let tmp = String.create tmpsize in
+  let len = ref 0 in
+  let rec loop () =
+    if !len < max then (
+      let r = min tmpsize (max - !len) in
+      let n = input chan tmp 0 r in
+      if n > 0 then (
+       Buffer.add_substring buf tmp 0 n;
+       len := !len + n;
+       loop ()
+      )
+    )
+  in
+  loop ();
+  Buffer.contents buf, 0, !len lsl 3
+
+let bitstring_of_file_descr fd =
+  let tmpsize = 16384 in
+  let buf = Buffer.create tmpsize in
+  let tmp = String.create tmpsize in
+  let n = ref 0 in
+  while n := Unix.read fd tmp 0 tmpsize; !n > 0 do
+    Buffer.add_substring buf tmp 0 !n;
+  done;
+  Buffer.contents buf, 0, Buffer.length buf lsl 3
+
+let bitstring_of_file_descr_max fd max =
+  let tmpsize = 16384 in
+  let buf = Buffer.create tmpsize in
+  let tmp = String.create tmpsize in
+  let len = ref 0 in
+  let rec loop () =
+    if !len < max then (
+      let r = min tmpsize (max - !len) in
+      let n = Unix.read fd tmp 0 r in
+      if n > 0 then (
+       Buffer.add_substring buf tmp 0 n;
+       len := !len + n;
+       loop ()
+      )
+    )
+  in
+  loop ();
+  Buffer.contents buf, 0, !len lsl 3
+
 let bitstring_of_file fname =
   let chan = open_in_bin fname in
   let bs = bitstring_of_chan chan in
index f1c7ed1..aee63e2 100644 (file)
@@ -15,7 +15,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *
- * $Id: bitmatch.mli,v 1.16 2008-04-25 12:55:39 rjones Exp $
+ * $Id: bitmatch.mli,v 1.17 2008-04-26 20:35:02 rjones Exp $
  *)
 
 (**
@@ -533,13 +533,15 @@ type bitstring = string * int * int
     The type contains the underlying data (a string),
     the current bit offset within the string and the
     current bit length of the string (counting from the
-    bit offset).  Note that the offsets are bits, not bytes.
+    bit offset).  Note that the offset and length are
+    in {b bits}, not bytes.
 
     Normally you don't need to use the bitstring type
     directly, since there are functions and syntax
     extensions which hide the details.
-    See {!bitstring_of_file}, {!hexdump_bitstring},
-    {!bitstring_length}.
+
+    See also {!bitstring_of_string}, {!bitstring_of_file},
+    {!hexdump_bitstring}, {!bitstring_length}.
 *)
 
 (** {3 Exceptions} *)
@@ -576,22 +578,46 @@ val make_bitstring : int -> char -> bitstring
 
     Note that the length is in bits, not bytes. *)
 
+val bitstring_of_string : string -> bitstring
+(** [bitstring_of_string str] creates a bitstring
+    of length [String.length str * 8] (bits) containing the
+    bits in [str].
+
+    Note that the bitstring uses [str] as the underlying
+    string (see the representation of {!bitstring}) so you
+    should not change [str] after calling this. *)
+
+val bitstring_of_file : string -> bitstring
+(** [bitstring_of_file filename] loads the named file
+    into a bitstring. *)
+
 val bitstring_of_chan : in_channel -> bitstring
 (** [bitstring_of_chan chan] loads the contents of
     the input channel [chan] as a bitstring.
 
     The length of the final bitstring is determined
     by the remaining input in [chan], but will always
-    be a multiple of 8 bits. *)
+    be a multiple of 8 bits.
 
-val bitstring_of_file : string -> bitstring
-(** [bitstring_of_file filename] loads the named file
-    into a bitstring. *)
+    See also {!bitstring_of_chan_max}. *)
 
-val hexdump_bitstring : out_channel -> bitstring -> unit
-(** [hexdump_bitstring chan bitstring] prints the bitstring
-    to the output channel in a format similar to the
-    Unix command [hexdump -C]. *)
+val bitstring_of_chan_max : in_channel -> int -> bitstring
+(** [bitstring_of_chan_max chan max] works like
+    {!bitstring_of_chan} but will only read up to
+    [max] bytes from the channel (or fewer if the end of input
+    occurs before that). *)
+
+val bitstring_of_file_descr : Unix.file_descr -> bitstring
+(** [bitstring_of_file_descr fd] loads the contents of
+    the file descriptor [fd] as a bitstring.
+
+    See also {!bitstring_of_chan}, {!bitstring_of_file_descr_max}. *)
+
+val bitstring_of_file_descr_max : Unix.file_descr -> int -> bitstring
+(** [bitstring_of_file_descr_max fd max] works like
+    {!bitstring_of_file_descr} but will only read up to
+    [max] bytes from the channel (or fewer if the end of input
+    occurs before that). *)
 
 val bitstring_length : bitstring -> int
 (** [bitstring_length bitstring] returns the length of
@@ -606,6 +632,13 @@ val string_of_bitstring : bitstring -> string
     bitstring isn't aligned then this involves a lot of bit twiddling
     and is particularly inefficient. *)
 
+(** {3 Printing bitstrings} *)
+
+val hexdump_bitstring : out_channel -> bitstring -> unit
+(** [hexdump_bitstring chan bitstring] prints the bitstring
+    to the output channel in a format similar to the
+    Unix command [hexdump -C]. *)
+
 (** {3 Bitstring buffer} *)
 
 module Buffer : sig