Implement dropbits, takebits, subbitstring.
[ocaml-bitstring.git] / bitmatch.mli
index fa7b525..cd59f95 100644 (file)
@@ -4,7 +4,8 @@
  * 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 of the License, or (at your option) any later version.
+ * version 2 of the License, or (at your option) any later version,
+ * with the OCaml linking exception described in COPYING.LIB.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -305,8 +306,9 @@ bitmatch bits with
        a {!endian} type, ie. [LittleEndian], [BigEndian] or [NativeEndian].
        The expression is an arbitrary OCaml expression and can use the
        value of earlier fields in the bitmatch.
+   - [offset (expr)]: see {{:#computedoffsets}computed offsets} below.
 
-   The default settings are [int], [unsigned], [bigendian].
+   The default settings are [int], [unsigned], [bigendian], no offset.
 
    Note that many of these qualifiers cannot be used together,
    eg. bitstrings do not have endianness.  The syntax extension should
@@ -417,6 +419,31 @@ Bitmatch.hexdump_bitstring stdout bits ;;
    still need to be a runtime check to enforce the
    size).
 
+   {2:computedoffsets Computed offsets}
+
+   You can add an [offset(..)] qualifier to bitmatch patterns in order
+   to move the current offset within the bitstring forwards.
+
+   For example:
+
+{[
+bitmatch bits with
+| { field1 : 8;
+    field2 : 8 : offset(160) } -> ...
+]}
+
+   matches [field1] at the start of the bitstring and [field2]
+   at 160 bits into the bitstring.  The middle 152 bits go
+   unmatched (ie. can be anything).
+
+   The generated code is efficient.  If field lengths and offsets
+   are known to be constant at compile time, then almost all
+   runtime checks are avoided.  Non-constant field lengths and/or
+   non-constant offsets can result in more runtime checks being added.
+
+   Note that moving the offset backwards, and moving the offset in
+   [BITSTRING] constructors, are both not supported at present.
+
    {2 Named patterns and persistent patterns}
 
    Please see {!Bitmatch_persistent} for documentation on this subject.
@@ -427,16 +454,16 @@ Bitmatch.hexdump_bitstring stdout bits ;;
 
    {v
    ocamlc -I +bitmatch \
-     -pp "camlp4o bitmatch.cma bitmatch_persistent.cma \
+     -pp "camlp4of bitmatch.cma bitmatch_persistent.cma \
             `ocamlc -where`/bitmatch/pa_bitmatch.cmo" \
-     bitmatch.cma test.ml -o test
+     unix.cma bitmatch.cma test.ml -o test
    v}
 
    Simpler method using findlib:
 
    {v
    ocamlfind ocamlc \
-     -package bitmatch.syntax -syntax bitmatch.syntax \
+     -package bitmatch,bitmatch.syntax -syntax bitmatch.syntax \
      -linkpkg test.ml -o test
    v}
 
@@ -573,7 +600,46 @@ exception Construct_failure of string * string * int * int
     location of the [BITSTRING] constructor that failed.
 *)
 
-(** {3 Bitstrings} *)
+(** {3 Bitstring manipulation} *)
+
+val bitstring_length : bitstring -> int
+(** [bitstring_length bitstring] returns the length of
+    the bitstring in bits.
+
+    Note this just returns the third field in the {!bitstring} tuple. *)
+
+val subbitstring : bitstring -> int -> int -> bitstring
+(** [subbitstring bits off len] returns a sub-bitstring
+    of the bitstring, starting at offset [off] bits and
+    with length [len] bits.
+
+    If the original bitstring is not long enough to do this
+    then the function raises [Invalid_argument "subbitstring"].
+
+    Note that this function just changes the offset and length
+    fields of the {!bitstring} tuple, so is very efficient. *)
+
+val dropbits : int -> bitstring -> bitstring
+(** Drop the first n bits of the bitstring and return a new
+    bitstring which is shorter by n bits.
+
+    If the length of the original bitstring is less than n bits,
+    this raises [Invalid_argument "dropbits"].
+
+    Note that this function just changes the offset and length
+    fields of the {!bitstring} tuple, so is very efficient. *)
+
+val takebits : int -> bitstring -> bitstring
+(** Take the first n bits of the bitstring and return a new
+    bitstring which is exactly n bits long.
+
+    If the length of the original bitstring is less than n bits,
+    this raises [Invalid_argument "takebits"].
+
+    Note that this function just changes the offset and length
+    fields of the {!bitstring} tuple, so is very efficient. *)
+
+(** {3 Constructing bitstrings} *)
 
 val empty_bitstring : bitstring
 (** [empty_bitstring] is the empty, zero-length bitstring. *)
@@ -589,7 +655,16 @@ val make_bitstring : int -> char -> bitstring
     For example, [make_bitstring 16 '\x5a'] will create
     the bitstring [0x5a5a] or in binary [0101 1010 0101 1010].
 
-    Note that the length is in bits, not bytes. *)
+    Note that the length is in bits, not bytes.  The length does NOT
+    need to be a multiple of 8. *)
+
+val zeroes_bitstring : int -> bitstring
+(** [zeroes_bitstring] creates an [n] bit bitstring of all 0's.
+
+    Actually this is the same as {!create_bitstring}. *)
+
+val ones_bitstring : int -> bitstring
+(** [ones_bitstring] creates an [n] bit bitstring of all 1's. *)
 
 val bitstring_of_string : string -> bitstring
 (** [bitstring_of_string str] creates a bitstring
@@ -632,9 +707,7 @@ val bitstring_of_file_descr_max : Unix.file_descr -> int -> bitstring
     [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
-    the bitstring in bits. *)
+(** {3 Converting bitstrings} *)
 
 val string_of_bitstring : bitstring -> string
 (** [string_of_bitstring bitstring] converts a bitstring to a string
@@ -769,3 +842,5 @@ val construct_int64_ne_unsigned : Buffer.t -> int64 -> int -> exn -> unit
 val construct_int64_ee_unsigned : endian -> Buffer.t -> int64 -> int -> exn -> unit
 
 val construct_string : Buffer.t -> string -> unit
+
+val construct_bitstring : Buffer.t -> bitstring -> unit