From 76ad80f52981449af3c79fdf5b298e4c8d817788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 20 Dec 2012 12:13:47 +0100 Subject: 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. --- lib/asn1/src/asn1rtt_per_common.erl | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'lib/asn1/src/asn1rtt_per_common.erl') 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) -> <> = Buf0, Res = <>, decode_fragmented_1(Buf, Unit, Res). + +decode_named_bit_string(Val, NNL) -> + Bits = [B || <> <= Val], + decode_named_bit_string_1(0, Bits, NNL, []). + +decode_legacy_bit_string(Val) -> + [B || <> <= Val]. + +decode_compact_bit_string(Val) -> + PadLen = (8 - (bit_size(Val) band 7)) band 7, + {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). -- cgit v1.2.3