From 85e2eaaf58a1e67dfdcd42dd572cd4bc44c4be4f Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 1 Jun 2013 22:30:45 +0200 Subject: [PATCH] FreeTDM: Fix "ftdm core flags/spanflags" with flag names "x >> 1" is _NOT_ the reverse of "1 << x"... Use code from Sean Eron Andersen's "Bit Twiddling Hacks" (=> http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog) to compute the log2 value (= position in the enum) of the bitflag. This preserves the current behaviour, which is rather odd because it is based on the position of the value in the enum, not its actual (bit flag) value. Signed-off-by: Stefan Knoblich --- libs/freetdm/src/ftdm_io.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index a88dd34ccc..20d4fc69ef 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4761,6 +4761,26 @@ static void print_span_flag_values(ftdm_stream_handle_t *stream) } } +/** + * Compute log2 of 64bit integer v + * + * Bit Twiddling Hacks + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog + */ +static int ftdm_log2_64(uint64_t v) +{ + unsigned int shift; + uint64_t r; + + r = (v > 0xFFFFFFFF) << 5; v >>= r; + shift = (v > 0xFFFF ) << 4; v >>= shift; r |= shift; + shift = (v > 0xFF ) << 3; v >>= shift; r |= shift; + shift = (v > 0xF ) << 2; v >>= shift; r |= shift; + shift = (v > 0x3 ) << 1; v >>= shift; r |= shift; + + return (r | (v >> 1)); +} + static char *handle_core_command(const char *cmd) { char *mycmd = NULL; @@ -4835,7 +4855,7 @@ static char *handle_core_command(const char *cmd) print_channel_flag_values(&stream); goto done; } - flagval = flagval >> 1; + flagval = ftdm_log2_64(flagval); } else { flagval = atoi(flag); } @@ -4880,7 +4900,7 @@ static char *handle_core_command(const char *cmd) print_span_flag_values(&stream); goto done; } - flagval = flagval >> 1; + flagval = ftdm_log2_64(flagval); } else { flagval = atoi(flag); }