Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
5271-Add-support-for-option-maps-in-the-JER-bac...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5271-Add-support-for-option-maps-in-the-JER-backend.patch of Package erlang
From 0e8bc92d290b9cb451104e6302ec5f8c0c7ae084 Mon Sep 17 00:00:00 2001 From: Kenneth Lundin <kenneth@erlang.org> Date: Wed, 20 Oct 2021 14:09:18 +0200 Subject: [PATCH] Add support for option 'maps' in the JER backend This solves GH-5129 --- lib/asn1/src/asn1ct_gen_jer.erl | 8 ++++++-- lib/asn1/src/asn1rtt_jer.erl | 36 +++++++++++++++++++++++++++++++++ lib/asn1/test/asn1_SUITE.erl | 26 +++++++++++++++++++----- 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/lib/asn1/src/asn1ct_gen_jer.erl b/lib/asn1/src/asn1ct_gen_jer.erl index 041ea6b247..5d775cd27f 100644 --- a/lib/asn1/src/asn1ct_gen_jer.erl +++ b/lib/asn1/src/asn1ct_gen_jer.erl @@ -104,9 +104,13 @@ gen_encode_sequence(Gen, Typename, #type{}=D) -> end, CompTypes = gen_enc_comptypes(Gen, Typename, CompList1, 1, EncObj, []), Prefix = asn1ct_gen:get_record_name_prefix(Gen), - {sequence, + {SequenceTag,NewCompTypes} = case Gen#gen.pack of + map -> {sequence_map,[{BinName,binary_to_atom(BinName),Type,OptOrDefault}||{BinName,Type,OptOrDefault} <- CompTypes]}; + _ -> {sequence,CompTypes} + end, + {SequenceTag, list_to_atom(lists:concat([Prefix,asn1ct_gen:list2name(Typename)])), - length(CompList1),CompTypes}. + length(CompList1),NewCompTypes}. gen_decode_sequence(_,_,_) -> ok. diff --git a/lib/asn1/src/asn1rtt_jer.erl b/lib/asn1/src/asn1rtt_jer.erl index 1efb9f1079..2c44ed2bd7 100644 --- a/lib/asn1/src/asn1rtt_jer.erl +++ b/lib/asn1/src/asn1rtt_jer.erl @@ -50,6 +50,8 @@ encode_jer({sequence_tab,Simple,Sname,Arity,CompInfos},Value) %% Arity::integer() % number of components %% CompInfos::[CompInfo()] % list of components with name, type etc %% Value::record matching name and arity +encode_jer({sequence_map,_Sname,_Arity,CompInfos},Value) when is_map(Value) -> + encode_jer_component_map(CompInfos,Value,[]); encode_jer({sequence,Sname,Arity,CompInfos},Value) when tuple_size(Value) == Arity+1 -> [Sname|Clist] = tuple_to_list(Value), @@ -167,6 +169,22 @@ encode_jer_component_tab([{Name, Type, _OptOrDefault} | CompInfos], [Value | Res encode_jer_component_tab(CompInfos, Rest, Simple, MapAcc#{Name => Enc}); encode_jer_component_tab([], _, _Simple, MapAcc) -> MapAcc. +encode_jer_component_map([{Name, AName, Type, _OptOrDefault} | CompInfos], MapVal, Acc) when is_map_key(AName,MapVal)-> + Value = maps:get(AName, MapVal), + Enc = encode_jer(Type, Value), + encode_jer_component_map(CompInfos, MapVal, [{Name,Enc}|Acc]); +encode_jer_component_map([{_Name, _AName, _Type, 'OPTIONAL'} | CompInfos], MapVal, Acc) -> + encode_jer_component_map(CompInfos, MapVal, Acc); +encode_jer_component_map([{_Name, _AName, _Type, {'DEFAULT',_}} | CompInfos], MapVal, Acc) -> + encode_jer_component_map(CompInfos, MapVal, Acc); +encode_jer_component_map([], MapVal, []) when map_size(MapVal) == 0-> + #{}; % ensure that it is encoded as an empty object in JSON +encode_jer_component_map([], MapVal, Acc) when map_size(MapVal) == length(Acc) -> + lists:reverse(Acc); +encode_jer_component_map(_, MapVal, Acc) -> + ErroneousKeys = maps:keys(MapVal) -- [K || {K,_V} <- Acc], + exit({error,{asn1,{{encode,'SEQUENCE'},{erroneous_keys,ErroneousKeys}}}}). + encode_jer_component([{_Name, _Type, 'OPTIONAL'} | CompInfos], [asn1_NOVALUE | Rest], Acc) -> encode_jer_component(CompInfos, Rest, Acc); @@ -210,6 +228,9 @@ decode_jer({sequence,Sname,_Arity,CompInfos},Value) when is_map(Value) -> DecodedComps = decode_jer_component(CompInfos,Value,[]), list_to_tuple([Sname|DecodedComps]); +decode_jer({sequence_map,_Sname,_Arity,CompInfos},Value) + when is_map(Value) -> + decode_jer_component_map(CompInfos,Value,[]); %% Unfortunately we have to represent strings as lists to be compatible %% with the other backends. Should add an option to the compiler in the future @@ -298,6 +319,21 @@ decode_jer_component([{Name, _Type, _OptOrDefault} | _CompInfos], VMap, _Acc) -> decode_jer_component([], _, Acc) -> lists:reverse(Acc). +decode_jer_component_map([{Name, AtomName, Type, _OptOrDefault} | CompInfos], VMap, Acc) + when is_map_key(Name, VMap) -> + Value = maps:get(Name, VMap), + Dec = decode_jer(Type, Value), + decode_jer_component_map(CompInfos, VMap, [{AtomName,Dec} | Acc]); +decode_jer_component_map([{_Name, _AtomName, _Type, 'OPTIONAL'} | CompInfos], VMap, Acc) -> + decode_jer_component_map(CompInfos, VMap, Acc); +decode_jer_component_map([{_Name, AtomName, _Type, {'DEFAULT',Dvalue}} | CompInfos], VMap, Acc) -> + decode_jer_component_map(CompInfos, VMap, [{AtomName, Dvalue} | Acc]); +decode_jer_component_map([{Name, _AtomName, _Type, _OptOrDefault} | _CompInfos], VMap, _Acc) -> + exit({error,{asn1,{{decode,{mandatory_component_missing,Name}},VMap}}}); +decode_jer_component_map([], _, Acc) -> + %% not reusing the map from JSON decoder since it can contain non expected extra K,V pairs + maps:from_list(Acc). + %% This is the default representation of octet string i.e binary json2octetstring2binary(Value) -> list_to_binary(json2octetstring(Value,[])). diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl index a1cc32da86..59a4246577 100644 --- a/lib/asn1/test/asn1_SUITE.erl +++ b/lib/asn1/test/asn1_SUITE.erl @@ -198,10 +198,16 @@ end_per_testcase(_Func, Config) -> %% Test runners %%------------------------------------------------------------------------------ +have_jsonlib() -> + case code:which(jsx) of + non_existing -> false; + _ -> true + end. + test(Config, TestF) -> - TestJer = case code:which(jsx) of - non_existing -> []; - _ -> [jer, {ber, [ber,jer]}] + TestJer = case have_jsonlib() of + true -> [jer, {ber, [ber,jer]}]; + false -> [] end, test(Config, TestF, [per, uper, @@ -424,11 +430,21 @@ testExtensionDefault(Config, Rule, Opts) -> end. testMaps(Config) -> - test(Config, fun testMaps/3, + Jer = case have_jsonlib() of + true -> [{jer,[maps,no_ok_wrapper]}]; + false -> [] + end, + RulesAndOptions = [{ber,[maps,no_ok_wrapper]}, {ber,[maps,der,no_ok_wrapper]}, {per,[maps,no_ok_wrapper]}, - {uper,[maps,no_ok_wrapper]}]). + {uper,[maps,no_ok_wrapper]}] ++ Jer, + test(Config, fun testMaps/3, RulesAndOptions), + case Jer of + [] -> {comment,"skipped JER"}; + _ -> ok + end. + testMaps(Config, Rule, Opts) -> asn1_test_lib:compile_all(['Maps'], Config, [Rule|Opts]), testMaps:main(Rule). -- 2.34.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor