aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asn1')
-rw-r--r--lib/asn1/doc/src/asn1ct.xml4
-rw-r--r--lib/asn1/src/asn1ct.erl22
-rw-r--r--lib/asn1/src/asn1ct_check.erl72
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl58
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl19
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl164
-rw-r--r--lib/asn1/src/asn1ct_gen_per_rt2ct.erl189
-rw-r--r--lib/asn1/src/asn1ct_parser2.erl31
-rw-r--r--lib/asn1/src/asn1rt_uper_bin.erl15
-rw-r--r--lib/asn1/test/asn1_SUITE.erl56
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn142
-rw-r--r--lib/asn1/test/asn1_SUITE_data/PrimStrings.asn113
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqExtension.asn128
-rw-r--r--lib/asn1/test/asn1_SUITE_data/testobj.erl28
-rw-r--r--lib/asn1/test/testChoExtension.erl41
-rw-r--r--lib/asn1/test/testChoExternal.erl75
-rw-r--r--lib/asn1/test/testChoRecursive.erl51
-rw-r--r--lib/asn1/test/testCompactBitString.erl302
-rw-r--r--lib/asn1/test/testConstraints.erl191
-rw-r--r--lib/asn1/test/testDeepTConstr.erl26
-rw-r--r--lib/asn1/test/testEnumExt.erl55
-rw-r--r--lib/asn1/test/testMergeCompile.erl2
-rw-r--r--lib/asn1/test/testParameterizedInfObj.erl2
-rw-r--r--lib/asn1/test/testPrimStrings.erl5
-rw-r--r--lib/asn1/test/testSeqExtension.erl135
-rw-r--r--lib/asn1/test/testSetOptional.erl210
-rw-r--r--lib/asn1/test/test_partial_incomplete_decode.erl2
-rw-r--r--lib/asn1/test/test_selective_decode.erl2
-rw-r--r--lib/asn1/test/test_special_decode_performance.erl6
29 files changed, 726 insertions, 1120 deletions
diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index 9a9bb7ec1b..bb3c6a4f0f 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -120,9 +120,7 @@ File3.asn </pre>
<c>Options</c> is a list with options specific for the asn1
compiler and options that are applied to the Erlang compiler.
The latter are those that not is recognized as asn1 specific.
- For <em>preferred option use</em> see <seealso
- marker="asn1_ug#preferred option use">Preferred Option Use
- section in users guide</seealso>. Available options are:
+ Available options are:
</p>
<taglist>
<tag><c>ber | per | uper</c></tag>
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index 90882462ac..98877320a0 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -1288,35 +1288,35 @@ pretty2(Module,AbsFile) ->
{ok,F} = file:open(AbsFile,[write]),
M = asn1_db:dbget(Module,'MODULE'),
io:format(F,"%%%%%%%%%%%%%%%%%%% ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- io:format(F,"~s\n",[asn1ct_pretty_format:term(M#module.defid)]),
- io:format(F,"~s\n",[asn1ct_pretty_format:term(M#module.tagdefault)]),
- io:format(F,"~s\n",[asn1ct_pretty_format:term(M#module.exports)]),
- io:format(F,"~s\n",[asn1ct_pretty_format:term(M#module.imports)]),
- io:format(F,"~s\n\n",[asn1ct_pretty_format:term(M#module.extensiondefault)]),
+ io:format(F,"~s.\n",[asn1ct_pretty_format:term(M#module.defid)]),
+ io:format(F,"~s.\n",[asn1ct_pretty_format:term(M#module.tagdefault)]),
+ io:format(F,"~s.\n",[asn1ct_pretty_format:term(M#module.exports)]),
+ io:format(F,"~s.\n",[asn1ct_pretty_format:term(M#module.imports)]),
+ io:format(F,"~s.\n\n",[asn1ct_pretty_format:term(M#module.extensiondefault)]),
{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets} = M#module.typeorval,
io:format(F,"%%%%%%%%%%%%%%%%%%% TYPES in ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- lists:foreach(fun(T)-> io:format(F,"~s\n",
+ lists:foreach(fun(T)-> io:format(F,"~s.\n",
[asn1ct_pretty_format:term(asn1_db:dbget(Module,T))])
end,Types),
io:format(F,"%%%%%%%%%%%%%%%%%%% VALUES in ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- lists:foreach(fun(T)-> io:format(F,"~s\n",
+ lists:foreach(fun(T)-> io:format(F,"~s.\n",
[asn1ct_pretty_format:term(asn1_db:dbget(Module,T))])
end,Values),
io:format(F,"%%%%%%%%%%%%%%%%%%% Parameterized Types in ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- lists:foreach(fun(T)-> io:format(F,"~s\n",
+ lists:foreach(fun(T)-> io:format(F,"~s.\n",
[asn1ct_pretty_format:term(asn1_db:dbget(Module,T))])
end,ParameterizedTypes),
io:format(F,"%%%%%%%%%%%%%%%%%%% Classes in ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- lists:foreach(fun(T)-> io:format(F,"~s\n",
+ lists:foreach(fun(T)-> io:format(F,"~s.\n",
[asn1ct_pretty_format:term(asn1_db:dbget(Module,T))])
end,Classes),
io:format(F,"%%%%%%%%%%%%%%%%%%% Objects in ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- lists:foreach(fun(T)-> io:format(F,"~s\n",
+ lists:foreach(fun(T)-> io:format(F,"~s.\n",
[asn1ct_pretty_format:term(asn1_db:dbget(Module,T))])
end,Objects),
io:format(F,"%%%%%%%%%%%%%%%%%%% Object Sets in ~p %%%%%%%%%%%%%%%%%%%~n",[Module]),
- lists:foreach(fun(T)-> io:format(F,"~s\n",
+ lists:foreach(fun(T)-> io:format(F,"~s.\n",
[asn1ct_pretty_format:term(asn1_db:dbget(Module,T))])
end,ObjectSets).
start() ->
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index fe1b2e14a8..dd77085c39 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -4340,11 +4340,33 @@ permitted_alphabet_merge([C1|Rest],UorI,Acc) ->
%% there will be no extension if the last constraint is without extension.
%% The rootset of all constraints are considered in the "outermoust
%% intersection". See section 13.1.2 in Dubuisson.
-constraint_merge(_S,C=[H])when is_tuple(H) ->
+constraint_merge(St, Cs0) ->
+ Cs = constraint_merge_1(St, Cs0),
+ normalize_cs(Cs).
+
+normalize_cs([{'SingleValue',[V]}|Cs]) ->
+ [{'SingleValue',V}|normalize_cs(Cs)];
+normalize_cs([{'SingleValue',[_|_]=L0}|Cs]) ->
+ [H|T] = L = lists:usort(L0),
+ [case is_range(H, T) of
+ false -> {'SingleValue',L};
+ true -> {'ValueRange',{H,lists:last(T)}}
+ end|normalize_cs(Cs)];
+normalize_cs([{'ValueRange',{Sv,Sv}}|Cs]) ->
+ [{'SingleValue',Sv}|normalize_cs(Cs)];
+normalize_cs([{'ValueRange',{'MIN','MAX'}}|Cs]) ->
+ normalize_cs(Cs);
+normalize_cs(Other) -> Other.
+
+is_range(Prev, [H|T]) when Prev =:= H - 1 -> is_range(H, T);
+is_range(_, [_|_]) -> false;
+is_range(_, []) -> true.
+
+constraint_merge_1(_S, [H]=C) when is_tuple(H) ->
C;
-constraint_merge(_S,[]) ->
+constraint_merge_1(_S, []) ->
[];
-constraint_merge(S,C) ->
+constraint_merge_1(S, C) ->
%% skip all extension but the last extension
C1 = filter_extensions(C),
%% perform all internal level intersections, intersections first
@@ -4367,17 +4389,16 @@ constraint_merge(S,C) ->
%% get the least common size constraint
SZs = get_constraints(C3,'SizeConstraint'),
CombSZ = intersection_of_size(S,SZs),
- CminusSVs=ordsets:subtract(ordsets:from_list(C3),ordsets:from_list(SVs)),
- % CminusSVsVRs = ordsets:subtract(ordsets:from_list(CminusSVs),
-% ordsets:from_list(VRs)),
- RestC = ordsets:subtract(ordsets:from_list(CminusSVs),
- ordsets:from_list(SZs)),
+ RestC = ordsets:subtract(ordsets:from_list(C3),
+ ordsets:from_list(SZs ++ VRs ++ SVs)),
%% get the least common combined constraint. That is the union of each
- %% deep costraint and merge of single value and value range constraints
- NewCs = combine_constraints(S,CombSV,CombVR,CombSZ++RestC),
- [X||X <- lists:flatten(NewCs),
- X /= intersection,
- X /= union].
+ %% deep constraint and merge of single value and value range constraints.
+ %% FIXME: Removing 'intersection' from the flattened list essentially
+ %% means that intersections are converted to unions!
+ Cs = combine_constraints(S, CombSV, CombVR, CombSZ++RestC),
+ [X || X <- lists:flatten(Cs),
+ X =/= intersection,
+ X =/= union].
%% constraint_union(S,C) takes a list of constraints as input and
%% merge them to a union. Unions are performed when two
@@ -4407,16 +4428,16 @@ constraint_union(_S,C) ->
constraint_union1(S,[A={'ValueRange',_},union,B={'ValueRange',_}|Rest],Acc) ->
AunionB = constraint_union_vr([A,B]),
- constraint_union1(S,Rest,Acc ++ AunionB);
+ constraint_union1(S, AunionB++Rest, Acc);
constraint_union1(S,[A={'SingleValue',_},union,B={'SingleValue',_}|Rest],Acc) ->
AunionB = constraint_union_sv(S,[A,B]),
constraint_union1(S,Rest,Acc ++ AunionB);
constraint_union1(S,[A={'SingleValue',_},union,B={'ValueRange',_}|Rest],Acc) ->
AunionB = union_sv_vr(S,A,B),
- constraint_union1(S,Rest,Acc ++ AunionB);
+ constraint_union1(S, AunionB++Rest, Acc);
constraint_union1(S,[A={'ValueRange',_},union,B={'SingleValue',_}|Rest],Acc) ->
AunionB = union_sv_vr(S,B,A),
- constraint_union1(S,Rest,Acc ++ AunionB);
+ constraint_union1(S, AunionB++Rest, Acc);
constraint_union1(S,[union|Rest],Acc) -> %skip when unsupported constraints
constraint_union1(S,Rest,Acc);
constraint_union1(S,[A|Rest],Acc) ->
@@ -4449,15 +4470,8 @@ constraint_union_vr(VR) ->
({_,{A1,_B1}},{_,{A2,_B2}}) when is_integer(A1),is_integer(A2),A1<A2 -> true;
({_,{A,B1}},{_,{A,B2}}) when B1=<B2->true;
(_,_)->false end,
- % sort and remove duplicates
- SortedVR = lists:sort(Fun,VR),
- RemoveDup = fun([],_) ->[];
- ([H],_) -> [H];
- ([H,H|T],F) -> F([H|T],F);
- ([H|T],F) -> [H|F(T,F)]
- end,
-
- constraint_union_vr(RemoveDup(SortedVR,RemoveDup),[]).
+ SortedVR = lists:usort(Fun,VR),
+ constraint_union_vr(SortedVR, []).
constraint_union_vr([],Acc) ->
lists:reverse(Acc);
@@ -4467,8 +4481,8 @@ constraint_union_vr([{_,{Lb,Ub2}}|Rest],[{_,{Lb,_Ub1}}|Acc]) -> %Ub2 > Ub1
constraint_union_vr(Rest,[{'ValueRange',{Lb,Ub2}}|Acc]);
constraint_union_vr([{_,{_,Ub}}|Rest],A=[{_,{_,Ub}}|_Acc]) ->
constraint_union_vr(Rest,A);
-constraint_union_vr([{_,{Lb2,Ub2}}|Rest],[{_,{Lb1,Ub1}}|Acc]) when Lb2=<Ub1,
- Ub2>Ub1->
+constraint_union_vr([{_,{Lb2,Ub2}}|Rest], [{_,{Lb1,Ub1}}|Acc])
+ when Ub1 =< Lb2, Ub1 < Ub2 ->
constraint_union_vr(Rest,[{'ValueRange',{Lb1,Ub2}}|Acc]);
constraint_union_vr([{_,{_,Ub2}}|Rest],A=[{_,{_,Ub1}}|_Acc]) when Ub2=<Ub1->
constraint_union_vr(Rest,A);
@@ -4589,9 +4603,11 @@ constraint_intersection(_S,C) ->
constraint_intersection1(S,[A,intersection,B|Rest],Acc) ->
AisecB = c_intersect(S,A,B),
- constraint_intersection1(S,Rest,AisecB++Acc);
+ constraint_intersection1(S, AisecB++Rest, Acc);
constraint_intersection1(S,[A|Rest],Acc) ->
constraint_intersection1(S,Rest,[A|Acc]);
+constraint_intersection1(_, [], [C]) ->
+ C;
constraint_intersection1(_,[],Acc) ->
lists:reverse(Acc).
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index b29a7b3048..2f711413bf 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -1099,10 +1099,11 @@ gen_dec_components_call(Erule,TopType,CL={Root1,ExtList,Root2},
{EmitExts,_} = gen_dec_comp_calls(NewExtList, Erule, TopType, OptTable,
DecInfObj, Ext, NumberOfOptionals,
Tpos, []),
+ NumExtsToSkip = ext_length(ExtList),
Finish =
fun(St) ->
emit([{next,bytes},"= ?RT_PER:skipextensions(",{curr,bytes},",",
- length(ExtList)+1,",Extensions)"]),
+ NumExtsToSkip+1,",Extensions)"]),
asn1ct_name:new(bytes),
St
end,
@@ -1361,7 +1362,7 @@ gen_dec_line_open_type(_, _, _) ->
fun() -> St end}
end}.
-gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
+gen_dec_line_special(Erule, {typefield,_}, _TopType, Comp,
DecInfObj, Ext) ->
#'ComponentType'{name=Cname,typespec=Type,prop=Prop} = Comp,
fun({_BytesVar,PrevSt}) ->
@@ -1370,13 +1371,14 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
{Name,RestFieldNames} =
(Type#type.def)#'ObjectClassFieldType'.fieldname,
- asn1ct_name:new(tmpterm),
asn1ct_name:new(reason),
- emit([indent(2),"{",{curr,tmpterm},", ",{next,bytes},
- "} = ?RT_PER:decode_open_type(",{curr,bytes},
- ", []),",nl]),
- emit([indent(2),"case (catch ObjFun(",
- {asis,Name},",",{curr,tmpterm},",telltype,",
+ Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+ BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+ {TmpTerm,TempBuf} = asn1ct_imm:dec_slim_cg(Imm, BytesVar),
+ emit([com,nl,
+ {next,bytes}," = ",TempBuf,com,nl,
+ indent(2),"case (catch ObjFun(",
+ {asis,Name},",",TmpTerm,",telltype,",
{asis,RestFieldNames},")) of", nl]),
emit([indent(4),"{'EXIT',",{curr,reason},"} ->",nl]),
emit([indent(6),"exit({'Type not ",
@@ -1402,8 +1404,10 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
end,
{Name,RestFieldNames} =
(Type#type.def)#'ObjectClassFieldType'.fieldname,
- emit(["?RT_PER:decode_open_type(",{curr,bytes},
- ", []),",nl]),
+ Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+ BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+ asn1ct_imm:dec_code_gen(Imm, BytesVar),
+ emit([com,nl]),
if
Ext == noext andalso Prop == mandatory ->
emit([{curr,term}," =",nl," "]);
@@ -1429,8 +1433,9 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
end,
{[],PrevSt};
_ ->
- emit(["?RT_PER:decode_open_type(",{curr,bytes},
- ", [])"]),
+ Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+ BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+ asn1ct_imm:dec_code_gen(Imm, BytesVar),
RefedFieldName =
(Type#type.def)#'ObjectClassFieldType'.fieldname,
@@ -1440,10 +1445,12 @@ gen_dec_line_special(_, {typefield,_}, _TopType, Comp,
Prop}],PrevSt}
end
end;
-gen_dec_line_special(_, {objectfield,PrimFieldName1,PFNList}, _TopType,
+gen_dec_line_special(Erule, {objectfield,PrimFieldName1,PFNList}, _TopType,
Comp, _DecInfObj, _Ext) ->
fun({_BytesVar,PrevSt}) ->
- emit(["?RT_PER:decode_open_type(",{curr,bytes},", [])"]),
+ Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+ BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+ asn1ct_imm:dec_code_gen(Imm, BytesVar),
#'ComponentType'{name=Cname,prop=Prop} = Comp,
SaveBytes = [{Cname,{PrimFieldName1,PFNList},
asn1ct_gen:mk_var(asn1ct_name:curr(term)),
@@ -1666,20 +1673,15 @@ gen_dec_choice1(Erule,TopType,CompList,{ext,ExtPos,ExtNum}) ->
length(CompList)-ExtNum,",Ext ),",nl}),
emit({"{Cname,{Val,NewBytes}} = case Choice + Ext*",ExtPos-1," of",nl}),
gen_dec_choice2(Erule,TopType,CompList,{ext,ExtPos,ExtNum}),
- case Erule of
- per ->
- emit([";",nl,"_ -> {asn1_ExtAlt,",nl,
- " fun() -> ",nl,
- " {XTerm,XBytes} = ?RT_PER:decode_open_type(",
- {curr,bytes},",[]),",nl,
- " {binary_to_list(XTerm),XBytes}",nl,
- " end()}"]);
- _ ->
- emit([";",nl,"_ -> {asn1_ExtAlt, ?RT_PER:decode_open_type(",
- {curr,bytes},",[])}"])
- end,
- emit({nl,"end,",nl}),
- emit({nl,"{{Cname,Val},NewBytes}"}).
+ Imm = asn1ct_imm:per_dec_open_type(is_aligned(Erule)),
+ BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)),
+ emit([";",nl,
+ "_ ->",nl]),
+ {TmpTerm,TmpBuf} = asn1ct_imm:dec_slim_cg(Imm, BytesVar),
+ emit([com,nl,
+ "{asn1_ExtAlt,{",TmpTerm,com,TmpBuf,"}}",nl,
+ "end,",nl,nl,
+ "{{Cname,Val},NewBytes}"]).
gen_dec_choice2(Erule,TopType,L,Ext) ->
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index 00c3dd98b2..664dfc2086 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -114,16 +114,6 @@ gen_encode(Erules,Typename,Type) when is_record(Type,type) ->
_ -> % embedded type with constructed name
true
end,
- case lists:member(InnerType,['SET','SEQUENCE']) of
- true ->
- true;
- _ ->
- emit([nl,"'enc_",asn1ct_gen:list2name(Typename),
- "'({'",asn1ct_gen:list2name(Typename),
- "',Val}, TagIn",ObjFun,") ->",nl]),
- emit([" 'enc_",asn1ct_gen:list2name(Typename),
- "'(Val, TagIn",ObjFun,");",nl,nl])
- end,
emit(["'enc_",asn1ct_gen:list2name(Typename),
"'(Val, TagIn",ObjFun,") ->",nl," "]),
asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type);
@@ -157,15 +147,6 @@ gen_encode_user(Erules,D) when is_record(D,typedef) ->
"'(Val",") ->",nl]),
emit([" 'enc_",asn1ct_gen:list2name(Typename),
"'(Val, ", {asis,lists:reverse(Tag)},").",nl,nl]),
-
- case lists:member(InnerType,['SET','SEQUENCE']) of
- true ->
- true;
- _ ->
- emit({nl,"'enc_",asn1ct_gen:list2name(Typename),
- "'({'",asn1ct_gen:list2name(Typename),"',Val}, TagIn) ->",nl}),
- emit({" 'enc_",asn1ct_gen:list2name(Typename),"'(Val, TagIn);",nl,nl})
- end,
emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val, TagIn) ->",nl}),
CurrentMod = get(currmod),
case asn1ct_gen:type(InnerType) of
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index eb4cfdccc6..af19edb908 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -79,18 +79,6 @@ gen_encode(Erules,Typename,Type) when is_record(Type,type) ->
end,
case asn1ct_gen:type(InnerType) of
{constructed,bif} ->
- case InnerType of
- 'SET' ->
- true;
- 'SEQUENCE' ->
- true;
- _ ->
- emit({nl,"'enc_",asn1ct_gen:list2name(Typename),
- "'({'",asn1ct_gen:list2name(Typename),
- "',Val}",ObjFun,") ->",nl}),
- emit({"'enc_",asn1ct_gen:list2name(Typename),
- "'(Val",ObjFun,");",nl,nl})
- end,
emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val",ObjFun,
") ->",nl}),
asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type);
@@ -943,7 +931,6 @@ gen_objset_dec(ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,_ClFields,
_NthObj) ->
emit({"'getdec_",ObjSetName,"'(_, _) ->",nl}),
emit({indent(3),"fun(Attr1, Bytes, _,_) ->",nl}),
-%% emit({indent(6),"?RT_PER:decode_open_type(Bytes,[])",nl}),
emit({indent(6),"{Bytes,Attr1}",nl}),
emit({indent(3),"end.",nl,nl}),
ok;
@@ -959,76 +946,42 @@ emit_default_getdec(ObjSetName,UniqueName) ->
emit([indent(2), "fun(C,V,_,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},",ErrV}}) end"]).
-gen_inlined_dec_funs(Fields,[{typefield,Name,_}|Rest],
- ObjSetName,NthObj) ->
- CurrMod = get(currmod),
- InternalDefFunName = [NthObj,Name,ObjSetName],
- case lists:keysearch(Name,1,Fields) of
- {value,{_,Type}} when is_record(Type,type) ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- N=emit_inner_of_decfun(Type,InternalDefFunName),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj+N);
- {value,{_,Type}} when is_record(Type,typedef) ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- emit({indent(9),{asis,Name}," ->",nl}),
- N=emit_inner_of_decfun(Type,InternalDefFunName),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj+N);
- {value,{_,#'Externaltypereference'{module=CurrMod,type=T}}} ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- emit({indent(9),{asis,Name}," ->",nl}),
- emit([indent(12),"'dec_",T,"'(Val, telltype)"]),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj);
- {value,{_,#'Externaltypereference'{module=M,type=T}}} ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- emit({indent(9),{asis,Name}," ->",nl}),
- emit([indent(12),"'",M,"':'dec_",T,"'(Val, telltype)"]),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj);
- false ->
- emit([indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl,
- indent(9),{asis,Name}," ->{Val,Type}"]),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj)
- end;
-gen_inlined_dec_funs(Fields,[_|Rest],ObjSetName,NthObj) ->
- gen_inlined_dec_funs(Fields,Rest,ObjSetName,NthObj);
-gen_inlined_dec_funs(_,[],_,NthObj) ->
+gen_inlined_dec_funs(Fields, List, ObjSetName, NthObj0) ->
+ emit([indent(3),"fun(Type, Val, _, _) ->",nl,
+ indent(6),"case Type of",nl]),
+ NthObj = gen_inlined_dec_funs1(Fields, List, ObjSetName, "", NthObj0),
+ emit([nl,indent(6),"end",nl,
+ indent(3),"end"]),
NthObj.
-gen_inlined_dec_funs1(Fields,[{typefield,Name,_}|Rest],
- ObjSetName,NthObj) ->
+gen_inlined_dec_funs1(Fields, [{typefield,Name,_}|Rest],
+ ObjSetName, Sep0, NthObj) ->
CurrentMod = get(currmod),
InternalDefFunName = [NthObj,Name,ObjSetName],
- N=case lists:keysearch(Name,1,Fields) of
- {value,{_,Type}} when is_record(Type,type) ->
- emit({";",nl}),
- emit_inner_of_decfun(Type,InternalDefFunName);
- {value,{_,Type}} when is_record(Type,typedef) ->
- emit({";",nl,indent(9),{asis,Name}," ->",nl}),
- emit_inner_of_decfun(Type,InternalDefFunName);
- {value,{_,#'Externaltypereference'{module=CurrentMod,type=T}}} ->
- emit([";",nl,indent(9),{asis,Name}," ->",nl]),
- emit([indent(12),"'dec_",T,"'(Val,telltype)"]),
- 0;
- {value,{_,#'Externaltypereference'{module=M,type=T}}} ->
- emit([";",nl,indent(9),{asis,Name}," ->",nl]),
- emit([indent(12),"'",M,"'",":'dec_",T,"'(Val,telltype)"]),
- 0;
- false ->
- emit([";",nl,
- indent(9),{asis,Name}," ->{Val,Type}"]),
- 0
- end,
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj+N);
-gen_inlined_dec_funs1(Fields,[_|Rest],ObjSetName,NthObj)->
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj);
-gen_inlined_dec_funs1(_,[],_,NthObj) ->
- emit({nl,indent(6),"end",nl}),
- emit({indent(3),"end"}),
- NthObj.
+ emit(Sep0),
+ Sep = [";",nl],
+ N = case lists:keyfind(Name, 1, Fields) of
+ {_,#type{}=Type} ->
+ emit_inner_of_decfun(Type, InternalDefFunName);
+ {_,#typedef{}=Type} ->
+ emit([indent(9),{asis,Name}," ->",nl]),
+ emit_inner_of_decfun(Type, InternalDefFunName);
+ {_,#'Externaltypereference'{module=CurrentMod,type=T}} ->
+ emit([indent(9),{asis,Name}," ->",nl,
+ indent(12),"'dec_",T,"'(Val,telltype)"]),
+ 0;
+ {_,#'Externaltypereference'{module=M,type=T}} ->
+ emit([indent(9),{asis,Name}," ->",nl,
+ indent(12),"'",M,"':'dec_",T,"'(Val,telltype)"]),
+ 0;
+ false ->
+ emit([indent(9),{asis,Name}," -> {Val,Type}"]),
+ 0
+ end,
+ gen_inlined_dec_funs1(Fields, Rest, ObjSetName, Sep, NthObj+N);
+gen_inlined_dec_funs1(Fields, [_|Rest], ObjSetName, Sep, NthObj) ->
+ gen_inlined_dec_funs1(Fields, Rest, ObjSetName, Sep, NthObj);
+gen_inlined_dec_funs1(_, [], _, _, NthObj) -> NthObj.
emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},
InternalDefFunName) ->
@@ -1147,6 +1100,10 @@ gen_dec_imm(Erule, #type{def=Name,constraint=C}) ->
end,
gen_dec_imm_1(Name, C, Aligned).
+gen_dec_imm_1('ASN1_OPEN_TYPE', Constraint, Aligned) ->
+ imm_decode_open_type(Constraint, Aligned);
+gen_dec_imm_1('ANY', _Constraint, Aligned) ->
+ imm_decode_open_type([], Aligned);
gen_dec_imm_1('BOOLEAN', _Constr, _Aligned) ->
asn1ct_imm:per_dec_boolean();
gen_dec_imm_1({'ENUMERATED',{Base,Ext}}, _Constr, Aligned) ->
@@ -1239,36 +1196,6 @@ gen_dec_prim_1(Erule,
",",{asis,Constraint},")"});
'UTF8String' ->
emit({"?RT_PER:decode_UTF8String(",BytesVar,")"});
- 'ANY' ->
- case Erule of
- per ->
- emit(["fun() -> {XTerm,YTermXBytes} = ?RT_PER:decode_open_type(",BytesVar,",",{asis,Constraint}, "), {binary_to_list(XTerm),XBytes} end ()"]);
- _ ->
- emit(["?RT_PER:decode_open_type(",BytesVar,",",
- {asis,Constraint}, ")"])
- end;
- 'ASN1_OPEN_TYPE' ->
- case Constraint of
- [#'Externaltypereference'{type=Tname}] ->
- emit(["fun(FBytes) ->",nl,
- " {XTerm,XBytes} = "]),
- emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
- emit([" {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
- emit([" {YTerm,XBytes} end(",BytesVar,")"]);
- [#type{def=#'Externaltypereference'{type=Tname}}] ->
- emit(["fun(FBytes) ->",nl,
- " {XTerm,XBytes} = "]),
- emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
- emit([" {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
- emit([" {YTerm,XBytes} end(",BytesVar,")"]);
- _ ->
- case Erule of
- per ->
- emit(["fun() -> {XTerm,XBytes} = ?RT_PER:decode_open_type(",BytesVar,", []), {binary_to_list(XTerm),XBytes} end()"]);
- _ ->
- emit(["?RT_PER:decode_open_type(",BytesVar,",[])"])
- end
- end;
#'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(Typename) of
{fixedtypevaluefield,_,InnerType} ->
@@ -1334,3 +1261,22 @@ extaddgroup2sequence([C|T],ExtNum,Acc) ->
extaddgroup2sequence(T,ExtNum,[C|Acc]);
extaddgroup2sequence([],_,Acc) ->
lists:reverse(Acc).
+
+imm_decode_open_type([#'Externaltypereference'{type=Tname}], Aligned) ->
+ imm_dec_open_type_1(Tname, Aligned);
+imm_decode_open_type([#type{def=#'Externaltypereference'{type=Tname}}],
+ Aligned) ->
+ imm_dec_open_type_1(Tname, Aligned);
+imm_decode_open_type(_, Aligned) ->
+ asn1ct_imm:per_dec_open_type(Aligned).
+
+imm_dec_open_type_1(Type, Aligned) ->
+ D = fun(OpenType, Buf) ->
+ asn1ct_name:new(tmpval),
+ emit(["begin",nl,
+ "{",{curr,tmpval},",_} = ",
+ "dec_",Type,"(",OpenType,", mandatory),",nl,
+ "{",{curr,tmpval},com,Buf,"}",nl,
+ "end"])
+ end,
+ {call,D,asn1ct_imm:per_dec_open_type(Aligned)}.
diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
index ecd212c3e3..4f4563833f 100644
--- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
+++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
@@ -69,18 +69,6 @@ gen_encode(Erules,Typename,Type) when is_record(Type,type) ->
end,
case asn1ct_gen:type(InnerType) of
{constructed,bif} ->
- case InnerType of
- 'SET' ->
- true;
- 'SEQUENCE' ->
- true;
- _ ->
- emit({nl,"'enc_",asn1ct_gen:list2name(Typename),
- "'({'",asn1ct_gen:list2name(Typename),
- "',Val}",ObjFun,") ->",nl}),
- emit({"'enc_",asn1ct_gen:list2name(Typename),
- "'(Val",ObjFun,");",nl,nl})
- end,
emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val",ObjFun,
") ->",nl}),
asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type);
@@ -417,35 +405,46 @@ emit_enc_octet_string(_Erules,Constraint,Value) ->
asn1ct_name:new(tmpval),
emit({" begin",nl}),
emit({" [",{curr,tmpval},"] = ",Value,",",nl}),
- emit({" [10,8,",{curr,tmpval},"]",nl}),
+ emit([" [[10,8],",{curr,tmpval},"]",nl]),
emit(" end");
2 ->
asn1ct_name:new(tmpval),
- emit({" begin",nl}),
- emit({" [",{curr,tmpval},",",{next,tmpval},"] = ",
- Value,",",nl}),
- emit({" [[10,8,",{curr,tmpval},"],[10,8,",
- {next,tmpval},"]]",nl}),
- emit(" end"),
- asn1ct_name:new(tmpval);
- Sv when is_integer(Sv),Sv =< 256 ->
+ emit([" begin",nl,
+ " ",{curr,tmpval}," = ",Value,",",nl,
+ " case length(",{curr,tmpval},") of",nl,
+ " 2 ->",nl,
+ " [[45,16,2]|",{curr,tmpval},"];",nl,
+ " _ ->",nl,
+ " exit({error,{value_out_of_bounds,",
+ {curr,tmpval},"}})",nl,
+ " end",nl,
+ " end"]);
+ Sv when is_integer(Sv), Sv < 256 ->
asn1ct_name:new(tmpval),
- emit({" begin",nl}),
- emit({" case length(",Value,") of",nl}),
- emit([" ",{curr,tmpval}," when ",{curr,tmpval}," == ",Sv," ->"]),
- emit([" [2,20,",{curr,tmpval},",",Value,"];",nl]),
- emit({" _ -> exit({error,{value_out_of_bounds,",
- Value,"}})", nl," end",nl}),
- emit(" end");
+ asn1ct_name:new(tmplen),
+ emit([" begin",nl,
+ " ",{curr,tmpval}," = ",Value,",",nl,
+ " case length(",{curr,tmpval},") of",nl,
+ " ",Sv,"=",{curr,tmplen}," ->",nl,
+ " [20,",{curr,tmplen},"|",{curr,tmpval},"];",nl,
+ " _ ->",nl,
+ " exit({error,{value_out_of_bounds,",
+ {curr,tmpval},"}})",nl,
+ " end",nl,
+ " end"]);
Sv when is_integer(Sv),Sv =< 65535 ->
asn1ct_name:new(tmpval),
- emit({" begin",nl}),
- emit({" case length(",Value,") of",nl}),
- emit([" ",{curr,tmpval}," when ",{curr,tmpval}," == ",Sv," ->"]),
- emit([" [2,21,",{curr,tmpval},",",Value,"];",nl]),
- emit({" _ -> exit({error,{value_out_of_bounds,",
- Value,"}})",nl," end",nl}),
- emit(" end");
+ asn1ct_name:new(tmplen),
+ emit([" begin",nl,
+ " ",{curr,tmpval}," = ",Value,",",nl,
+ " case length(",{curr,tmpval},") of",nl,
+ " ",Sv,"=",{curr,tmplen}," ->",nl,
+ " [<<21,",{curr,tmplen},":16>>|",Value,"];",nl,
+ " _ ->",nl,
+ " exit({error,{value_out_of_bounds,",
+ {curr,tmpval},"}})",nl,
+ " end",nl,
+ " end"]);
C ->
emit({" ?RT_PER:encode_octet_string(",{asis,C},",false,",Value,")",nl})
end.
@@ -1292,7 +1291,6 @@ gen_objset_dec(ObjSetName,_,['EXTENSIONMARK'],_ClName,_ClFields,
_NthObj) ->
emit({"'getdec_",ObjSetName,"'(_, _) ->",nl}),
emit({indent(3),"fun(Attr1, Bytes, _, _) ->",nl}),
- %% emit({indent(6),"?RT_PER:decode_open_type(Bytes,[])",nl}),
emit({indent(6),"{Bytes,Attr1}",nl}),
emit({indent(3),"end.",nl,nl}),
ok;
@@ -1308,77 +1306,42 @@ emit_default_getdec(ObjSetName,UniqueName) ->
emit([indent(2), "fun(C,V,_,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},",ErrV}}) end"]).
-gen_inlined_dec_funs(Fields,[{typefield,Name,_}|Rest],
- ObjSetName,NthObj) ->
- CurrMod = get(currmod),
- InternalDefFunName = [NthObj,Name,ObjSetName],
- case lists:keysearch(Name,1,Fields) of
- {value,{_,Type}} when is_record(Type,type) ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- N=emit_inner_of_decfun(Type,InternalDefFunName),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj+N);
- {value,{_,Type}} when is_record(Type,typedef) ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- emit({indent(9),{asis,Name}," ->",nl}),
- N=emit_inner_of_decfun(Type,InternalDefFunName),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj+N);
- {value,{_,#'Externaltypereference'{module=CurrMod,type=T}}} ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- emit({indent(9),{asis,Name}," ->",nl}),
- emit([indent(12),"'dec_",T,"'(Val, telltype)"]),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj);
- {value,{_,#'Externaltypereference'{module=M,type=T}}} ->
- emit({indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl}),
- emit({indent(9),{asis,Name}," ->",nl}),
- emit([indent(12),"'",M,"':'dec_",T,"'(Val, telltype)"]),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj);
- false ->
- emit([indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl,
- indent(9),{asis,Name}," -> {Val,Type}"]),
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj)
- end;
-gen_inlined_dec_funs(Fields,[_|Rest],ObjSetName,NthObj) ->
- gen_inlined_dec_funs(Fields,Rest,ObjSetName,NthObj);
-gen_inlined_dec_funs(_,[],_,NthObj) ->
+gen_inlined_dec_funs(Fields, List, ObjSetName, NthObj0) ->
+ emit([indent(3),"fun(Type, Val, _, _) ->",nl,
+ indent(6),"case Type of",nl]),
+ NthObj = gen_inlined_dec_funs1(Fields, List, ObjSetName, "", NthObj0),
+ emit([nl,indent(6),"end",nl,
+ indent(3),"end"]),
NthObj.
-gen_inlined_dec_funs1(Fields,[{typefield,Name,_}|Rest],
- ObjSetName,NthObj) ->
+gen_inlined_dec_funs1(Fields, [{typefield,Name,_}|Rest],
+ ObjSetName, Sep0, NthObj) ->
CurrentMod = get(currmod),
InternalDefFunName = [NthObj,Name,ObjSetName],
- N=
- case lists:keysearch(Name,1,Fields) of
- {value,{_,Type}} when is_record(Type,type) ->
- emit({";",nl}),
- emit_inner_of_decfun(Type,InternalDefFunName);
- {value,{_,Type}} when is_record(Type,typedef) ->
- emit({";",nl,indent(9),{asis,Name}," ->",nl}),
- emit_inner_of_decfun(Type,InternalDefFunName);
- {value,{_,#'Externaltypereference'{module=CurrentMod,type=T}}} ->
- emit([";",nl,indent(9),{asis,Name}," ->",nl]),
- emit([indent(12),"'dec_",T,"'(Val,telltype)"]),
- 0;
- {value,{_,#'Externaltypereference'{module=M,type=T}}} ->
- emit([";",nl,indent(9),{asis,Name}," ->",nl]),
- emit([indent(12),"'",M,"':'dec_",T,"'(Val,telltype)"]),
- 0;
- false ->
- emit([";",nl,
- indent(9),{asis,Name}," -> {Val,Type}"]),
- 0
- end,
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj+N);
-gen_inlined_dec_funs1(Fields,[_|Rest],ObjSetName,NthObj)->
- gen_inlined_dec_funs1(Fields,Rest,ObjSetName,NthObj);
-gen_inlined_dec_funs1(_,[],_,NthObj) ->
- emit({nl,indent(6),"end",nl}),
- emit({indent(3),"end"}),
- NthObj.
+ emit(Sep0),
+ Sep = [";",nl],
+ N = case lists:keyfind(Name, 1, Fields) of
+ {_,#type{}=Type} ->
+ emit_inner_of_decfun(Type, InternalDefFunName);
+ {_,#typedef{}=Type} ->
+ emit([indent(9),{asis,Name}," ->",nl]),
+ emit_inner_of_decfun(Type, InternalDefFunName);
+ {_,#'Externaltypereference'{module=CurrentMod,type=T}} ->
+ emit([indent(9),{asis,Name}," ->",nl,
+ indent(12),"'dec_",T,"'(Val,telltype)"]),
+ 0;
+ {_,#'Externaltypereference'{module=M,type=T}} ->
+ emit([indent(9),{asis,Name}," ->",nl,
+ indent(12),"'",M,"':'dec_",T,"'(Val,telltype)"]),
+ 0;
+ false ->
+ emit([indent(9),{asis,Name}," -> {Val,Type}"]),
+ 0
+ end,
+ gen_inlined_dec_funs1(Fields, Rest, ObjSetName, Sep, NthObj+N);
+gen_inlined_dec_funs1(Fields, [_|Rest], ObjSetName, Sep, NthObj) ->
+ gen_inlined_dec_funs1(Fields, Rest, ObjSetName, Sep, NthObj);
+gen_inlined_dec_funs1(_, [], _, _, NthObj) -> NthObj.
emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},
InternalDefFunName) ->
@@ -1579,25 +1542,9 @@ gen_dec_prim(Erules,Att,BytesVar) ->
'UTF8String' ->
emit({"?RT_PER:decode_UTF8String(",BytesVar,")"});
'ANY' ->
- emit(["?RT_PER:decode_open_type(",BytesVar,",",
- {asis,Constraint}, ")"]);
+ asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
'ASN1_OPEN_TYPE' ->
- case Constraint of
- [#'Externaltypereference'{type=Tname}] ->
- emit(["fun(FBytes) ->",nl,
- " {XTerm,XBytes} = "]),
- emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
- emit([" {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
- emit([" {YTerm,XBytes} end(",BytesVar,")"]);
- [#type{def=#'Externaltypereference'{type=Tname}}] ->
- emit(["fun(FBytes) ->",nl,
- " {XTerm,XBytes} = "]),
- emit(["?RT_PER:decode_open_type(FBytes,[]),",nl]),
- emit([" {YTerm,_} = dec_",Tname,"(XTerm,mandatory),",nl]),
- emit([" {YTerm,XBytes} end(",BytesVar,")"]);
- _ ->
- emit(["?RT_PER:decode_open_type(",BytesVar,",[])"])
- end;
+ asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar);
#'ObjectClassFieldType'{} ->
case asn1ct_gen:get_inner(Att#type.def) of
{fixedtypevaluefield,_,InnerType} ->
diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl
index 7301f49085..9e1fcce2b1 100644
--- a/lib/asn1/src/asn1ct_parser2.erl
+++ b/lib/asn1/src/asn1ct_parser2.erl
@@ -924,19 +924,8 @@ parse_UnionsRec([{'|',_}|Rest]) ->
{V1,V2} ->
{[V1,union,V2],Rest3}
end;
-parse_UnionsRec([{'UNION',_}|Rest]) ->
- {InterSec,Rest2} = parse_Intersections(Rest),
- {URec,Rest3} = parse_UnionsRec(Rest2),
- case {InterSec,URec} of
- {V1,[]} ->
- {V1,Rest3};
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {{'SingleValue',ordsets:union(to_set(V1),to_set(V2))},Rest3};
- {V1,V2} when is_list(V2) ->
- {[V1] ++ [union|V2],Rest3};
- {V1,V2} ->
- {[V1,union,V2],Rest3}
- end;
+parse_UnionsRec([{'UNION',Info}|Rest]) ->
+ parse_UnionsRec([{'|',Info}|Rest]);
parse_UnionsRec(Tokens) ->
{[],Tokens}.
@@ -971,20 +960,8 @@ parse_IElemsRec([{'^',_}|Rest]) ->
{V1,V2} ->
{[V1,intersection,V2],Rest3}
end;
-parse_IElemsRec([{'INTERSECTION',_}|Rest]) ->
- {InterSec,Rest2} = parse_IntersectionElements(Rest),
- {IRec,Rest3} = parse_IElemsRec(Rest2),
- case {InterSec,IRec} of
- {{'SingleValue',V1},{'SingleValue',V2}} ->
- {{'SingleValue',
- ordsets:intersection(to_set(V1),to_set(V2))},Rest3};
- {V1,[]} ->
- {V1,Rest3};
- {V1,V2} when is_list(V2) ->
- {[V1] ++ [intersection|V2],Rest3};
- {V1,V2} ->
- {[V1,intersection,V2],Rest3}
- end;
+parse_IElemsRec([{'INTERSECTION',Info}|Rest]) ->
+ parse_IElemsRec([{'^',Info}|Rest]);
parse_IElemsRec(Tokens) ->
{[],Tokens}.
diff --git a/lib/asn1/src/asn1rt_uper_bin.erl b/lib/asn1/src/asn1rt_uper_bin.erl
index 9410c3ef90..fc65d80245 100644
--- a/lib/asn1/src/asn1rt_uper_bin.erl
+++ b/lib/asn1/src/asn1rt_uper_bin.erl
@@ -120,14 +120,15 @@ fixextensions(Pos,ExtPos,Val,Acc) ->
end,
fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
-skipextensions(Bytes,Nr,ExtensionBitPattern) ->
- case (catch element(Nr,ExtensionBitPattern)) of
- 1 ->
+skipextensions(Bytes,Nr,ExtensionBitstr) when is_bitstring(ExtensionBitstr) ->
+ Prev = Nr - 1,
+ case ExtensionBitstr of
+ <<_:Prev,1:1,_/bitstring>> ->
{_,Bytes2} = decode_open_type(Bytes,[]),
- skipextensions(Bytes2, Nr+1, ExtensionBitPattern);
- 0 ->
- skipextensions(Bytes, Nr+1, ExtensionBitPattern);
- {'EXIT',_} -> % badarg, no more extensions
+ skipextensions(Bytes2, Nr+1, ExtensionBitstr);
+ <<_:Prev,0:1,_/bitstring>> ->
+ skipextensions(Bytes, Nr+1, ExtensionBitstr);
+ _ ->
Bytes
end.
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index 38ec72c473..3d3ed65a65 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -20,19 +20,10 @@
-module(asn1_SUITE).
--define(only_per(Func),
- if Rule =:= per -> Func;
- true -> ok
- end).
-define(only_ber(Func),
if Rule =:= ber -> Func;
true -> ok
end).
--define(only_uper(Func),
- case Rule of
- uper -> Func;
- _ -> ok
- end).
-compile(export_all).
@@ -62,7 +53,8 @@ groups() ->
[{compile, parallel([]),
[c_syntax,
c_string,
- c_implicit_before_choice]},
+ c_implicit_before_choice,
+ constraint_equivalence]},
{ber, parallel([]),
[ber_choiceinseq,
@@ -188,7 +180,6 @@ groups() ->
testDoubleEllipses,
test_x691,
ticket_6143,
- testExtensionAdditionGroup,
test_OTP_9688]},
{performance, [],
@@ -321,12 +312,12 @@ testCompactBitString(Config, Rule, Opts) ->
asn1_test_lib:compile("PrimStrings", Config,
[Rule, compact_bit_string|Opts]),
testCompactBitString:compact_bit_string(Rule),
- ?only_uper(testCompactBitString:bit_string_unnamed(Rule)),
- ?only_per(testCompactBitString:bit_string_unnamed(Rule)),
- ?only_per(testCompactBitString:ticket_7734(Rule)),
- ?only_per(asn1_test_lib:compile("Constraints", Config,
- [Rule, compact_bit_string|Opts])),
- ?only_per(testCompactBitString:otp_4869(Rule)).
+ testCompactBitString:bit_string_unnamed(Rule),
+ testCompactBitString:bit_string_unnamed(Rule),
+ testCompactBitString:ticket_7734(Rule),
+ asn1_test_lib:compile("Constraints", Config,
+ [Rule, compact_bit_string|Opts]),
+ testCompactBitString:otp_4869(Rule).
testPrimStrings(Config) -> test(Config, fun testPrimStrings/3).
testPrimStrings(Config, Rule, Opts) ->
@@ -439,7 +430,8 @@ testSeqExtension(Config) -> test(Config, fun testSeqExtension/3).
testSeqExtension(Config, Rule, Opts) ->
asn1_test_lib:compile_all(["External", "SeqExtension"], Config,
[Rule|Opts]),
- testSeqExtension:main(Rule).
+ DataDir = ?config(data_dir, Config),
+ testSeqExtension:main(DataDir, [Rule|Opts]).
testSeqExternal(Config) -> test(Config, fun testSeqExternal/3).
testSeqExternal(Config, Rule, Opts) ->
@@ -627,6 +619,34 @@ c_implicit_before_choice(Config, Rule, Opts) ->
{error, _R2} = asn1ct:compile(filename:join(DataDir, "CCSNARG3"),
[Rule, {outdir, CaseDir}|Opts]).
+constraint_equivalence(Config) ->
+ DataDir = ?config(data_dir, Config),
+ CaseDir = ?config(case_dir, Config),
+ Asn1Spec = "ConstraintEquivalence",
+ Asn1Src = filename:join(DataDir, Asn1Spec),
+ ok = asn1ct:compile(Asn1Src, [abs,{outdir,CaseDir}]),
+ AbsFile = filename:join(CaseDir, Asn1Spec++".abs"),
+ {ok,Terms} = file:consult(AbsFile),
+ Cs = [begin
+ 'INTEGER' = element(3, Type), %Assertion.
+ Constraints = element(4, Type),
+ Name1 = atom_to_list(Name0),
+ {Name,_} = lists:splitwith(fun(C) -> C =/= $X end, Name1),
+ {Name,Constraints}
+ end || {typedef,_,_,Name0,Type} <- Terms],
+ R = sofs:relation(Cs, [{name,constraint}]),
+ F0 = sofs:relation_to_family(R),
+ F = sofs:to_external(F0),
+ Diff = [E || {_,L}=E <- F, length(L) > 1],
+ case Diff of
+ [] ->
+ ok;
+ [_|_] ->
+ io:put_chars("Not equivalent:\n"),
+ [io:format("~s: ~p\n", [N,D]) || {N,D} <- Diff],
+ test_server:fail(length(Diff))
+ end.
+
parse(Config) ->
[asn1_test_lib:compile(M, Config, [abs]) || M <- test_modules()].
diff --git a/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1 b/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
new file mode 100644
index 0000000000..6a97c1b38e
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
@@ -0,0 +1,42 @@
+ConstraintEquivalence DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+ SingleValueX42 ::= INTEGER (42)
+ SingleValueX1 ::= INTEGER ((42) ^ (42))
+ SingleValueX2 ::= INTEGER ((42) INTERSECTION (42))
+ SingleValueX3 ::= INTEGER ((42) | (42))
+ SingleValueX4 ::= INTEGER ((42) UNION (42))
+ SingleValueX5 ::= INTEGER ((42) INTERSECTION (MIN..MAX))
+ SingleValueX6 ::= INTEGER ((42) INTERSECTION (40..49))
+ SingleValueX7 ::= INTEGER (42..42)
+
+ UnconstrainedX0 ::= INTEGER
+ UnconstrainedX1 ::= INTEGER (MIN..MAX)
+ UnconstrainedX2 ::= INTEGER (1|(MIN..MAX))
+ UnconstrainedX3 ::= INTEGER (1..10|(MIN..MAX))
+ UnconstrainedX4 ::= INTEGER ((MIN..MAX)|9|10)
+ UnconstrainedX5 ::= INTEGER ((MIN..MAX)|10..20)
+ UnconstrainedX6 ::= INTEGER ((MIN..MAX) UNION (10..20))
+
+ RangeX00 ::= INTEGER (5..10)
+ RangeX01 ::= INTEGER (4<..<11)
+ RangeX02 ::= INTEGER (5..<11)
+ RangeX03 ::= INTEGER (4<..10)
+ RangeX04 ::= INTEGER (5|6|7|8|9|10)
+ RangeX05 ::= INTEGER (10|9|8|7|6|5)
+ RangeX06 ::= INTEGER (5|6|7..10)
+
+ RangeX10 ::= INTEGER ((5..6) UNION (7..8) UNION (9|10))
+ RangeX11 ::= INTEGER ((5|6) UNION (7..8) UNION (9|10))
+ RangeX12 ::= INTEGER ((5|6) UNION (7|8) UNION (9|10))
+ RangeX13 ::= INTEGER ((5|6) UNION (7) UNION (8..10))
+ RangeX14 ::= INTEGER ((5|6) UNION (7) UNION (8..10))
+ RangeX15 ::= INTEGER ((5|6) UNION (7) UNION ((8..8)|(9..9)|(10)))
+ RangeX16 ::= INTEGER ((5|6) UNION (7) UNION (7<..<11))
+
+ RangeX20 ::= INTEGER (0..20) (5..10)
+ RangeX21 ::= INTEGER (0..10) (5..20)
+ RangeX22 ::= INTEGER (0..10) (5..20) (MIN..MAX)
+ RangeX23 ::= INTEGER ((0..10) INTERSECTION (5..20) ^ (MIN..MAX))
+ RangeX24 ::= INTEGER ((5|6|7|8|9|10) INTERSECTION (5..20) ^ (MIN..MAX))
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1 b/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
index 7cb47e9792..9b6b34a776 100644
--- a/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/PrimStrings.asn1
@@ -59,6 +59,19 @@ BS1024 ::= BIT STRING (SIZE (1024))
FixedOs65536 ::= OCTET STRING (SIZE (65536))
FixedOs65537 ::= OCTET STRING (SIZE (65537))
+ OsFixedStrings ::= SEQUENCE {
+ b1 BOOLEAN, -- Unalign
+ s0 OCTET STRING (SIZE (0)),
+ s1 OCTET STRING (SIZE (1)),
+ s2 OCTET STRING (SIZE (2)),
+ s3 OCTET STRING (SIZE (3)),
+ b2 BOOLEAN, -- Unalign
+ s255 OCTET STRING (SIZE (255)),
+ s256 OCTET STRING (SIZE (256)),
+ s257 OCTET STRING (SIZE (257)),
+ i INTEGER (0..1024)
+ }
+
OsAlignment ::= SEQUENCE {
b1 BOOLEAN,
s1 Os,
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
index bb0a7cca3a..5fda19303a 100644
--- a/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
@@ -31,7 +31,35 @@ SeqExt4 ::= SEQUENCE
int INTEGER
}
+SeqExt5 ::= SEQUENCE
+{
+ ...,
+ [[ name OCTET STRING (SIZE (1..8)),
+ shoesize INTEGER ]]
+}
+
+SeqExt6 ::= SEQUENCE
+{
+ -- The spaces between the ellipsis and the comma will prevent them
+ -- from being removed.
+ ... ,
+ [[ i1 [100] INTEGER, i2 [101] INTEGER, i3 [102] INTEGER ]],
+ [[ i4 [104] INTEGER, i5 [105] INTEGER ]],
+ [[ i6 [106] INTEGER, i7 [107] INTEGER ]]
+}
+
SeqExt1X ::= XSeqExt1
SeqExt2X ::= XSeqExt2
+SuperSeq ::= SEQUENCE
+{
+ s1 SeqExt1,
+ s2 SeqExt2,
+ s3 SeqExt3,
+ s4 SeqExt4,
+ s5 SeqExt5,
+ s6 SeqExt6,
+ i INTEGER
+}
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/testobj.erl b/lib/asn1/test/asn1_SUITE_data/testobj.erl
index 80942f7e38..d9f60ca8a3 100644
--- a/lib/asn1/test/asn1_SUITE_data/testobj.erl
+++ b/lib/asn1/test/asn1_SUITE_data/testobj.erl
@@ -883,7 +883,7 @@ initial_ue_ies() ->
cn_domain_indicator() ->
- {'CN-DomainIndicator', 'ps-domain'}.
+ 'ps-domain'.
init_lai() ->
#'ProtocolIE-Field'{
@@ -1279,11 +1279,11 @@ reset() ->
protocolIEs = reset_ies()
}.
reset_ies() ->
- {'Reset_protocolIEs', % this identifier is very unneccesary here
- [reset_cause(),
- cn_domain_ind(), % Se initial Ue
- init_global_rnc_id() % ---- " ----
- ]}.
+ [reset_cause(),
+ cn_domain_ind(), % Se initial Ue
+ init_global_rnc_id() % ---- " ----
+ ].
+
init_global_rnc_id() ->
#'ProtocolIE-Field'{
id = 86, % 86 = id-GlobalRNC-ID
@@ -1323,8 +1323,7 @@ reset_ack() ->
protocolIEs = reset_ack_ies()
}.
reset_ack_ies() ->
- {'ResetAcknowledge_protocolIEs', % very unneccesary
- [cn_domain_ind()]}. % Se initial Ue
+ [cn_domain_ind()]. % Se initial Ue
@@ -1336,13 +1335,12 @@ reset_res(IuSCId) ->
}.
reset_res_ies(IuSCId) ->
- {'ResetResource_protocolIEs', % very unneccesary
- [
- cn_domain_ind() % Se initial Ue
- ,reset_cause() % Se reset
- ,reset_res_list(IuSCId)
- ,init_global_rnc_id_reset_res() % ---- " ----
- ]}.
+ [
+ cn_domain_ind() % Se initial Ue
+ ,reset_cause() % Se reset
+ ,reset_res_list(IuSCId)
+ ,init_global_rnc_id_reset_res() % ---- " ----
+ ].
init_global_rnc_id_reset_res() ->
#'ProtocolIE-Field'{
diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl
index b75cfb6831..067d4d2bf7 100644
--- a/lib/asn1/test/testChoExtension.erl
+++ b/lib/asn1/test/testChoExtension.erl
@@ -25,42 +25,27 @@
extension(_Rules) ->
-
- ?line {ok,Bytes1} = asn1_wrapper:encode('ChoExtension','ChoExt1',{'ChoExt1',{bool,true}}),
- ?line {ok,{bool,true}} =
- asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes1)),
-
- ?line {ok,Bytes2} = asn1_wrapper:encode('ChoExtension','ChoExt1',{'ChoExt1',{int,33}}),
- ?line {ok,{int,33}} =
- asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes2)),
+ roundtrip('ChoExt1', {bool,true}),
+ roundtrip('ChoExt1', {int,33}),
%% A trick to encode with another compatible CHOICE type to test reception
%% extension alternative
- ?line {ok,Bytes2x} = asn1_wrapper:encode('ChoExtension','ChoExt1x',{str,"abc"}),
- ?line {ok,Val2x} =
+ {ok,Bytes2x} = asn1_wrapper:encode('ChoExtension','ChoExt1x',{str,"abc"}),
+ {ok,Val2x} =
asn1_wrapper:decode('ChoExtension','ChoExt1',lists:flatten(Bytes2x)),
io:format("Choice extension alternative = ~p~n",[Val2x]),
- ?line {ok,Bytes3} = asn1_wrapper:encode('ChoExtension','ChoExt2',{'ChoExt2',{bool,true}}),
- ?line {ok,{bool,true}} =
- asn1_wrapper:decode('ChoExtension','ChoExt2',lists:flatten(Bytes3)),
-
- ?line {ok,Bytes4} = asn1_wrapper:encode('ChoExtension','ChoExt2',{'ChoExt2',{int,33}}),
- ?line {ok,{int,33}} =
- asn1_wrapper:decode('ChoExtension','ChoExt2',lists:flatten(Bytes4)),
+ roundtrip('ChoExt2', {bool,true}),
+ roundtrip('ChoExt2', {int,33}),
+ roundtrip('ChoExt3', {bool,true}),
+ roundtrip('ChoExt3', {int,33}),
+ roundtrip('ChoExt4', {str,"abc"}),
- ?line {ok,Bytes5} = asn1_wrapper:encode('ChoExtension','ChoExt3',{'ChoExt3',{bool,true}}),
- ?line {ok,{bool,true}} =
- asn1_wrapper:decode('ChoExtension','ChoExt3',lists:flatten(Bytes5)),
-
- ?line {ok,Bytes6} = asn1_wrapper:encode('ChoExtension','ChoExt3',{'ChoExt3',{int,33}}),
- ?line {ok,{int,33}} =
- asn1_wrapper:decode('ChoExtension','ChoExt3',lists:flatten(Bytes6)),
-
- Val7 = {str,"abc"},
- ?line {ok,Bytes7} = asn1_wrapper:encode('ChoExtension','ChoExt4',Val7),
- ?line {ok,Val7} = asn1_wrapper:decode('ChoExtension','ChoExt4',lists:flatten(Bytes7)),
+ ok.
+roundtrip(Type, Value) ->
+ {ok,Encoded} = 'ChoExtension':encode(Type, Value),
+ {ok,Value} = 'ChoExtension':decode(Type, Encoded),
ok.
diff --git a/lib/asn1/test/testChoExternal.erl b/lib/asn1/test/testChoExternal.erl
index b2d171f9c7..5fdee48add 100644
--- a/lib/asn1/test/testChoExternal.erl
+++ b/lib/asn1/test/testChoExternal.erl
@@ -38,62 +38,27 @@ compile(Config, Rules, Optimize) ->
external(_Rules) ->
+ roundtrip('ChoXCho', {boolCho,true}),
+ roundtrip('ChoXCho', {intCho,77}),
- ?line {ok,Bytes11} = asn1_wrapper:encode('ChoExternal','ChoXCho',{'ChoXCho',{boolCho,true}}),
- ?line {ok,{boolCho,true}} = asn1_wrapper:decode('ChoExternal','ChoXCho',lists:flatten(Bytes11)),
-
-
- ?line {ok,Bytes12} = asn1_wrapper:encode('ChoExternal','ChoXCho',{'ChoXCho',{intCho,77}}),
- ?line {ok,{intCho,77}} = asn1_wrapper:decode('ChoExternal','ChoXCho',lists:flatten(Bytes12)),
-
-
-
- ?line {ok,Bytes21} = asn1_wrapper:encode('ChoExternal','ChoXBool',{'ChoXBool',{xbool,true}}),
- ?line {ok,{xbool,true}} = asn1_wrapper:decode('ChoExternal','ChoXBool',lists:flatten(Bytes21)),
-
-
- ?line {ok,Bytes22} = asn1_wrapper:encode('ChoExternal','ChoXBool',{'ChoXBool',{xboolImp,true}}),
- ?line {ok,{xboolImp,true}} = asn1_wrapper:decode('ChoExternal','ChoXBool',lists:flatten(Bytes22)),
-
-
- ?line {ok,Bytes23} = asn1_wrapper:encode('ChoExternal','ChoXBool',{'ChoXBool',{xboolExp,true}}),
- ?line {ok,{xboolExp,true}} = asn1_wrapper:decode('ChoExternal','ChoXBool',lists:flatten(Bytes23)),
-
-
-
- ?line {ok,Bytes31} = asn1_wrapper:encode('ChoExternal','NT',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','NT',lists:flatten(Bytes31)),
-
- ?line {ok,Bytes32} = asn1_wrapper:encode('ChoExternal','Exp',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','Exp',lists:flatten(Bytes32)),
-
- ?line {ok,Bytes33} = asn1_wrapper:encode('ChoExternal','NTNT',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','NTNT',lists:flatten(Bytes33)),
-
- ?line {ok,Bytes34} = asn1_wrapper:encode('ChoExternal','NTExp',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','NTExp',lists:flatten(Bytes34)),
-
- ?line {ok,Bytes35} = asn1_wrapper:encode('ChoExternal','ExpNT',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','ExpNT',lists:flatten(Bytes35)),
-
- ?line {ok,Bytes36} = asn1_wrapper:encode('ChoExternal','ExpExp',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','ExpExp',lists:flatten(Bytes36)),
-
-
-
-
-
- ?line {ok,Bytes41} = asn1_wrapper:encode('ChoExternal','XNTNT',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XNTNT',lists:flatten(Bytes41)),
-
- ?line {ok,Bytes42} = asn1_wrapper:encode('ChoExternal','XNTExp',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XNTExp',lists:flatten(Bytes42)),
-
- ?line {ok,Bytes43} = asn1_wrapper:encode('ChoExternal','XExpNT',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XExpNT',lists:flatten(Bytes43)),
-
- ?line {ok,Bytes44} = asn1_wrapper:encode('ChoExternal','XExpExp',{os,"kalle"}),
- ?line {ok,{os,"kalle"}} = asn1_wrapper:decode('ChoExternal','XExpExp',lists:flatten(Bytes44)),
+ roundtrip('ChoXBool', {xbool,true}),
+ roundtrip('ChoXBool', {xboolImp,true}),
+ roundtrip('ChoXBool', {xboolExp,true}),
+
+ roundtrip('NT', {os,"kalle"}),
+ roundtrip('Exp', {os,"kalle"}),
+ roundtrip('NTNT', {os,"kalle"}),
+ roundtrip('NTExp', {os,"kalle"}),
+ roundtrip('ExpNT', {os,"kalle"}),
+ roundtrip('ExpExp', {os,"kalle"}),
+ roundtrip('XNTNT', {os,"kalle"}),
+ roundtrip('XNTExp', {os,"kalle"}),
+ roundtrip('XExpNT', {os,"kalle"}),
+ roundtrip('XExpExp', {os,"kalle"}),
ok.
+roundtrip(Type, Value) ->
+ {ok,Encoded} = 'ChoExternal':encode(Type, Value),
+ {ok,Value} = 'ChoExternal':decode(Type, Encoded),
+ ok.
diff --git a/lib/asn1/test/testChoRecursive.erl b/lib/asn1/test/testChoRecursive.erl
index 22be26cbce..ee26d124a9 100644
--- a/lib/asn1/test/testChoRecursive.erl
+++ b/lib/asn1/test/testChoRecursive.erl
@@ -28,38 +28,21 @@
-record('ChoRec2_something',{a, b, c}).
recursive(_Rules) ->
-
- ?line {ok,Bytes11} = asn1_wrapper:encode('ChoRecursive','ChoRec',{'ChoRec',{something,
- #'ChoRec_something'{a = 77,
- b = "some octets here",
- c = {'ChoRec',{nothing,'NULL'}}}}}),
- ?line {ok,{something,{'ChoRec_something',77,"some octets here",{nothing,'NULL'}}}} =
- asn1_wrapper:decode('ChoRecursive','ChoRec',lists:flatten(Bytes11)),
-
-
- ?line {ok,Bytes12} = asn1_wrapper:encode('ChoRecursive','ChoRec',{'ChoRec',{nothing,'NULL'}}),
- ?line {ok,{nothing,'NULL'}} =
- asn1_wrapper:decode('ChoRecursive','ChoRec',lists:flatten(Bytes12)),
-
-
-
- ?line {ok,Bytes21} =
- asn1_wrapper:encode('ChoRecursive','ChoRec2',{'ChoRec2',
- {something,
- #'ChoRec2_something'{a = 77,
- b = "some octets here",
- c = {'ChoRec2',
- {nothing,'NULL'}}}}}),
- ?line {ok,{something,{'ChoRec2_something',77,"some octets here",{nothing,'NULL'}}}} =
- asn1_wrapper:decode('ChoRecursive','ChoRec2',lists:flatten(Bytes21)),
-
-
- ?line {ok,Bytes22} =
- asn1_wrapper:encode('ChoRecursive','ChoRec2',{'ChoRec2',{nothing,'NULL'}}),
- ?line {ok,{nothing,'NULL'}} =
- asn1_wrapper:decode('ChoRecursive','ChoRec2',lists:flatten(Bytes22)),
-
-
-
-
+ roundtrip('ChoRec',
+ {something,
+ #'ChoRec_something'{a = 77,
+ b = "some octets here",
+ c = {nothing,'NULL'}}}),
+ roundtrip('ChoRec', {nothing,'NULL'}),
+ roundtrip('ChoRec2',
+ {something,
+ #'ChoRec2_something'{a = 77,
+ b = "some octets here",
+ c = {nothing,'NULL'}}}),
+ roundtrip('ChoRec2', {nothing,'NULL'}),
+ ok.
+
+roundtrip(Type, Value) ->
+ {ok,Encoded} = 'ChoRecursive':encode(Type, Value),
+ {ok,Value} = 'ChoRecursive':decode(Type, Encoded),
ok.
diff --git a/lib/asn1/test/testCompactBitString.erl b/lib/asn1/test/testCompactBitString.erl
index db102a3bda..96d9f0fdcb 100644
--- a/lib/asn1/test/testCompactBitString.erl
+++ b/lib/asn1/test/testCompactBitString.erl
@@ -22,240 +22,132 @@
-export([compact_bit_string/1, bit_string_unnamed/1,otp_4869/1,
ticket_7734/1]).
--include_lib("test_server/include/test_server.hrl").
-
compact_bit_string(Rules) ->
%%==========================================================
%% Bs1 ::= BIT STRING
%%==========================================================
- ?line {ok,Bytes1} = asn1_wrapper:encode('PrimStrings','Bs1',0),
- ?line {ok,{0,<<>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes1)),
-
- ?line {ok,Bytes2} = asn1_wrapper:encode('PrimStrings','Bs1',4),
- ?line {ok,{5,<<32>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes2)),
-
- ?line {ok,Bytes3} = asn1_wrapper:encode('PrimStrings','Bs1',15),
- ?line {ok,{4,<<240>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes3)),
-
- ?line {ok,Bytes4} = asn1_wrapper:encode('PrimStrings','Bs1',255),
- ?line {ok,{0,<<255>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes4)),
-
- ?line {ok,Bytes5} = asn1_wrapper:encode('PrimStrings','Bs1',256),
- ?line {ok,{7,<<0,128>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes5)),
-
- ?line {ok,Bytes6} = asn1_wrapper:encode('PrimStrings','Bs1',257),
- ?line {ok,{7,<<128,128>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes6)),
-
- ?line {ok,Bytes7} = asn1_wrapper:encode('PrimStrings','Bs1',444),
- ?line {ok,{7,<<61,128>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes7)),
-
- ?line {ok,Bytes8} = asn1_wrapper:encode('PrimStrings','Bs1',
- 12345678901234567890),
- ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes8)),
-
-%% Removed due to beam cannot handle this big integers
-%% Bs1_1 = 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
-%% ?line {ok,Bytes9} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_1),
-%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes9)),
-
-%% Bs1_2 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
-%% ?line {ok,Bytes10} = asn1_wrapper:encode('PrimStrings','Bs1',Bs1_2),
-%% ?line {ok,_} = asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes10)),
-
- ?line {ok,Bytes11} = asn1_wrapper:encode('PrimStrings','Bs1',
- [1,1,1,1,1,1,1,1]),
- ?line {ok,{0,<<255>>}} = asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes11)),
-
- ?line {ok,Bytes12} = asn1_wrapper:encode('PrimStrings',
- 'Bs1',
- [0,1,0,0,1,0]),
- ?line {ok,{2,<<72>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes12)),
-
- ?line {ok,Bytes13} =
- asn1_wrapper:encode('PrimStrings', 'Bs1',
- [1,0,0,0,0,0,0,0,0]),
- ?line {ok,{7,<<128,0>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes13)),
-
-
- ?line {ok,Bytes14} =
- asn1_wrapper:encode('PrimStrings','Bs1',
- [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1]),
- ?line {ok,{5,<<75,226,96>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes14)),
-
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line Bytes15 = [35,8,3,2,0,73,3,2,4,32],
- ?line {ok,{4,<<73,32>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes15)),
-
- ?line Bytes16 = [35,9,3,2,0,234,3,3,7,156,0],
- ?line {ok,{7,<<234,156,0>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes16)),
-
- ?line Bytes17 = [35,128,3,2,0,73,3,2,4,32,0,0],
- ?line {ok,{4,<<73,32>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes17)),
-
- ?line Bytes18 = [35,128,3,2,0,234,3,3,7,156,0,0,0],
- ?line {ok,{7,<<234,156,0>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',
- lists:flatten(Bytes18)),
- ok;
-
- per ->
- ok
- end,
+ roundtrip('Bs1', 0, {0,<<>>}),
+ roundtrip('Bs1', 4, {5,<<2#00100000>>}),
+ roundtrip('Bs1', 15, {4,<<2#11110000>>}),
+ roundtrip('Bs1', 255, {0,<<2#11111111>>}),
+ roundtrip('Bs1', 256, {7,<<16#00,16#80>>}),
+ roundtrip('Bs1', 257, {7,<<16#80,16#80>>}),
+ roundtrip('Bs1', 444, {7,<<16#3D,16#80>>}),
+ roundtrip('Bs1', 12345678901234567890,
+ {0,<<75,80,248,215,49,149,42,213>>}),
+
+ roundtrip('Bs1', [1,1,1,1,1,1,1,1], {0,<<255>>}),
+ roundtrip('Bs1', [0,1,0,0,1,0], {2,<<16#48>>}),
+ roundtrip('Bs1', [1,0,0,0,0,0,0,0,0], {7,<<16#80,0>>}),
+ roundtrip('Bs1', [0,1,0,0,1,0,1,1,1,1,1,0,0,0,1,0,0,1,1],
+ {5,<<75,226,96>>}),
- %% The following case to test OTP-4200
- ?line {ok,Bytes19} =
- asn1_wrapper:encode('PrimStrings','Bs1',{0,<<0,0,1,1>>}),
- ?line {ok,{0,<<0,0,1,1>>}} =
- asn1_wrapper:decode('PrimStrings','Bs1',lists:flatten(Bytes19)),
+ case Rules of
+ ber ->
+ {ok,{4,<<73,32>>}} =
+ 'PrimStrings':decode('Bs1', <<35,8,3,2,0,73,3,2,4,32>>),
+ {ok,{7,<<234,156,0>>}} =
+ 'PrimStrings':decode('Bs1', <<35,9,3,2,0,234,3,3,7,156,0>>),
+ {ok,{4,<<73,32>>}} =
+ 'PrimStrings':decode('Bs1', <<35,128,3,2,0,73,3,2,4,32,0,0>>),
+ {ok,{7,<<234,156,0>>}} =
+ 'PrimStrings':decode('Bs1',
+ <<35,128,3,2,0,234,3,3,7,156,0,0,0>>);
+ _ ->
+ ok
+ end,
+
+ %% Test OTP-4200
+ roundtrip('Bs1', {0,<<0,0,1,1>>}),
%%==========================================================
%% Bs2 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (7))
%%==========================================================
-
- ?line {ok,Bytes21} = asn1_wrapper:encode('PrimStrings','Bs2',[mo,tu,fr]),
- ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs2',lists:flatten(Bytes21)),
-
- ?line {ok,Bytes22} = asn1_wrapper:encode('PrimStrings','Bs2',[0,1,1,0,0,1,0]),
- ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs2',lists:flatten(Bytes22)),
-
- % ?line case asn1_wrapper:erule(Rules) of
-% ber ->
-% ?line {ok,[mo,tu,fr,su,mo,th]} =
-% asn1_wrapper:decode('PrimStrings','Bs2',[35,8,3,2,1,100,3,2,2,200]),
-
-% ?line {ok,[mo,tu,fr,su,mo,th]} =
-% asn1_wrapper:decode('PrimStrings','Bs2',[35,128,3,2,1,100,3,2,2,200,0,0]),
-% ok;
-
-% per ->
-% ok
-% end,
-
-
+
+ roundtrip('Bs2', [mo,tu,fr]),
+ roundtrip('Bs2', [0,1,1,0,0,1,0], [mo,tu,fr]),
%%==========================================================
%% Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
%%==========================================================
- ?line {ok,Bytes31} = asn1_wrapper:encode('PrimStrings','Bs3',[mo,tu,fr]),
- ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes31)),
-
- ?line {ok,Bytes32} = asn1_wrapper:encode('PrimStrings','Bs3',[0,1,1,0,0,1,0]),
- ?line {ok,[mo,tu,fr]} = asn1_wrapper:decode('PrimStrings','Bs3',lists:flatten(Bytes32)),
-
-
+ roundtrip('Bs3', [mo,tu,fr]),
+ roundtrip('Bs3', [0,1,1,0,0,1,0], [mo,tu,fr]),
%%==========================================================
%% BsPri ::= [PRIVATE 61] BIT STRING
%%==========================================================
-
- ?line {ok,Bytes41} = asn1_wrapper:encode('PrimStrings','BsPri',45),
- ?line {ok,{2,<<180>>}} =
- asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes41)),
-
- ?line {ok,Bytes42} = asn1_wrapper:encode('PrimStrings','BsPri',211),
- ?line {ok,{0,<<203>>}} =
- asn1_wrapper:decode('PrimStrings','BsPri',lists:flatten(Bytes42)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,{5,<<75,226,96>>}} =
- asn1_wrapper:decode('PrimStrings','BsPri',
- [223,61,4,5,75,226,96]),
-
- ?line {ok,{5,<<75,226,96>>}} =
- asn1_wrapper:decode('PrimStrings','BsPri',
- [255,61,128,3,4,5,75,226,96,0,0]),
-
- ?line {ok,{5,<<75,226,96>>}} =
- asn1_wrapper:decode('PrimStrings','BsPri',
- [255,61,9,3,2,0,75,3,3,5,226,96]),
-
- ?line {ok,{5,<<75,226,96>>}} =
- asn1_wrapper:decode('PrimStrings','BsPri',
- [255,61,128,3,2,0,75,3,3,5,226,96,0,0]),
- ok;
-
- per ->
- ok
- end,
-
+
+ roundtrip('BsPri', 45, {2,<<180>>}),
+ roundtrip('BsPri', 211, {0,<<203>>}),
+
+ case Rules of
+ ber ->
+ {ok,{5,<<75,226,96>>}} =
+ 'PrimStrings':decode('BsPri',
+ <<223,61,4,5,75,226,96>>),
+
+ {ok,{5,<<75,226,96>>}} =
+ 'PrimStrings':decode('BsPri',
+ <<255,61,128,3,4,5,75,226,96,0,0>>),
+
+ {ok,{5,<<75,226,96>>}} =
+ 'PrimStrings':decode('BsPri',
+ <<255,61,9,3,2,0,75,3,3,5,226,96>>),
+
+ {ok,{5,<<75,226,96>>}} =
+ 'PrimStrings':decode('BsPri',
+ <<255,61,128,3,2,0,75,3,3,5,226,96,0,0>>),
+ ok;
+ _ ->
+ ok
+ end,
%%==========================================================
%% BsExpPri ::= [PRIVATE 61] EXPLICIT BIT STRING
%%==========================================================
-
- ?line {ok,Bytes51} = asn1_wrapper:encode('PrimStrings','BsExpPri',45),
- ?line {ok,{2,<<180>>}} =
- asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes51)),
-
- ?line {ok,Bytes52} = asn1_wrapper:encode('PrimStrings','BsExpPri',211),
- ?line {ok,{0,<<203>>}} =
- asn1_wrapper:decode('PrimStrings','BsExpPri',lists:flatten(Bytes52)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,{5,<<75,226,96>>}} =
- asn1_wrapper:decode('PrimStrings','BsExpPri',[255,61,6,3,4,5,75,226,96]),
- ok;
-
- per ->
- ok
- end,
-
- ok.
-ticket_7734(per) ->
- ?line BS = {0,list_to_binary(lists:duplicate(128,0))},
- ?line {ok,BSEnc} = asn1_wrapper:encode('PrimStrings','BS1024',BS),
- ?line {ok,BS} = asn1_wrapper:decode('PrimStrings','BS1024',BSEnc).
+ roundtrip('BsExpPri', 45, {2,<<180>>}),
+ roundtrip('BsExpPri', 211, {0,<<203>>}),
-bit_string_unnamed(Rules) ->
- case asn1_wrapper:erule(Rules) of
+ case Rules of
ber ->
- ok;
- per ->
- ?line {ok,Bytes1} =
- asn1_wrapper:encode('PrimStrings','TransportLayerAddress',
- [0,1,1,0]),
- ?line {ok,{4,<<96>>}} =
- asn1_wrapper:decode('PrimStrings','TransportLayerAddress',
- lists:flatten(Bytes1))
- end.
+ {ok,{5,<<75,226,96>>}} =
+ 'PrimStrings':decode('BsExpPri', <<255,61,6,3,4,5,75,226,96>>);
+ _ ->
+ ok
+ end,
-otp_4869(per) ->
- ?line Val1={'IP',[0],{0,<<62,235,90,50,0,0,0,0,0,0,0,0,0,0,0,0>>},asn1_NOVALUE},
- ?line Val2 = {'IP',[0],[0,0,1,1,1,1,1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,0,1,1,0,0,1,0] ++ lists:duplicate(128 - 32,0),asn1_NOVALUE},
+ ok.
+
+ticket_7734(_) ->
+ BS = {0,list_to_binary(lists:duplicate(128, 0))},
+ roundtrip('BS1024', BS).
- ?line {ok,Bytes1} = asn1_wrapper:encode('Constraints','IP',Val1),
- ?line {ok,Bytes1} = asn1_wrapper:encode('Constraints','IP',Val2);
+bit_string_unnamed(_Rules) ->
+ roundtrip('TransportLayerAddress', [0,1,1,0], {4,<<96>>}).
+
+otp_4869(per) ->
+ Val1 = {'IP',[0],{0,<<62,235,90,50,0,0,0,0,0,0,0,0,0,0,0,0>>},asn1_NOVALUE},
+ Val2 = {'IP',[0],[0,0,1,1,1,1,1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,0,
+ 1,0,0,0,1,1,0,0,1,0] ++
+ lists:duplicate(128 - 32, 0),asn1_NOVALUE},
+ {ok,Encoded} = 'Constraints':encode('IP', Val1),
+ {ok,Encoded} = 'Constraints':encode('IP', Val2),
+ ok;
otp_4869(_) ->
ok.
+
+roundtrip(Type, Val) ->
+ roundtrip_1('PrimStrings', Type, Val, Val).
+
+roundtrip(Type, Val1, Val2) ->
+ roundtrip_1('PrimStrings', Type, Val1, Val2).
+
+roundtrip_1(Mod, Type, In, Out) ->
+ {ok,Encoded} = Mod:encode(Type, In),
+ {ok,Out} = Mod:decode(Type, Encoded),
+ ok.
diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl
index 543c106e8a..c8d9008641 100644
--- a/lib/asn1/test/testConstraints.erl
+++ b/lib/asn1/test/testConstraints.erl
@@ -30,59 +30,20 @@ int_constraints(Rules) ->
%% SingleValue ::= INTEGER (1)
%%==========================================================
- ?line {ok,Bytes1} = asn1_wrapper:encode('Constraints','SingleValue',1),
- ?line {ok,1} = asn1_wrapper:decode('Constraints','SingleValue',
- lists:flatten(Bytes1)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,Bytes2} =
- asn1_wrapper:encode('Constraints','SingleValue',0),
- ?line {error,{asn1,{integer_range,_,0}}} =
- asn1_wrapper:decode('Constraints','SingleValue',
- lists:flatten(Bytes2)),
- ?line {ok,Bytes3} =
- asn1_wrapper:encode('Constraints','SingleValue',1000),
- ?line {error,{asn1,{integer_range,_,1000}}} =
- asn1_wrapper:decode('Constraints','SingleValue',
- lists:flatten(Bytes3));
- per ->
- ?line {error,_Reason1} =
- asn1_wrapper:encode('Constraints','SingleValue',0),
- ?line {error,_Reason2} =
- asn1_wrapper:encode('Constraints','SingleValue',1000)
- end,
+ range_error(Rules, 'SingleValue', 0),
+ roundtrip('SingleValue', 1),
+ range_error(Rules, 'SingleValue', 2),
+ range_error(Rules, 'SingleValue', 1000),
%%==========================================================
%% SingleValue2 ::= INTEGER (1..20)
%%==========================================================
- ?line {ok,Bytes4} = asn1_wrapper:encode('Constraints','SingleValue2',1),
- ?line {ok,1} = asn1_wrapper:decode('Constraints','SingleValue2',
- lists:flatten(Bytes4)),
-
- ?line {ok,Bytes5} = asn1_wrapper:encode('Constraints','SingleValue2',20),
- ?line {ok,20} = asn1_wrapper:decode('Constraints','SingleValue2',
- lists:flatten(Bytes5)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,Bytes6} =
- asn1_wrapper:encode('Constraints','SingleValue2',0),
- ?line {error,{asn1,{integer_range,{1,20},0}}} =
- asn1_wrapper:decode('Constraints','SingleValue2',
- lists:flatten(Bytes6)),
- ?line {ok,Bytes7} =
- asn1_wrapper:encode('Constraints','SingleValue2',21),
- ?line {error,{asn1,{integer_range,{1,20},21}}} =
- asn1_wrapper:decode('Constraints','SingleValue2',
- lists:flatten(Bytes7));
- per ->
- ?line {error,_Reason3} =
- asn1_wrapper:encode('Constraints','SingleValue',0),
- ?line {error,_Reason4} =
- asn1_wrapper:encode('Constraints','SingleValue',1000)
- end,
+ range_error(Rules, 'SingleValue2', 0),
+ roundtrip('SingleValue2', 1),
+ roundtrip('SingleValue2', 20),
+ range_error(Rules, 'SingleValue2', 21),
+ range_error(Rules, 'SingleValue2', 1000),
%%==========================================================
%% SingleValue3 ::= INTEGER (Predefined | 5 | 10)
@@ -90,136 +51,106 @@ int_constraints(Rules) ->
%% where one value is predefined.
%%==========================================================
- ?line {ok,BytesSV3} = asn1_wrapper:encode('Constraints','SingleValue3',1),
- ?line {ok,1} = asn1_wrapper:decode('Constraints','SingleValue3',
- lists:flatten(BytesSV3)),
- ?line {ok,BytesSV3_2} = asn1_wrapper:encode('Constraints','SingleValue3',5),
- ?line {ok,5} = asn1_wrapper:decode('Constraints','SingleValue3',
- lists:flatten(BytesSV3_2)),
- ?line {ok,BytesSV3_3} = asn1_wrapper:encode('Constraints','SingleValue3',10),
- ?line {ok,10} = asn1_wrapper:decode('Constraints','SingleValue3',
- lists:flatten(BytesSV3_3)),
+ roundtrip('SingleValue3', 1),
+ roundtrip('SingleValue3', 5),
+ roundtrip('SingleValue3', 10),
%%==========================================================
%% Range2to19 ::= INTEGER (1<..<20)
%%==========================================================
- ?line {ok,Bytes8} = asn1_wrapper:encode('Constraints','Range2to19',2),
- ?line {ok,2} = asn1_wrapper:decode('Constraints','Range2to19',lists:flatten(Bytes8)),
-
- ?line {ok,Bytes9} = asn1_wrapper:encode('Constraints','Range2to19',19),
- ?line {ok,19} = asn1_wrapper:decode('Constraints','Range2to19',lists:flatten(Bytes9)),
-
- ?line case asn1_wrapper:erule(Rules) of
- ber ->
- ?line {ok,Bytes10} =
- asn1_wrapper:encode('Constraints','Range2to19',1),
- ?line {error,{asn1,{integer_range,{2,19},1}}} =
- asn1_wrapper:decode('Constraints','Range2to19',
- lists:flatten(Bytes10)),
- ?line {ok,Bytes11} =
- asn1_wrapper:encode('Constraints','Range2to19',20),
- ?line {error,{asn1,{integer_range,{2,19},20}}} =
- asn1_wrapper:decode('Constraints','Range2to19',
- lists:flatten(Bytes11));
- per ->
- ?line {error,_Reason5} =
- asn1_wrapper:encode('Constraints','Range2to19',1),
- ?line {error,_Reason6} =
- asn1_wrapper:encode('Constraints','Range2to19',20)
- end,
+ range_error(Rules, 'Range2to19', 1),
+ roundtrip('Range2to19', 2),
+ roundtrip('Range2to19', 19),
+ range_error(Rules, 'Range2to19', 20),
%%==========================================================
%% Tests for Range above 16^4 up to maximum supported by asn1 assuming the
%% octet length field is encoded on max 8 bits
%%==========================================================
LastNumWithoutLengthEncoding = 65536,
- ?line {ok,BytesFoo} = asn1_wrapper:encode('Constraints','Range256to65536',
- LastNumWithoutLengthEncoding),
- ?line {ok,LastNumWithoutLengthEncoding} =
- asn1_wrapper:decode('Constraints','Range256to65536',lists:flatten(BytesFoo)),
+ roundtrip('Range256to65536', LastNumWithoutLengthEncoding),
FirstNumWithLengthEncoding = 65537,
- ?line {ok,BytesBar} = asn1_wrapper:encode('LargeConstraints','RangeMax',
- FirstNumWithLengthEncoding),
- ?line {ok,FirstNumWithLengthEncoding} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesBar)),
+ roundtrip('LargeConstraints', 'RangeMax', FirstNumWithLengthEncoding),
FirstNumOver16_6 = 16777217,
- ?line {ok, BytesBaz} =
- asn1_wrapper:encode('LargeConstraints','RangeMax', FirstNumOver16_6),
- ?line {ok, FirstNumOver16_6} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesBaz)),
+ roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_6),
FirstNumOver16_8 = 4294967297,
- ?line {ok, BytesQux} =
- asn1_wrapper:encode('LargeConstraints','RangeMax', FirstNumOver16_8),
- ?line {ok, FirstNumOver16_8} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesQux)),
+ roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_8),
FirstNumOver16_10 = 1099511627776,
- ?line {ok, BytesBur} =
- asn1_wrapper:encode('LargeConstraints','RangeMax', FirstNumOver16_10),
- ?line {ok, FirstNumOver16_10} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesBur)),
+ roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_10),
FirstNumOver16_10 = 1099511627776,
- ?line {ok, BytesBur} =
- asn1_wrapper:encode('LargeConstraints','RangeMax', FirstNumOver16_10),
- ?line {ok, FirstNumOver16_10} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesBur)),
+ roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_10),
HalfMax = 1 bsl (128*8),
- ?line {ok, BytesHalfMax} =
- asn1_wrapper:encode('LargeConstraints','RangeMax', HalfMax),
- ?line {ok, HalfMax} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesHalfMax)),
+ roundtrip('LargeConstraints', 'RangeMax', HalfMax),
Max = 1 bsl (255*8),
- ?line {ok, BytesMax} =
- asn1_wrapper:encode('LargeConstraints','RangeMax', Max),
- ?line {ok, Max} =
- asn1_wrapper:decode('LargeConstraints','RangeMax',lists:flatten(BytesMax)),
+ roundtrip('LargeConstraints', 'RangeMax', Max),
%% Random number within longlong range
LongLong = 12672809400538808320,
- ?line {ok, BytesLongLong} =
- asn1_wrapper:encode('Constraints','LongLong', LongLong),
- ?line {ok, LongLong} =
- asn1_wrapper:decode('Constraints','LongLong',lists:flatten(BytesLongLong)),
+ roundtrip('LongLong', LongLong),
%%==========================================================
%% Constraint Combinations (Duboisson p. 285)
%% I ::= INTEGER (0|15..269)
%%==========================================================
- ?line {ok,Bytes12} = asn1_wrapper:encode('Constraints','I',0),
- ?line {ok,0} = asn1_wrapper:decode('Constraints','I',Bytes12),
- ?line {ok,Bytes13} = asn1_wrapper:encode('Constraints','I',20),
- ?line {ok,20} = asn1_wrapper:decode('Constraints','I',Bytes13),
+ range_error(Rules, 'I', -1),
+ roundtrip('I', 0),
+ roundtrip('I', 15),
+ roundtrip('I', 20),
+ roundtrip('I', 269),
+ range_error(Rules, 'I', 270),
%%==========================================================
%% Constraint Combinations (Duboisson p. 285)
%% X1 ::= INTEGER (1..4|8|10|20)
%%==========================================================
- ?line {ok,Bytes14} = asn1_wrapper:encode('Constraints','X1',1),
- ?line {ok,1} = asn1_wrapper:decode('Constraints','X1',Bytes14),
- ?line {ok,Bytes15} = asn1_wrapper:encode('Constraints','X1',20),
- ?line {ok,20} = asn1_wrapper:decode('Constraints','X1',Bytes15),
+ range_error(Rules, 'X1', 0),
+ roundtrip('X1', 1),
+ roundtrip('X1', 4),
+ roundtrip('X1', 8),
+ roundtrip('X1', 10),
+ roundtrip('X1', 20),
+ range_error(Rules, 'X1', 21),
+
%%==========================================================
%% SIZE Constraint (Duboisson p. 268)
%% T ::= IA5String (SIZE (1|2, ..., SIZE (1|2|3)))
%% T2 ::= IA5String (SIZE (1|2, ..., 3))
%%==========================================================
- ?line {ok,Bytes16} = asn1_wrapper:encode('Constraints','T',"IA"),
- ?line {ok,"IA"} = asn1_wrapper:decode('Constraints','T',Bytes16),
- ?line {ok,Bytes17} = asn1_wrapper:encode('Constraints','T2',"IA"),
- ?line {ok,"IA"} = asn1_wrapper:decode('Constraints','T2',Bytes17).
-
+ roundtrip('T', "IA"),
+ roundtrip('T2', "IA").
refed_NNL_name(_Erule) ->
?line {ok,_} = asn1_wrapper:encode('Constraints','AnotherThing',fred),
?line {error,_Reason} =
asn1_wrapper:encode('Constraints','AnotherThing',fred3).
+
+roundtrip(Type, Value) ->
+ roundtrip('Constraints', Type, Value).
+
+roundtrip(Module, Type, Value) ->
+ {ok,Encoded} = Module:encode(Type, Value),
+ {ok,Value} = Module:decode(Type, Encoded),
+ ok.
+
+range_error(ber, Type, Value) ->
+ %% BER: Values outside the effective range should be rejected
+ %% on decode.
+ {ok,Encoded} = 'Constraints':encode(Type, Value),
+ {error,{asn1,{integer_range,_,_}}} = 'Constraints':decode(Type, Encoded),
+ ok;
+range_error(Per, Type, Value) when Per =:= per; Per =:= uper ->
+ %% (U)PER: Values outside the effective range should be rejected
+ %% on encode.
+ {error,_} = 'Constraints':encode(Type, Value),
+ ok.
diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl
index aa3afbb58f..3df7bcbaa0 100644
--- a/lib/asn1/test/testDeepTConstr.erl
+++ b/lib/asn1/test/testDeepTConstr.erl
@@ -26,21 +26,19 @@
-include_lib("test_server/include/test_server.hrl").
main(_Erule) ->
- Val1 = {'FilterItem',
- {substrings,
- {'FilterItem_substrings',
- {2,6},
- [{initial,"SE"},
- {any,"DK"},
- {final,"N"}]}}},
+ Val1 = {substrings,
+ {'FilterItem_substrings',
+ {2,6},
+ [{initial,"SE"},
+ {any,"DK"},
+ {final,"N"}]}},
- Val2 = {'FilterItem',
- {substrings,
- {'FilterItem_substrings',
- {2,6},
- [{initial,"SE"},
- {any,"DK"},
- {final,"NO"}]}}},
+ Val2 = {substrings,
+ {'FilterItem_substrings',
+ {2,6},
+ [{initial,"SE"},
+ {any,"DK"},
+ {final,"NO"}]}},
?line {ok,Bytes1} =
asn1_wrapper:encode('TConstrChoice','FilterItem',Val1),
diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl
index bb975a1d13..0811f20571 100644
--- a/lib/asn1/test/testEnumExt.erl
+++ b/lib/asn1/test/testEnumExt.erl
@@ -25,58 +25,41 @@
main(Rule) when Rule =:= per; Rule =:= uper ->
io:format("main(~p)~n",[Rule]),
- B32=[32],B64=[64],
+
%% ENUMERATED with extensionmark (value is in root set)
- ?line {ok,B32} = asn1_wrapper:encode('EnumExt','Ext',red),
- ?line {ok,red} = asn1_wrapper:decode('EnumExt','Ext',B32),
+ B32 = <<32>>,
+ B32 = roundtrip('Ext', red),
%% ENUMERATED with extensionmark (value is an extensionvalue)
- ?line {ok,Or} = asn1_wrapper:encode('EnumExt','Ext1',orange),
- ?line {ok,orange} = asn1_wrapper:decode('EnumExt','Ext1',Or),
+ Or = roundtrip('Ext1', orange),
%% unknown extensionvalue
- ?line {ok,{asn1_enum,0}} = asn1_wrapper:decode('EnumExt','Ext',Or),
-
+ {ok,{asn1_enum,0}} = asn1_wrapper:decode('EnumExt','Ext',Or),
%% ENUMERATED no extensionmark
- ?line {ok,B64} = asn1_wrapper:encode('EnumExt','Noext',red),
- ?line {ok,red} = asn1_wrapper:decode('EnumExt','Noext',B64),
+ B64 = <<64>>,
+ B64 = roundtrip('Noext', red),
ok;
main(ber) ->
io:format("main(ber)~n",[]),
%% ENUMERATED with extensionmark (value is in root set)
- ?line {ok,Bytes1} = asn1_wrapper:encode('EnumExt','Ext',red),
- ?line {ok,red} = asn1_wrapper:decode('EnumExt','Ext',lists:flatten(Bytes1)),
+ roundtrip('Ext', red),
%% value is an extensionvalue
- ?line {ok,Bytes1_1} = asn1_wrapper:encode('EnumExt','Ext1',orange),
- ?line {ok,{asn1_enum,7}} = asn1_wrapper:decode('EnumExt','Ext',lists:flatten(Bytes1_1)),
-%% ?line {ok,Bytes1_1} = asn1_wrapper:encode('EnumExt','Ext',{asn1_enum,7}),
+ {ok,Bytes1_1} = asn1_wrapper:encode('EnumExt','Ext1',orange),
+ {ok,{asn1_enum,7}} = asn1_wrapper:decode('EnumExt','Ext',lists:flatten(Bytes1_1)),
- %% ENUMERATED no extensionmark
- ?line {ok,Bytes2} = asn1_wrapper:encode('EnumExt','Noext',red),
- ?line {ok,red} = asn1_wrapper:decode('EnumExt','Noext',lists:flatten(Bytes2)),
+ %% ENUMERATED no extensionmark
+ roundtrip('Noext', red),
?line {error,{asn1,_}} = (catch asn1_wrapper:encode('EnumExt','Noext',orange)),
-%% ?line {error,{asn1,_}} = (catch asn1_wrapper:encode('EnumExt','Noext',{asn1_enum,7})),
- ok,
%% ENUMERATED with atom 'com'
- ?line {ok,Bytes3} = asn1_wrapper:encode('EnumExt','Globalstate',{'Globalstate',preop}),
- ?line {ok,preop} = asn1_wrapper:decode('EnumExt','Globalstate',
- lists:flatten(Bytes3)),
- ?line {ok,Bytes4} = asn1_wrapper:encode('EnumExt','Globalstate',{'Globalstate',com}),
- ?line {ok,com} = asn1_wrapper:decode('EnumExt','Globalstate',
- lists:flatten(Bytes4)).
-
-
-
-
-
-
-
-
-
-
-
+ roundtrip('Globalstate', preop),
+ roundtrip('Globalstate', com),
+ ok.
+roundtrip(Type, Value) ->
+ {ok,Encoded} = 'EnumExt':encode(Type, Value),
+ {ok,Value} = 'EnumExt':decode(Type, Encoded),
+ Encoded.
diff --git a/lib/asn1/test/testMergeCompile.erl b/lib/asn1/test/testMergeCompile.erl
index d63df28c31..8ef7ba3458 100644
--- a/lib/asn1/test/testMergeCompile.erl
+++ b/lib/asn1/test/testMergeCompile.erl
@@ -37,7 +37,7 @@ main(Erule) ->
%% test of RANAP.set.asn1
?line _PIEVal = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,{'CauseRadioNetwork','rab-pre-empted'}}}}],
- ?line PIEVal2 = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,'rab-pre-empted'}}}],
+ PIEVal2 = [{'ProtocolIE-Field',4,ignore,{radioNetwork,'rab-pre-empted'}}],
?line _PEVal = [{'ProtocolExtensionField',[0]}],
%% ?line EncVal = asn1rt_per_v1:encode_integer([],100),
?line EncVal =
diff --git a/lib/asn1/test/testParameterizedInfObj.erl b/lib/asn1/test/testParameterizedInfObj.erl
index 6f53595132..17108e285b 100644
--- a/lib/asn1/test/testParameterizedInfObj.erl
+++ b/lib/asn1/test/testParameterizedInfObj.erl
@@ -86,7 +86,7 @@ main(Erule) ->
ranap(_Erule) ->
- ?line PIEVal2 = [{'ProtocolIE-Field',4,ignore,{'Cause',{radioNetwork,'rab-pre-empted'}}}],
+ PIEVal2 = [{'ProtocolIE-Field',4,ignore,{radioNetwork,'rab-pre-empted'}}],
?line Val2 =
#'InitiatingMessage'{procedureCode=1,
criticality=ignore,
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
index 9a640a2cb1..263d9e5ed2 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -372,6 +372,11 @@ octet_string(Rules) ->
end,
fragmented_octet_string(Rules),
+
+ S255 = lists:seq(1, 255),
+ FixedStrings = {'OsFixedStrings',true,"","1","12","345",true,
+ S255,[$a|S255],[$a,$b|S255],397},
+ roundtrip('OsFixedStrings', FixedStrings),
ok.
fragmented_octet_string(Erules) ->
diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl
index 7c77ab87e9..1128d9a7c3 100644
--- a/lib/asn1/test/testSeqExtension.erl
+++ b/lib/asn1/test/testSeqExtension.erl
@@ -20,7 +20,7 @@
-module(testSeqExtension).
-include("External.hrl").
--export([main/1]).
+-export([main/2]).
-include_lib("test_server/include/test_server.hrl").
@@ -28,70 +28,73 @@
-record('SeqExt2',{bool, int}).
-record('SeqExt3',{bool, int}).
-record('SeqExt4',{bool, int}).
-
-
-main(_Rules) ->
-
- ?line {ok,Bytes11} =
- asn1_wrapper:encode('SeqExtension','SeqExt1',#'SeqExt1'{}),
- ?line {ok,{'SeqExt1'}} =
- asn1_wrapper:decode('SeqExtension','SeqExt1',lists:flatten(Bytes11)),
-
- ?line {ok,Bytes21} =
- asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{bool = true,int = 99}),
- ?line {ok,{'SeqExt2',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(Bytes21)),
-
- ?line {ok,Bytes22} =
- asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{int = 99,bool = true}),
- ?line {ok,{'SeqExt2',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(Bytes22)),
-
- ?line {ok,Bytes31} =
- asn1_wrapper:encode('SeqExtension','SeqExt3',#'SeqExt3'{bool = true,int = 99}),
- ?line {ok,{'SeqExt3',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt3',lists:flatten(Bytes31)),
-
- ?line {ok,Bytes32} =
- asn1_wrapper:encode('SeqExtension','SeqExt3',#'SeqExt3'{int = 99,bool = true}),
- ?line {ok,{'SeqExt3',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt3',lists:flatten(Bytes32)),
-
- ?line {ok,Bytes41} =
- asn1_wrapper:encode('SeqExtension','SeqExt4',#'SeqExt4'{bool = true,int = 99}),
- ?line {ok,{'SeqExt4',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt4',lists:flatten(Bytes41)),
-
- ?line {ok,Bytes42} =
- asn1_wrapper:encode('SeqExtension','SeqExt4',#'SeqExt4'{int = 99,bool = true}),
- ?line {ok,{'SeqExt4',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt4',lists:flatten(Bytes42)),
-
-
- % test of extension , not ready
-
- ?line {ok,BytesX11} =
- asn1_wrapper:encode('SeqExtension','SeqExt1',#'SeqExt1'{}),
- ?line {ok,{'SeqExt1'}} =
- asn1_wrapper:decode('SeqExtension','SeqExt1',lists:flatten(BytesX11)),
-
- ?line {ok,BytesX21} =
- asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{bool = true,int = 99}),
- ?line {ok,{'SeqExt2',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(BytesX21)),
-
- ?line {ok,BytesX22} =
- asn1_wrapper:encode('SeqExtension','SeqExt2',#'SeqExt2'{int = 99,bool = true}),
- ?line {ok,{'SeqExt2',true,99}} =
- asn1_wrapper:decode('SeqExtension','SeqExt2',lists:flatten(BytesX22)),
-
-
-
-
-
+-record('SeqExt5',{name, shoesize}).
+-record('SeqExt6',{i1,i2,i3,i4,i5,i6,i7}).
+-record('SuperSeq',{s1,s2,s3,s4,s5,s6,i}).
+
+main(DataDir, Opts) ->
+ roundtrip('SeqExt1', #'SeqExt1'{}),
+
+ roundtrip('SeqExt2', #'SeqExt2'{bool=true,int=99}),
+ roundtrip('SeqExt2', #'SeqExt2'{bool=false,int=42}),
+
+ roundtrip('SeqExt3', #'SeqExt3'{bool=true,int=-77777}),
+ roundtrip('SeqExt3', #'SeqExt3'{bool=false,int=-42000}),
+
+ roundtrip('SeqExt4', #'SeqExt4'{bool=true,int=12345}),
+ roundtrip('SeqExt4', #'SeqExt4'{bool=false,int=123456}),
+
+ roundtrip('SeqExt5', #'SeqExt5'{name="Arne",shoesize=47}),
+
+ %% Encode a value with this version of the specification.
+ BigInt = 128638468966,
+ SuperSeq = #'SuperSeq'{s1=#'SeqExt1'{},
+ s2=#'SeqExt2'{bool=true,int=2345},
+ s3=#'SeqExt3'{bool=false,int=17},
+ s4=#'SeqExt4'{bool=true,int=38739739},
+ s5=#'SeqExt5'{name="Arne",shoesize=47},
+ s6=#'SeqExt6'{i1=531,i2=601,i3=999,
+ i4=777,i5=11953,
+ i6=13553,i7=77777},
+ i=BigInt
+ },
+ {ok,SuperSeqEnc} = 'SeqExtension':encode('SuperSeq', SuperSeq),
+ {ok,SuperSeq} = 'SeqExtension':decode('SuperSeq', SuperSeqEnc),
+
+ %% Remove all extensions from the ASN.1 specification and compile it.
+ CaseDir = filename:dirname(code:which('SeqExtension')),
+ Asn1SrcBase = "SeqExtension.asn1",
+ Asn1SrcFile0 = filename:join(DataDir, Asn1SrcBase),
+ {ok,Src0} = file:read_file(Asn1SrcFile0),
+ %% Remove all declarations following "...," up to the end
+ %% of the SEQUENCE.
+ Src1 = re:replace(Src0, "[.][.][.],[^}]*", "...\n",
+ [global,{return,binary}]),
+ %% Remove the last double bracket group in the SEQUENCE.
+ Src = re:replace(Src1, ",\\s*\\[\\[.*?\\]\\]\\s*\\}", "\n}",
+ [global,{return,binary}]),
+ io:format("~s\n\n", [Src]),
+ Asn1SrcFile = filename:join(CaseDir, Asn1SrcBase),
+ ok = file:write_file(Asn1SrcFile, Src),
+ ok = asn1ct:compile(Asn1SrcFile,
+ [{i,DataDir},{outdir,CaseDir}|Opts]),
+
+ %% Decode the encoded sequence with the version of the spec
+ %% with no extensions following the extension marks
+ %% (except in SeqExt6). The integer 'i' at the end
+ %% of the sequence must still be the correct integer (otherwise
+ %% some extension has not been skipped correctly).
+ {ok,DecodedSuperSeq} = 'SeqExtension':decode('SuperSeq', SuperSeqEnc),
+ #'SuperSeq'{s1={'SeqExt1'},
+ s2=#'SeqExt2'{bool=true,int=2345},
+ s3={'SeqExt3'},
+ s4={'SeqExt4',true},
+ s5={'SeqExt5'},
+ s6={'SeqExt6',531,601,999,777,11953},
+ i=BigInt} = DecodedSuperSeq,
ok.
-
-
-
-
+roundtrip(Type, Value) ->
+ {ok,Encoded} = 'SeqExtension':encode(Type, Value),
+ {ok,Value} = 'SeqExtension':decode(Type, Encoded),
+ ok.
diff --git a/lib/asn1/test/testSetOptional.erl b/lib/asn1/test/testSetOptional.erl
index cef90bc843..bb43ff0a96 100644
--- a/lib/asn1/test/testSetOptional.erl
+++ b/lib/asn1/test/testSetOptional.erl
@@ -21,8 +21,7 @@
-include("External.hrl").
-export([main/1]).
--export([ticket_7533/1,decoder/4]).
--include_lib("test_server/include/test_server.hrl").
+-export([ticket_7533/1]).
-record('SetOpt1',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
-record('SetOpt1Imp',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
@@ -36,171 +35,64 @@
-record('SetIn',{boolIn, intIn}).
main(_Rules) ->
+ roundtrip('SetOpt1',
+ #'SetOpt1'{bool1=true,int1=15,
+ set1=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt1', #'SetOpt1'{int1=15}),
+
+ roundtrip('SetOpt2', #'SetOpt2'{bool2=true,int2=15,
+ set2=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt2', #'SetOpt2'{int2=15,bool2=true}),
+
+ roundtrip('SetOpt3', #'SetOpt3'{bool3=true,int3=15,
+ set3=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt3', #'SetOpt3'{int3=15}),
+
+ roundtrip('SetOpt1Imp',
+ #'SetOpt1Imp'{bool1=true,int1 = 15,
+ set1=#'SetIn'{boolIn = true,intIn = 66}}),
+ roundtrip('SetOpt1Imp', #'SetOpt1Imp'{int1=15}),
- ?line {ok,Bytes11} =
- asn1_wrapper:encode('SetOptional','SetOpt1',#'SetOpt1'{bool1 = true,
- int1 = 15,
- set1 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt1',true,15,{'SetIn',true,66}}} =
- asn1_wrapper:decode('SetOptional','SetOpt1',lists:flatten(Bytes11)),
-
-
- ?line {ok,Bytes12} = asn1_wrapper:encode('SetOptional','SetOpt1',#'SetOpt1'{int1 = 15}),
- ?line {ok,{'SetOpt1',asn1_NOVALUE,15,asn1_NOVALUE}} =
- asn1_wrapper:decode('SetOptional','SetOpt1',lists:flatten(Bytes12)),
-
-
- ?line {ok,Bytes21} =
- asn1_wrapper:encode('SetOptional','SetOpt2',#'SetOpt2'{bool2 = true,
- int2 = 15,
- set2 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt2',{'SetIn',true,66},true,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt2',lists:flatten(Bytes21)),
-
-
- ?line {ok,Bytes22} = asn1_wrapper:encode('SetOptional','SetOpt2',#'SetOpt2'{int2 = 15,
- bool2 = true}),
- ?line {ok,{'SetOpt2',asn1_NOVALUE,true,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt2',lists:flatten(Bytes22)),
-
-
-
- ?line {ok,Bytes31} =
- asn1_wrapper:encode('SetOptional','SetOpt3',#'SetOpt3'{bool3 = true,
- int3 = 15,
- set3 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt3',true,{'SetIn',true,66},15}} =
- asn1_wrapper:decode('SetOptional','SetOpt3',lists:flatten(Bytes31)),
-
-
- ?line {ok,Bytes32} = asn1_wrapper:encode('SetOptional','SetOpt3',#'SetOpt3'{int3 = 15}),
- ?line {ok,{'SetOpt3',asn1_NOVALUE,asn1_NOVALUE,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt3',lists:flatten(Bytes32)),
-
-
-
-
-
- ?line {ok,Bytes41} =
- asn1_wrapper:encode('SetOptional','SetOpt1Imp',#'SetOpt1Imp'{bool1 = true,
- int1 = 15,
- set1 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt1Imp',true,15,{'SetIn',true,66}}} =
- asn1_wrapper:decode('SetOptional','SetOpt1Imp',lists:flatten(Bytes41)),
-
-
- ?line {ok,Bytes42} = asn1_wrapper:encode('SetOptional','SetOpt1Imp',#'SetOpt1Imp'{int1 = 15}),
- ?line {ok,{'SetOpt1Imp',asn1_NOVALUE,15,asn1_NOVALUE}} =
- asn1_wrapper:decode('SetOptional','SetOpt1Imp',lists:flatten(Bytes42)),
-
-
- ?line {ok,Bytes51} =
- asn1_wrapper:encode('SetOptional','SetOpt2Imp',#'SetOpt2Imp'{bool2 = true,
- int2 = 15,
- set2 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt2Imp',{'SetIn',true,66},true,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt2Imp',lists:flatten(Bytes51)),
-
-
- ?line {ok,Bytes52} = asn1_wrapper:encode('SetOptional','SetOpt2Imp',#'SetOpt2Imp'{int2 = 15,
- bool2 = true}),
- ?line {ok,{'SetOpt2Imp',asn1_NOVALUE,true,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt2Imp',lists:flatten(Bytes52)),
-
-
-
- ?line {ok,Bytes61} =
- asn1_wrapper:encode('SetOptional','SetOpt3Imp',#'SetOpt3Imp'{bool3 = true,
- int3 = 15,
- set3 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt3Imp',true,{'SetIn',true,66},15}} =
- asn1_wrapper:decode('SetOptional','SetOpt3Imp',lists:flatten(Bytes61)),
-
-
- ?line {ok,Bytes62} = asn1_wrapper:encode('SetOptional','SetOpt3Imp',#'SetOpt3Imp'{int3 = 15}),
- ?line {ok,{'SetOpt3Imp',asn1_NOVALUE,asn1_NOVALUE,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt3Imp',lists:flatten(Bytes62)),
-
-
-
-
-
-
- ?line {ok,Bytes71} =
- asn1_wrapper:encode('SetOptional','SetOpt1Exp',#'SetOpt1Exp'{bool1 = true,
- int1 = 15,
- set1 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt1Exp',true,15,{'SetIn',true,66}}} =
- asn1_wrapper:decode('SetOptional','SetOpt1Exp',lists:flatten(Bytes71)),
-
-
- ?line {ok,Bytes72} = asn1_wrapper:encode('SetOptional','SetOpt1Exp',#'SetOpt1Exp'{int1 = 15}),
- ?line {ok,{'SetOpt1Exp',asn1_NOVALUE,15,asn1_NOVALUE}} =
- asn1_wrapper:decode('SetOptional','SetOpt1Exp',lists:flatten(Bytes72)),
-
-
- ?line {ok,Bytes81} =
- asn1_wrapper:encode('SetOptional','SetOpt2Exp',#'SetOpt2Exp'{bool2 = true,
- int2 = 15,
- set2 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt2Exp',{'SetIn',true,66},true,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt2Exp',lists:flatten(Bytes81)),
-
-
- ?line {ok,Bytes82} = asn1_wrapper:encode('SetOptional','SetOpt2Exp',#'SetOpt2Exp'{int2 = 15,
- bool2 = true}),
- ?line {ok,{'SetOpt2Exp',asn1_NOVALUE,true,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt2Exp',lists:flatten(Bytes82)),
-
-
-
- ?line {ok,Bytes91} =
- asn1_wrapper:encode('SetOptional','SetOpt3Exp',#'SetOpt3Exp'{bool3 = true,
- int3 = 15,
- set3 = #'SetIn'{boolIn = true,
- intIn = 66}}),
- ?line {ok,{'SetOpt3Exp',true,{'SetIn',true,66},15}} =
- asn1_wrapper:decode('SetOptional','SetOpt3Exp',lists:flatten(Bytes91)),
-
-
- ?line {ok,Bytes92} = asn1_wrapper:encode('SetOptional','SetOpt3Exp',#'SetOpt3Exp'{int3 = 15}),
- ?line {ok,{'SetOpt3Exp',asn1_NOVALUE,asn1_NOVALUE,15}} =
- asn1_wrapper:decode('SetOptional','SetOpt3Exp',lists:flatten(Bytes92)),
-
+
+ roundtrip('SetOpt2Imp',
+ #'SetOpt2Imp'{bool2=true,int2=15,
+ set2=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt2Imp',#'SetOpt2Imp'{int2=15,bool2=true}),
+
+ roundtrip('SetOpt3Imp',
+ #'SetOpt3Imp'{bool3=true,int3=15,
+ set3=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt3Imp', #'SetOpt3Imp'{int3=15}),
+
+ roundtrip('SetOpt1Exp',
+ #'SetOpt1Exp'{bool1=true,int1=15,
+ set1=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt1Exp', #'SetOpt1Exp'{int1=15}),
+
+ roundtrip('SetOpt2Exp',
+ #'SetOpt2Exp'{bool2=true,int2=15,
+ set2=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt2Exp', #'SetOpt2Exp'{int2=15,bool2=true}),
+ roundtrip('SetOpt3Exp',
+ #'SetOpt3Exp'{bool3=true,int3=15,
+ set3=#'SetIn'{boolIn=true,intIn=66}}),
+ roundtrip('SetOpt3Exp', #'SetOpt3Exp'{int3=15}),
ok.
ticket_7533(Ber) when Ber == ber ->
- Val = #'SetOpt1'{bool1 = true,int1=12,set1=#'SetIn'{boolIn=false,intIn=13}},
- ?line {ok,B} = asn1_wrapper:encode('SetOptional','SetOpt1',Val),
- ?line {ok,Val} = asn1_wrapper:decode('SetOptional','SetOpt1',B),
-
- CorruptVal = [49,14,1,1,255,2,1,12] ++ lists:duplicate(8,0),
- Pid = spawn(?MODULE,decoder,[self(),'SetOptional','SetOpt1',CorruptVal]),
- receive
- {ok,Pid,Result} ->
- io:format("Decode result: ~p~n",[Result]),
- ok
- after 10000 ->
- io:format("Decode timeout~n",[]),
- exit(Pid,normal)
- end;
+ Val = #'SetOpt1'{bool1=true,int1=12,set1=#'SetIn'{boolIn=false,intIn=13}},
+ roundtrip('SetOpt1', Val),
+ CorruptVal = <<49,14,1,1,255,2,1,12,0:8/unit:8>>,
+ {error,_} = 'SetOptional':decode('SetOpt1', CorruptVal),
+ ok;
ticket_7533(_) ->
ok.
-decoder(Parent,Module,Type,Val) ->
- io:format("Decoding~n",[]),
- ?line {ok,Res} = asn1_wrapper:decode(Module,Type,Val),
- io:format("Decode res: ~p~n",[Res]),
- Parent ! {ok,self(),Res}.
+roundtrip(Type, Value) ->
+ {ok,Encoded} = 'SetOptional':encode(Type, Value),
+ {ok,Value} = 'SetOptional':decode(Type, Encoded),
+ ok.
diff --git a/lib/asn1/test/test_partial_incomplete_decode.erl b/lib/asn1/test/test_partial_incomplete_decode.erl
index df56c27115..8ede06938d 100644
--- a/lib/asn1/test/test_partial_incomplete_decode.erl
+++ b/lib/asn1/test/test_partial_incomplete_decode.erl
@@ -188,7 +188,7 @@ decode_parts('S1_2',PartDecMsg) ->
msg('F') ->
- {'F',{fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}}};
+ {fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}};
msg('F3') ->
{fb,{'E',10,[{'D',11,true},{'D',12,false}],false,{dc,{'E_d_dc',13,true,{'E_d_dc_dcc',14,15}}}}};
diff --git a/lib/asn1/test/test_selective_decode.erl b/lib/asn1/test/test_selective_decode.erl
index bb348611da..ebe1296cf3 100644
--- a/lib/asn1/test/test_selective_decode.erl
+++ b/lib/asn1/test/test_selective_decode.erl
@@ -53,7 +53,7 @@ test() ->
msg('F') ->
- {'F',{fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}}};
+ {fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{da,[{'A',16,{'D',17,true}}]}}};
msg('E') ->
{'E',10,[{'D',11,true},{'D',12,false}],false,{dc,{'E_d_dc',13,true,{'E_d_dc_dcc',14,15}}}};
diff --git a/lib/asn1/test/test_special_decode_performance.erl b/lib/asn1/test/test_special_decode_performance.erl
index dd56d29b28..7dfab1f25a 100644
--- a/lib/asn1/test/test_special_decode_performance.erl
+++ b/lib/asn1/test/test_special_decode_performance.erl
@@ -31,8 +31,8 @@ go(all) ->
{Time_S_c,Time_MGC_c}).
go(N,Mod) ->
- ?line Val = val(Mod),
- ?line {ok,B} = Mod:encode(element(1,Val),Val),
+ {Type,Val} = val(Mod),
+ {ok,B} = Mod:encode(Type, Val),
?line go(Mod,B,N).
go(Mod,Bin,N) ->
@@ -92,7 +92,7 @@ val('PartialDecSeq') ->
{'F',{fb,{'E',12,[{'D',13,true},{'D',14,false},{'D',15,true},{'D',16,false},{'D',13,true},{'D',14,false},{'D',15,true},{'D',16,false},{'D',13,true},{'D',14,false},{'D',15,true},{'D',16,false}],true,{da,[{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}},{'A',17,{'D',18,false}},{'A',19,{'D',20,true}},{'A',21,{'D',22,false}}]}}}};
val('MEDIA-GATEWAY-CONTROL') ->
- {'MegacoMessage',asn1_NOVALUE,{'Message',1,{ip4Address,{'IP4Address',[125,125,125,111],55555}},{transactions,[{transactionReply,{'TransactionReply',50007,asn1_NOVALUE,{actionReplies,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,[{auditValueReply,{auditResult,{'AuditResult',{'TerminationID',[],[255,255,255]},[{mediaDescriptor,{'MediaDescriptor',asn1_NOVALUE,{multiStream,[{'StreamDescriptor',1,{'StreamParms',{'LocalControlDescriptor',sendRecv,asn1_NOVALUE,asn1_NOVALUE,[{'PropertyParm',[0,11,0,7],[[52,48]],asn1_NOVALUE}]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,53,46,49,50,53,46,49,50,53,46,49,49,49]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,49,49,49,49,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,52,46,49,50,52,46,49,50,52,46,50,50,50]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,50,50,50,50,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]}}}]}}},{packagesDescriptor,[{'PackagesItem',[0,11],1},{'PackagesItem',[0,11],1}]},{statisticsDescriptor,[{'StatisticsParameter',[0,12,0,4],[[49,50,48,48]]},{'StatisticsParameter',[0,11,0,2],[[54,50,51,48,48]]},{'StatisticsParameter',[0,12,0,5],[[55,48,48]]},{'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},{'StatisticsParameter',[0,12,0,6],[[48,46,50]]},{'StatisticsParameter',[0,12,0,7],[[50,48]]},{'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}.
+ {'MegacoMessage',{'MegacoMessage',asn1_NOVALUE,{'Message',1,{ip4Address,{'IP4Address',[125,125,125,111],55555}},{transactions,[{transactionReply,{'TransactionReply',50007,asn1_NOVALUE,{actionReplies,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,[{auditValueReply,{auditResult,{'AuditResult',{'TerminationID',[],[255,255,255]},[{mediaDescriptor,{'MediaDescriptor',asn1_NOVALUE,{multiStream,[{'StreamDescriptor',1,{'StreamParms',{'LocalControlDescriptor',sendRecv,asn1_NOVALUE,asn1_NOVALUE,[{'PropertyParm',[0,11,0,7],[[52,48]],asn1_NOVALUE}]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,53,46,49,50,53,46,49,50,53,46,49,49,49]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,49,49,49,49,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]},{'LocalRemoteDescriptor',[[{'PropertyParm',[0,0,176,1],[[48]],asn1_NOVALUE},{'PropertyParm',[0,0,176,8],[[73,78,32,73,80,52,32,49,50,52,46,49,50,52,46,49,50,52,46,50,50,50]],asn1_NOVALUE},{'PropertyParm',[0,0,176,15],[[97,117,100,105,111,32,50,50,50,50,32,82,84,80,47,65,86,80,32,32,52]],asn1_NOVALUE},{'PropertyParm',[0,0,176,12],[[112,116,105,109,101,58,51,48]],asn1_NOVALUE}]]}}}]}}},{packagesDescriptor,[{'PackagesItem',[0,11],1},{'PackagesItem',[0,11],1}]},{statisticsDescriptor,[{'StatisticsParameter',[0,12,0,4],[[49,50,48,48]]},{'StatisticsParameter',[0,11,0,2],[[54,50,51,48,48]]},{'StatisticsParameter',[0,12,0,5],[[55,48,48]]},{'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},{'StatisticsParameter',[0,12,0,6],[[48,46,50]]},{'StatisticsParameter',[0,12,0,7],[[50,48]]},{'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}}.
%% val('PartialDecSeq') ->
%% {'F',{fb,{'E',35,[{'D',3,true},{'D',4,false},{'D',5,true},{'D',6,true},{'D',7,false},{'D',8,true},{'D',9,true},{'D',10,false},{'D',11,true},{'D',12,true},{'D',13,false},{'D',14,true}],false,{dc,{'E_d_dc',15,true,{'E_d_dc_dcc',17,4711}}}}}}.