X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=bitstring.ml;h=fda9ad6b1ffd787784ab0e9ef453b316507a46d1;hb=1cd333c8aa3a51f02f36f97518006f502bfa4afa;hp=44dc1f28b6d1f6f88d98a4279134897c1fb1b49f;hpb=7c3ce1f99992caa51c6ce3eabea3b9bce137665f;p=ocaml-bitstring.git diff --git a/bitstring.ml b/bitstring.ml index 44dc1f2..fda9ad6 100644 --- a/bitstring.ml +++ b/bitstring.ml @@ -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