From 17eb38a5f2bc6e26634314dd7070ae4407924518 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 14 May 2013 15:56:07 +0000 Subject: [PATCH] Add functions: is_zeroes_bitstring, is_ones_bitstring. --- aclocal.m4 | 6 +++--- bitstring.ml | 36 ++++++++++++++++++++++++++++++++++++ bitstring.mli | 6 ++++++ tests/test_36_is_zeroes_ones.ml | 29 +++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 tests/test_36_is_zeroes_ones.ml diff --git a/aclocal.m4 b/aclocal.m4 index f4de067..36c9013 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.11 -*- Autoconf -*- +# generated automatically by aclocal 1.12.2 -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/bitstring.ml b/bitstring.ml index efac383..1c51a73 100644 --- a/bitstring.ml +++ b/bitstring.ml @@ -1101,6 +1101,42 @@ let equals ((_, _, len1) as bs1) ((_, _, len2) as bs2) = else if bs1 = bs2 then true else 0 = compare bs1 bs2 +let is_zeroes_bitstring ((data, off, len) as bits) = + if off land 7 = 0 && len land 7 = 0 then ( + let off = off lsr 3 and len = len lsr 3 in + let rec loop i = + if i < len then ( + if String.unsafe_get data (off + i) <> '\000' then false + else loop (i+1) + ) else true + in + loop 0 + ) + else ( + (* Slow/unaligned case. *) + let len = bitstring_length bits in + let zeroes = zeroes_bitstring len in + 0 = compare bits zeroes + ) + +let is_ones_bitstring ((data, off, len) as bits) = + if off land 7 = 0 && len land 7 = 0 then ( + let off = off lsr 3 and len = len lsr 3 in + let rec loop i = + if i < len then ( + if String.unsafe_get data (off + i) <> '\xff' then false + else loop (i+1) + ) else true + in + loop 0 + ) + else ( + (* Slow/unaligned case. *) + let len = bitstring_length bits in + let ones = ones_bitstring len in + 0 = compare bits ones + ) + (*----------------------------------------------------------------------*) (* Bit get/set functions. *) diff --git a/bitstring.mli b/bitstring.mli index a29cb03..33f85f4 100644 --- a/bitstring.mli +++ b/bitstring.mli @@ -707,6 +707,12 @@ val equals : bitstring -> bitstring -> bool semantically equal. It is the same as calling [compare] and testing if the result is [0], but usually more efficient. *) +val is_zeroes_bitstring : bitstring -> bool +(** Tests if the bitstring is all zero bits (cf. {!zeroes_bitstring}) *) + +val is_ones_bitstring : bitstring -> bool +(** Tests if the bitstring is all one bits (cf. {!ones_bitstring}). *) + (** {3 Bitstring manipulation} *) val bitstring_length : bitstring -> int diff --git a/tests/test_36_is_zeroes_ones.ml b/tests/test_36_is_zeroes_ones.ml new file mode 100644 index 0000000..59ab38f --- /dev/null +++ b/tests/test_36_is_zeroes_ones.ml @@ -0,0 +1,29 @@ +(* Test if bitstrings are all zeroes or all ones. + * $Id$ + *) + +open Printf + +let () = + for i = 0 to 33 do + let bits = Bitstring.zeroes_bitstring i in + if not (Bitstring.is_zeroes_bitstring bits) then ( + eprintf "is_zeros_bitstring failed %d\n" i; + exit 1 + ); + if i > 0 && Bitstring.is_ones_bitstring bits then ( + eprintf "false match is_ones_bitstring %d\n" i; + exit 1 + ) + done; + for i = 0 to 33 do + let bits = Bitstring.ones_bitstring i in + if not (Bitstring.is_ones_bitstring bits) then ( + eprintf "is_ones_bitstring failed %d\n" i; + exit 1 + ); + if i > 0 && Bitstring.is_zeroes_bitstring bits then ( + eprintf "false match is_zeroes_bitstring %d\n" i; + exit 1 + ) + done -- 1.8.3.1