Added little-endian constructors (thanks to Romain Beauxis and Samuel Mimram).
authorRichard W.M. Jones <rich@annexia.org>
Wed, 20 Aug 2008 16:58:33 +0000 (16:58 +0000)
committerRichard W.M. Jones <rich@annexia.org>
Wed, 20 Aug 2008 16:58:33 +0000 (16:58 +0000)
bitstring.ml
bitstring.mli

index 44dc1f2..fda9ad6 100644 (file)
@@ -208,6 +208,19 @@ module I = struct
       let lsb = v land (mask bits) in
       g (to_int lsb) bits
     )
+
+  (* Call function g on the top bits, then f on each full byte
+   * (little endian - so start at root).
+   *)
+  let rec map_bytes_le g f v bits =
+    if bits >= 8 then (
+      let lsb = v land ff in
+      f (to_int lsb);
+      map_bytes_le g f (v >> 8) (bits-8)
+    ) else if bits > 0 then (
+      let lsb = v land (mask bits) in
+      g (to_int lsb) bits
+    )
 end
 
 module I32 = struct
@@ -279,6 +292,19 @@ module I32 = struct
       let lsb = v land (mask bits) in
       g (to_int lsb) bits
     )
+
+  (* Call function g on the top bits, then f on each full byte
+   * (little endian - so start at root).
+   *)
+  let rec map_bytes_le g f v bits =
+    if bits >= 8 then (
+      let lsb = v land ff in
+      f (to_int lsb);
+      map_bytes_le g f (v >> 8) (bits-8)
+    ) else if bits > 0 then (
+      let lsb = v land (mask bits) in
+      g (to_int lsb) bits
+    )
 end
 
 module I64 = struct
@@ -330,6 +356,19 @@ module I64 = struct
       let lsb = v land (mask bits) in
       g (to_int lsb) bits
     )
+
+  (* Call function g on the top bits, then f on each full byte
+   * (little endian - so start at root).
+   *)
+  let rec map_bytes_le g f v bits =
+    if bits >= 8 then (
+      let lsb = v land ff in
+      f (to_int lsb);
+      map_bytes_le g f (v >> 8) (bits-8)
+    ) else if bits > 0 then (
+      let lsb = v land (mask bits) in
+      g (to_int lsb) bits
+    )
 end
 
 (*----------------------------------------------------------------------*)
@@ -760,16 +799,21 @@ let construct_int_be_unsigned buf v flen exn =
   (* Add the bytes. *)
   I.map_bytes_be (Buffer._add_bits buf) (Buffer.add_byte buf) v flen
 
+(* Construct a field of up to 31 bits. *)
+let construct_int_le_unsigned buf v flen exn =
+  (* Check value is within range. *)
+  if not (I.range_unsigned v flen) then raise exn;
+  (* Add the bytes. *)
+  I.map_bytes_le (Buffer._add_bits buf) (Buffer.add_byte buf) v flen
+
 let construct_int_ne_unsigned =
   if nativeendian = BigEndian
   then construct_int_be_unsigned
-  else (*construct_int_le_unsigned*)
-    fun _ _ _ _ -> failwith "construct_int_le_unsigned"
+  else construct_int_le_unsigned
 
 let construct_int_ee_unsigned = function
   | BigEndian -> construct_int_be_unsigned
-  | LittleEndian -> (*construct_int_le_unsigned*)
-      (fun _ _ _ _ -> failwith "construct_int_le_unsigned")
+  | LittleEndian -> construct_int_le_unsigned
   | NativeEndian -> construct_int_ne_unsigned
 
 (* Construct a field of exactly 32 bits. *)
@@ -810,6 +854,13 @@ let construct_int64_be_unsigned buf v flen exn =
   (* Add the bytes. *)
   I64.map_bytes_be (Buffer._add_bits buf) (Buffer.add_byte buf) v flen
 
+(* Construct a field of up to 64 bits. *)
+let construct_int64_le_unsigned buf v flen exn =
+  (* Check value is within range. *)
+  if not (I64.range_unsigned v flen) then raise exn;
+  (* Add the bytes. *)
+  I64.map_bytes_le (Buffer._add_bits buf) (Buffer.add_byte buf) v flen
+
 let construct_int64_ne_unsigned =
   if nativeendian = BigEndian
   then construct_int64_be_unsigned
index 69b56c1..6c35da8 100644 (file)
@@ -908,18 +908,24 @@ val construct_char_unsigned : Buffer.t -> int -> int -> exn -> unit
 
 val construct_int_be_unsigned : Buffer.t -> int -> int -> exn -> unit
 
+val construct_int_le_unsigned : Buffer.t -> int -> int -> exn -> unit
+
 val construct_int_ne_unsigned : Buffer.t -> int -> int -> exn -> unit
 
 val construct_int_ee_unsigned : endian -> Buffer.t -> int -> int -> exn -> unit
 
 val construct_int32_be_unsigned : Buffer.t -> int32 -> int -> exn -> unit
 
+val construct_int32_le_unsigned : Buffer.t -> int32 -> int -> exn -> unit
+
 val construct_int32_ne_unsigned : Buffer.t -> int32 -> int -> exn -> unit
 
 val construct_int32_ee_unsigned : endian -> Buffer.t -> int32 -> int -> exn -> unit
 
 val construct_int64_be_unsigned : Buffer.t -> int64 -> int -> exn -> unit
 
+val construct_int64_le_unsigned : Buffer.t -> int64 -> int -> exn -> unit
+
 val construct_int64_ne_unsigned : Buffer.t -> int64 -> int -> exn -> unit
 
 val construct_int64_ee_unsigned : endian -> Buffer.t -> int64 -> int -> exn -> unit