diff options
author | Björn Gustavsson <[email protected]> | 2017-01-16 16:47:58 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-02-06 12:49:26 +0100 |
commit | 8a7f914affce3102e4889c2973ea2d2e99ad633d (patch) | |
tree | dc346ad3a5a9f04f59046209fe042515a873f6da /lib/asn1/src/asn1ct_check.erl | |
parent | 48137fa5034202e0fc4c5fbc0faf9bbb8bc2bb13 (diff) | |
download | otp-8a7f914affce3102e4889c2973ea2d2e99ad633d.tar.gz otp-8a7f914affce3102e4889c2973ea2d2e99ad633d.tar.bz2 otp-8a7f914affce3102e4889c2973ea2d2e99ad633d.zip |
Teach the ASN.1 compiler the 'maps' option
When the 'maps' option is given, the SEQUENCE and SET types are
represented as maps instead of as records. Optional and default values
must be not be given as asn1_NOVALUE or asn1_DEFAULT in a map passed
to the M:encode/2 function; they must be omitted from the
map. Similarly, when decoding missing values will be omitted from the
map.
No .hrl files will be generated when the 'maps' options is used.
That means values in an ASN.1 module must be retrieved by calling the
appropriate function in generated module.
Since we one day hope to get rid of the options 'compact_bit_string',
'legacy_bit_string', and 'legacy_erlang_types', we will not allow them
to be combined with the 'maps' option.
Diffstat (limited to 'lib/asn1/src/asn1ct_check.erl')
-rw-r--r-- | lib/asn1/src/asn1ct_check.erl | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index a01a22ddc4..321f4147f5 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -2239,12 +2239,18 @@ normalized_record(SorS,S,Value,Components,NameList) -> case is_record_normalized(S,NewName,Value,length(Components)) of true -> Value; - _ -> + false -> NoComps = length(Components), ListOfVals = normalize_seq_or_set(SorS,S,Value,Components,NameList,[]), - NoComps = length(ListOfVals), %% Assert - list_to_tuple([NewName|ListOfVals]) + NoComps = length(ListOfVals), %Assertion. + case use_maps(S) of + false -> + list_to_tuple([NewName|ListOfVals]); + true -> + create_map_value(Components, ListOfVals) + end end. + is_record_normalized(S,Name,V = #'Externalvaluereference'{},NumComps) -> case get_referenced_type(S,V) of {_M,#valuedef{type=_T1,value=V2}} -> @@ -2253,9 +2259,20 @@ is_record_normalized(S,Name,V = #'Externalvaluereference'{},NumComps) -> end; is_record_normalized(_S,Name,Value,NumComps) when is_tuple(Value) -> (tuple_size(Value) =:= (NumComps + 1)) andalso (element(1, Value) =:= Name); +is_record_normalized(_S, _Name, Value, _NumComps) when is_map(Value) -> + true; is_record_normalized(_,_,_,_) -> false. +use_maps(#state{options=Opts}) -> + lists:member(maps, Opts). + +create_map_value(Components, ListOfVals) -> + Zipped = lists:zip(Components, ListOfVals), + L = [{Name,V} || {#'ComponentType'{name=Name},V} <- Zipped, + V =/= asn1_NOVALUE], + maps:from_list(L). + normalize_seq_or_set(SorS, S, [{#seqtag{val=Cname},V}|Vs], [#'ComponentType'{name=Cname,typespec=TS}|Cs], @@ -5674,7 +5691,8 @@ storeindb(S0, #module{name=ModName,typeorval=TVlist0}=M) -> storeindb_1(S, #module{name=ModName}=M, TVlist0, TVlist) -> NewM = M#module{typeorval=findtypes_and_values(TVlist0)}, - asn1_db:dbnew(ModName, S#state.erule), + Maps = lists:member(maps, S#state.options), + asn1_db:dbnew(ModName, S#state.erule, Maps), asn1_db:dbput(ModName, 'MODULE', NewM), asn1_db:dbput(ModName, TVlist), include_default_class(S, NewM#module.name), |