aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2013-04-09 07:23:40 +0200
committerBjörn Gustavsson <[email protected]>2013-05-31 14:52:23 +0200
commit4001ac2a291e26d9fa912dbeefbe92278aceb345 (patch)
tree55037cf1b23c5ee251fbd32a3051f7e0df1c4217
parent83fe4f33369c6c33f6241d279611dc2b91594298 (diff)
downloadotp-4001ac2a291e26d9fa912dbeefbe92278aceb345.tar.gz
otp-4001ac2a291e26d9fa912dbeefbe92278aceb345.tar.bz2
otp-4001ac2a291e26d9fa912dbeefbe92278aceb345.zip
PER: Generate code for deep table constraints at compile-time
For the PER backends, generate code for accessing deep table constraints at compile-time in the same way as is done for BER. While at it, remove the complicated indentation code. Also modernize the test suite and add a test for a deeper nested constraint.
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl27
-rw-r--r--lib/asn1/src/asn1ct_gen.erl19
-rw-r--r--lib/asn1/test/asn1_SUITE_data/TConstr.asn16
-rw-r--r--lib/asn1/test/testDeepTConstr.erl59
4 files changed, 34 insertions, 77 deletions
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index 9405d052db..dd5737dd8c 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -150,27 +150,12 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
true ->
ObjectEncode =
asn1ct_gen:un_hyphen_var(lists:concat(['Obj',AttrN])),
+ El = make_element(N+1, asn1ct_gen:mk_var(asn1ct_name:curr(val))),
+ ValueMatch = value_match(ValueIndex, El),
emit([ObjectEncode," =",nl,
" ",{asis,Module},":'getenc_",ObjSetName,"'(",
- {asis,UniqueFieldName},", ",nl]),
- El = make_element(N+1,asn1ct_gen:mk_var(asn1ct_name:curr(val))),
-
- Length = fun(X,_LFun) when is_atom(X) ->
- length(atom_to_list(X));
- (X,_LFun) when is_list(X) ->
- length(X);
- ({X1,X2},LFun) ->
- LFun(X1,LFun) + LFun(X2,LFun)
- end,
- Indent = 12 + Length(ObjectSet,Length),
- case ValueIndex of
- [] ->
- emit([indent(Indent),El,"),",nl]);
- _ ->
- emit([indent(Indent),"value_match(",
- {asis,ValueIndex},",",El,")),",nl]),
- notice_value_match()
- end,
+ {asis,UniqueFieldName},", ",nl,
+ " ",ValueMatch,"),",nl]),
{AttrN,ObjectEncode};
false ->
false
@@ -1793,9 +1778,5 @@ value_match1(Value,[],Acc,Depth) ->
value_match1(Value,[{VI,_}|VIs],Acc,Depth) ->
value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1).
-notice_value_match() ->
- Module = get(currmod),
- put(value_match,{true,Module}).
-
is_optimized(per) -> true;
is_optimized(uper) -> false.
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 978ac280dd..9095e145a3 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -108,8 +108,7 @@ pgen_values(Erules,Module,[H|T]) ->
gen_value(Valuedef),
pgen_values(Erules,Module,T).
-pgen_types(_,_,_,Module,[]) ->
- gen_value_match(Module),
+pgen_types(_, _, _, _, []) ->
true;
pgen_types(Rtmod,Erules,N2nConvEnums,Module,[H|T]) ->
asn1ct_name:clear(),
@@ -573,22 +572,6 @@ gen_types(Erules,Tname,Type) when is_record(Type,type) ->
asn1ct_name:clear(),
Rtmod:gen_decode(Erules,Tname,Type).
-gen_value_match(Module) ->
- case get(value_match) of
- {true,Module} ->
- emit(["value_match([{Index,Cname}|Rest],Value) ->",nl,
- " Value2 =",nl,
- " case element(Index,Value) of",nl,
- " {Cname,Val2} -> Val2;",nl,
- " X -> X",nl,
- " end,",nl,
- " value_match(Rest,Value2);",nl,
- "value_match([],Value) ->",nl,
- " Value.",nl]);
- _ -> ok
- end,
- put(value_match,undefined).
-
gen_check_defaultval(Erules,Module,[{Name,Type}|Rest]) ->
gen_check_func(Name,Type),
gen_check_defaultval(Erules,Module,Rest);
diff --git a/lib/asn1/test/asn1_SUITE_data/TConstr.asn1 b/lib/asn1/test/asn1_SUITE_data/TConstr.asn1
index 63f5dbde77..e2e0a11dc4 100644
--- a/lib/asn1/test/asn1_SUITE_data/TConstr.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/TConstr.asn1
@@ -51,6 +51,12 @@ Seq2 ::= SEQUENCE {
}
}
+Deeper ::= SEQUENCE {
+ a SEQUENCE {aa INTEGER,
+ s SEQUENCE { ab MYCLASS.&id ({ObjectSet}),
+ ac INTEGER }},
+ b SEQUENCE {ba INTEGER, bb MYCLASS.&Type ({ObjectSet}{@a.s.ab})}
+}
-- following from Peter's definitions
diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl
index 3df7bcbaa0..e826cafa0c 100644
--- a/lib/asn1/test/testDeepTConstr.erl
+++ b/lib/asn1/test/testDeepTConstr.erl
@@ -40,53 +40,40 @@ main(_Erule) ->
{any,"DK"},
{final,"NO"}]}},
- ?line {ok,Bytes1} =
- asn1_wrapper:encode('TConstrChoice','FilterItem',Val1),
-
- ?line {error,Reason} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes1),
-
+ {ok,Bytes1} = 'TConstrChoice':encode('FilterItem', Val1),
+ {error,Reason} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes1),
io:format("Reason: ~p~n~n",[Reason]),
-
- ?line {ok,Bytes2} =
- asn1_wrapper:encode('TConstrChoice','FilterItem',Val2),
-
- ?line {ok,Res} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes2),
-
-
+ {ok,Bytes2} = 'TConstrChoice':encode('FilterItem', Val2),
+ {ok,Res} = 'TConstrChoice':decode('FilterItem', Bytes2),
%% test of OTP-4248.
- ?line {ok,Bytes3} =
- asn1_wrapper:encode('TConstrChoice','Seq',{'Seq',3,Bytes2}),
-
- ?line {ok,{'Seq',3,Bytes4}} =
- asn1_wrapper:decode('TConstrChoice','Seq',Bytes3),
-
- ?line {ok,Res} = asn1_wrapper:decode('TConstrChoice','FilterItem',Bytes4),
+ {ok,Bytes3} = 'TConstrChoice':encode('Seq', {'Seq',3,Bytes2}),
+ {ok,{'Seq',3,Bytes4}} = 'TConstrChoice':decode('Seq', Bytes3),
+ {ok,Res} = 'TConstrChoice':decode('FilterItem', Bytes4),
%% test of TConstr
- Seq1Val = {'Seq1',{'Seq1_a',12,{2,4}},{'Seq1_b',13,{'Type-object1',14,true}}},
- ?line {ok,Bytes5} =
- asn1_wrapper:encode('TConstr','Seq1',Seq1Val),
-
- ?line {ok,Seq1Val} =
- asn1_wrapper:decode('TConstr','Seq1',Bytes5),
+ Seq1Val = {'Seq1',{'Seq1_a',12,{2,4}},
+ {'Seq1_b',13,{'Type-object1',14,true}}},
+ roundtrip('TConstr', 'Seq1', Seq1Val),
Seq2Val = {'Seq2',123,{'Seq2_content',{2,6,7},
{first,{'Type-object3_first',false,47}},
false}},
-
- ?line {ok,Bytes6} =
- asn1_wrapper:encode('TConstr','Seq2',Seq2Val),
+ roundtrip('TConstr', 'Seq2', Seq2Val),
- ?line {ok,Seq2Val} =
- asn1_wrapper:decode('TConstr','Seq2',Bytes6),
+ roundtrip('TConstr', 'Info', {'Info',{'Info_xyz',{1,2}},1234}),
+
+ roundtrip('TConstr', 'Deeper',
+ {'Deeper',
+ {'Deeper_a',12,
+ {'Deeper_a_s',{2,4},42}},
+ {'Deeper_b',13,{'Type-object1',14,true}}}),
+ ok.
- InfoVal = {'Info',{'Info_xyz',{1,2}},1234},
-
- ?line {ok,Bytes7} =
- asn1_wrapper:encode('TConstr','Info',InfoVal),
- ?line {ok,InfoVal} =
- asn1_wrapper:decode('TConstr','Info',Bytes7).
+roundtrip(M, T, V) ->
+ {ok,E} = M:encode(T, V),
+ {ok,V} = M:decode(T, E),
+ ok.