aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src/asn1rtt_per_common.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-12-20 12:13:47 +0100
committerBjörn Gustavsson <[email protected]>2013-01-22 19:20:12 +0100
commit76ad80f52981449af3c79fdf5b298e4c8d817788 (patch)
treee717f03e019d2a8089e9adfe424b8700067a98bc /lib/asn1/src/asn1rtt_per_common.erl
parentfbcb7fe589edbfe79d10d7fe01be8a9f77926b89 (diff)
downloadotp-76ad80f52981449af3c79fdf5b298e4c8d817788.tar.gz
otp-76ad80f52981449af3c79fdf5b298e4c8d817788.tar.bz2
otp-76ad80f52981449af3c79fdf5b298e4c8d817788.zip
Refactor decoding of BIT STRINGs
Refactor decoding of BIT STRINGs so that the run-time code does not spend testing conditions that are known already at compile-time (which wastes time and produces unnecessary Dialyzer warnings). There are three ways to decode BIT STRINGs: 1) To a list of bit names (and {bit,Position} for unnamed positions) if the BIT STRING type has any bit names. 2a) To a list of ones and zeros if there are no named bits, and the compact_bit_string option was NOT given. 2b) To a {Unused,Bin} tuple if there are no named bits compact_bit_string option WAS given. Structure the decoding functions in the same way.
Diffstat (limited to 'lib/asn1/src/asn1rtt_per_common.erl')
-rw-r--r--lib/asn1/src/asn1rtt_per_common.erl33
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl
index 926f0fe228..2edd240baf 100644
--- a/lib/asn1/src/asn1rtt_per_common.erl
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -21,7 +21,11 @@
-include("asn1_records.hrl").
--export([decode_fragmented/3]).
+-export([decode_fragmented/3,
+ decode_compact_bit_string/1,
+ decode_legacy_bit_string/1,
+ decode_named_bit_string/2]).
+
-define('16K',16384).
decode_fragmented(SegSz0, Buf0, Unit) ->
@@ -42,3 +46,30 @@ decode_fragmented_1(<<1:1,1:1,SegSz0:6,Buf0/bitstring>>, Unit, Res0) ->
<<Frag:SegSz/bitstring,Buf/bitstring>> = Buf0,
Res = <<Res0/bitstring,Frag/bitstring>>,
decode_fragmented_1(Buf, Unit, Res).
+
+decode_named_bit_string(Val, NNL) ->
+ Bits = [B || <<B:1>> <= Val],
+ decode_named_bit_string_1(0, Bits, NNL, []).
+
+decode_legacy_bit_string(Val) ->
+ [B || <<B:1>> <= Val].
+
+decode_compact_bit_string(Val) ->
+ PadLen = (8 - (bit_size(Val) band 7)) band 7,
+ {PadLen,<<Val/bitstring,0:PadLen>>}.
+
+%%%
+%%% Internal functions.
+%%%
+
+decode_named_bit_string_1(Pos, [0|Bt], Names, Acc) ->
+ decode_named_bit_string_1(Pos+1, Bt, Names, Acc);
+decode_named_bit_string_1(Pos, [1|Bt], Names, Acc) ->
+ case lists:keyfind(Pos, 2, Names) of
+ {Name,_} ->
+ decode_named_bit_string_1(Pos+1, Bt, Names, [Name|Acc]);
+ false ->
+ decode_named_bit_string_1(Pos+1, Bt, Names, [{bit,Pos}|Acc])
+ end;
+decode_named_bit_string_1(_Pos, [], _Names, Acc) ->
+ lists:reverse(Acc).