File 8321-asn1-Use-the-new-json-module-for-the-JER-backend.patch of Package erlang
From 7e004ed7b002eb95ea217b191de3074175e5253d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 8 Mar 2024 08:01:55 +0100
Subject: [PATCH] asn1: Use the new `json` module for the JER backend
---
lib/asn1/src/asn1ct.erl | 16 +++++++---------
lib/asn1/src/asn1ct_gen.erl | 30 +++++-------------------------
lib/asn1/src/asn1rtt_jer.erl | 18 ++++++++----------
3 files changed, 20 insertions(+), 44 deletions(-)
diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index 96b2ea6629..69bd72e69b 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -147,25 +147,14 @@ File3.asn</pre>
<c>jer_encode(Type, Value)</c> and <c>jer_decode(Type, Bytes)</c>.
</p>
<p>
- The <c>jer</c> encoding rules (ITU-T X.697) are experimental in
- OTP 22.
- There is support for a subset of the X.697 standard, for example there is no support for:
+ JER (ITU-T X.697) are experimental in OTP 22. There is support for a
+ subset of the X.697 standard, for example there is no support for:
</p>
<list>
<item>JER encoding instructions</item>
<item>the REAL type</item>
</list>
<p>
- Also note that when using the <c>jer</c> encoding rules the
- generated module will get a dependency to an external json
- component. The generated code is currently tested together with:
- </p>
- <list>
- <item><c>jsx</c> which currently is the default.</item>
- <item><c>jsone</c> can be chosen instead of <c>jsx</c>
- by providing the option <c>{d,jsone}</c>.</item>
- </list>
- <p>
If the encoding rule option is omitted, <c>ber</c>
is the default.
</p>
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index bf242bbc73..e69c63f847 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -765,7 +765,7 @@ pgen_dispatcher(Gen, Types) ->
#gen{erule=ber} ->
"iolist_to_binary(element(1, encode_disp(Type, Data)))";
#gen{erule=jer} ->
- ["?JSON_ENCODE(",{call,jer,encode_jer,[CurrMod,"Type","Data"]},")"];
+ [{call,jer,encode_jer,[CurrMod,"Type","Data"]}];
#gen{erule=per,aligned=false} when NoFinalPadding ->
asn1ct_func:need({uper,complete_NFP,1}),
"complete_NFP(encode_disp(Type, Data))";
@@ -789,7 +789,7 @@ pgen_dispatcher(Gen, Types) ->
case Gen#gen.jer of
true ->
emit(["jer_encode(Type, Data) ->",nl]),
- JerCall = ["?JSON_ENCODE(",{call,jer,encode_jer,[CurrMod,"Type","Data"]},")"],
+ JerCall = [{call,jer,encode_jer,[CurrMod,"Type","Data"]}],
case NoOkWrapper of
true ->
emit([" ",JerCall,"."]);
@@ -827,7 +827,7 @@ pgen_dispatcher(Gen, Types) ->
emit([" {Data,Rest} = ber_decode_nif(Data0),",nl]),
"Data";
{#gen{erule=jer},false} ->
- "?JSON_DECODE(Data)";
+ "json:decode(Data)";
{#gen{erule=jer},true} ->
exit("JER + return rest not supported");
{_,_} ->
@@ -869,7 +869,7 @@ pgen_dispatcher(Gen, Types) ->
false -> emit(["try",nl]);
true -> ok
end,
- JerDecWrap = "?JSON_DECODE(Data)",
+ JerDecWrap = "json:decode(Data)",
emit([" Result = ",
{call,jer,
decode_jer,
@@ -1349,27 +1349,7 @@ gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
end,
emit(["-asn1_info([{vsn,'",asn1ct:vsn(),"'},",nl,
" {module,'",Mod,"'},",nl,
- " {options,",io_lib:format("~p",[Options1]),"}]).",nl,nl]),
- JerDefines = case Gen of
- #gen{erule=jer} ->
- true;
- #gen{jer=true} ->
- true;
- _ ->
- false
- end,
- JerDefines andalso
-%% FIXME add jiffy as well and maybe a third argument where the user
-%% can provide the JSON encode/decode as a fun (or atom).
- emit([
- "-ifdef(jsone).",nl,
- "-define(JSON_DECODE(Data),jsone:decode(Data)).",nl,
- "-define(JSON_ENCODE(Term),jsone:encode(Term)).",nl,
- "-else.",nl,
- "-define(JSON_DECODE(Data),jsx:decode(Data,[return_maps])).",nl,
- "-define(JSON_ENCODE(Term),jsx:encode(Term)).",nl,
- "-endif.",nl
- ]).
+ " {options,",io_lib:format("~p",[Options1]),"}]).",nl,nl]).
gen_hrlhead(Mod) ->
emit(["%% Generated by the Erlang ASN.1 compiler. Version: ",
diff --git a/lib/asn1/src/asn1rtt_jer.erl b/lib/asn1/src/asn1rtt_jer.erl
index 3e0f2d835f..6fdf0390a2 100644
--- a/lib/asn1/src/asn1rtt_jer.erl
+++ b/lib/asn1/src/asn1rtt_jer.erl
@@ -33,7 +33,8 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
encode_jer(Module, Type, Val) ->
Info = Module:typeinfo(Type),
- encode_jer(Info, Val).
+ Enc = encode_jer(Info, Val),
+ iolist_to_binary(json:encode(Enc)).
%% {sequence,
%% Name::atom() % The record name used for the sequence
@@ -171,7 +172,9 @@ 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)->
+
+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]);
@@ -179,15 +182,12 @@ encode_jer_component_map([{_Name, _AName, _Type, 'OPTIONAL'} | CompInfos], MapVa
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) when map_size(MapVal) =:= length(Acc) ->
+ maps:from_list(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);
encode_jer_component([{_Name, _Type, {'DEFAULT',_}} | CompInfos], [asn1_DEFAULT | Rest], Acc) ->
@@ -195,10 +195,8 @@ encode_jer_component([{_Name, _Type, {'DEFAULT',_}} | CompInfos], [asn1_DEFAULT
encode_jer_component([{Name, Type, _OptOrDefault} | CompInfos], [Value | Rest], Acc) ->
Enc = encode_jer(Type, Value),
encode_jer_component(CompInfos, Rest, [{Name,Enc}|Acc]);
-encode_jer_component([], _, []) ->
- #{}; % ensure that it is encoded as an empty object in JSON
encode_jer_component([], _, Acc) ->
- lists:reverse(Acc).
+ maps:from_list(Acc).
decode_jer(Module, Type, Val) ->
TypeInfo = Module:typeinfo(Type),
--
2.35.3