File 8361-ASN.1-JER-Support-decoding-already-decoded-JSON-data.patch of Package erlang
From 618b46b379cf1787df1b2287f0f3de91cb8b9ca1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 18 Mar 2025 13:55:37 +0100
Subject: [PATCH] ASN.1 JER: Support decoding already decoded JSON data
---
lib/asn1/doc/guides/asn1_getting_started.md | 26 +++++
lib/asn1/src/asn1ct_gen.erl | 123 ++++++++++----------
lib/asn1/test/asn1_test_lib.erl | 14 ++-
3 files changed, 96 insertions(+), 67 deletions(-)
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 213e4f5b82..8926be42ac 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -803,6 +803,7 @@ pgen_dispatcher(Gen, Types) ->
false ->
ok
end,
+
%% DECODER
ReturnRest = proplists:get_bool(undec_rest, Gen#gen.options),
Data = case Gen#gen.erule =:= ber andalso ReturnRest of
@@ -811,6 +812,31 @@ pgen_dispatcher(Gen, Types) ->
end,
emit(["decode(Type, ",Data,") ->",nl]),
+ pgen_dispatcher_decode(Gen, ReturnRest, NoOkWrapper),
+
+ case Gen#gen.jer of
+ true ->
+ emit(["jer_decode(Type, ",Data,") ->",nl]),
+ pgen_dispatcher_decode(Gen#gen{erule=jer},
+ ReturnRest, NoOkWrapper);
+ false ->
+ ok
+ end,
+
+ %% REST of MODULE
+ gen_decode_partial_incomplete(Gen, NoOkWrapper),
+ gen_partial_inc_dispatcher(Gen),
+
+ case Gen of
+ #gen{erule=jer} ->
+ ok;
+ _ ->
+ gen_dispatcher(Types, "encode_disp", "enc_"),
+ gen_dispatcher(Types, "decode_disp", "dec_")
+ end.
+
+pgen_dispatcher_decode(Gen, ReturnRest, NoOkWrapper) ->
+ CurrMod = lists:concat(["'",get(currmod),"'"]),
case NoOkWrapper of
false -> emit(["try",nl]);
@@ -818,85 +844,52 @@ pgen_dispatcher(Gen, Types) ->
end,
DecWrap =
- case {Gen,ReturnRest} of
- {#gen{erule=ber},false} ->
- asn1ct_func:need({ber,ber_decode_nif,1}),
- "element(1, ber_decode_nif(Data))";
- {#gen{erule=ber},true} ->
- asn1ct_func:need({ber,ber_decode_nif,1}),
- emit([" {Data,Rest} = ber_decode_nif(Data0),",nl]),
- "Data";
- {#gen{erule=jer},false} ->
- "json:decode(Data)";
- {#gen{erule=jer},true} ->
- exit("JER + return rest not supported");
- {_,_} ->
- "Data"
- end,
+ case {Gen,ReturnRest} of
+ {#gen{erule=ber},false} ->
+ asn1ct_func:need({ber,ber_decode_nif,1}),
+ "element(1, ber_decode_nif(Data))";
+ {#gen{erule=ber},true} ->
+ asn1ct_func:need({ber,ber_decode_nif,1}),
+ emit([" {Data,Rest} = ber_decode_nif(Data0),",nl]),
+ "Data";
+ {#gen{erule=jer},false} ->
+ "case Data of\n"
+ " {json_decoded,Decoded} -> Decoded;\n"
+ " _ -> json:decode(Data)\n"
+ "end\n";
+ {#gen{erule=jer},true} ->
+ exit("JER + return rest not supported");
+ {_,_} ->
+ "Data"
+ end,
DecodeDisp = ["decode_disp(Type, ",DecWrap,")"],
case {Gen,ReturnRest} of
- {#gen{erule=ber},true} ->
- emit([" Result = ",DecodeDisp,",",nl]),
+ {#gen{erule=ber},true} ->
+ emit([" Result = ",DecodeDisp,",",nl]),
result_line(NoOkWrapper, ["Result","Rest"]);
- {#gen{erule=ber},false} ->
- emit([" Result = ",DecodeDisp,",",nl]),
+ {#gen{erule=ber},false} ->
+ emit([" Result = ",DecodeDisp,",",nl]),
result_line(NoOkWrapper, ["Result"]);
- {#gen{erule=jer},false} ->
- emit([" Result = ",{call,jer,decode_jer,[CurrMod,"Type",DecWrap]},",",nl]),
+ {#gen{erule=JER},false} when JER =:= jer ->
+ emit([" Result = ",{call,jer,decode_jer,[CurrMod,"Type",DecWrap]},",",nl]),
result_line(NoOkWrapper, ["Result"]);
-
-
- {#gen{erule=per},true} ->
- emit([" {Result,Rest} = ",DecodeDisp,",",nl]),
+ {#gen{erule=per},true} ->
+ emit([" {Result,Rest} = ",DecodeDisp,",",nl]),
result_line(NoOkWrapper, ["Result","Rest"]);
- {#gen{erule=per},false} ->
- emit([" {Result,_Rest} = ",DecodeDisp,",",nl]),
+ {#gen{erule=per},false} ->
+ emit([" {Result,_Rest} = ",DecodeDisp,",",nl]),
result_line(NoOkWrapper, ["Result"])
end,
case NoOkWrapper of
- false ->
- emit([nl,try_catch(),".",nl,nl]);
- true ->
- emit([".",nl,nl])
- end,
-
- case Gen#gen.jer of
- true ->
- emit(["jer_decode(Type, ",Data,") ->",nl]),
- case NoOkWrapper of
- false -> emit(["try",nl]);
- true -> ok
- end,
- JerDecWrap = "json:decode(Data)",
- emit([" Result = ",
- {call,jer,
- decode_jer,
- [CurrMod,"Type",JerDecWrap]},",",nl]),
- result_line(false, ["Result"]),
- case NoOkWrapper of
- false ->
- emit([nl,try_catch(),".",nl,nl]);
- true ->
- emit([".",nl,nl])
- end;
false ->
+ emit([nl,try_catch()]);
+ true ->
ok
end,
-
-
- %% REST of MODULE
- gen_decode_partial_incomplete(Gen, NoOkWrapper),
- gen_partial_inc_dispatcher(Gen),
- case Gen of
- #gen{erule=jer} ->
- ok;
- _ ->
- gen_dispatcher(Types, "encode_disp", "enc_"),
- gen_dispatcher(Types, "decode_disp", "dec_")
- end.
+ emit([".",nl,nl]).
result_line(NoOkWrapper, Items) ->
S = [" "|case NoOkWrapper of
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
index 7a271cb1d7..a6d0e963a4 100644
--- a/lib/asn1/test/asn1_test_lib.erl
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -197,7 +197,7 @@ roundtrip_enc(Mod, Type, Value, ExpectedValue) ->
ExpectedValue = Mod:decode(Type, Encoded)
end,
map_roundtrip(Mod, Type, Encoded),
- test_ber_indefinite(Mod, Type, Encoded, ExpectedValue),
+ test_special(Mod, Type, Encoded, ExpectedValue),
Encoded.
map_roundtrip(Mod, Type, Encoded) ->
@@ -248,9 +248,10 @@ match_value_tuple(I, T1, T2) when I =< tuple_size(T1) ->
match_value_tuple(_, _, _) ->
ok.
-test_ber_indefinite(Mod, Type, Encoded, ExpectedValue) ->
+test_special(Mod, Type, Encoded, ExpectedValue) ->
case Mod:encoding_rule() of
ber ->
+ %% Test indefinite decoding for BER.
Indefinite = iolist_to_binary(ber_indefinite(Encoded)),
case Mod:decode(Type, Indefinite) of
{ok,ExpectedValue} ->
@@ -258,7 +259,14 @@ test_ber_indefinite(Mod, Type, Encoded, ExpectedValue) ->
ExpectedValue ->
ok
end;
- _ ->
+ jer ->
+ %% Test already decoded JSON for JER.
+ JsonDecoded = json:decode(Encoded),
+ case Mod:decode(Type, {json_decoded,JsonDecoded}) of
+ {ok,ExpectedValue} -> ok;
+ ExpectedValue -> ok
+ end;
+ _ ->
ok
end.
--
2.43.0