aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src/asn1ct_gen_per.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2013-07-01 09:05:37 +0200
committerBjörn Gustavsson <[email protected]>2013-09-03 16:00:15 +0200
commitdf7bb30fd0e8161e5146705fd117aa0bb115fbe7 (patch)
treefad34f34add6e9822052a513c4524cdf4f47e311 /lib/asn1/src/asn1ct_gen_per.erl
parenteb49ee71f0751cf54bc39f9971f389c92525b0a4 (diff)
downloadotp-df7bb30fd0e8161e5146705fd117aa0bb115fbe7.tar.gz
otp-df7bb30fd0e8161e5146705fd117aa0bb115fbe7.tar.bz2
otp-df7bb30fd0e8161e5146705fd117aa0bb115fbe7.zip
PER, UPER: Optimize table constraints
The generated code for table constraints has several problems: * For each object set, a function for getting an encoding or decoding fun is generated, regardless of whether it is actually used. In many specifications, the object set actually used is the union of several other object sets. That means that the code can become a lot bulkier than it would need to be. * The funs are not necessary. The funs just add to the code bloat and generate more unnecessary garbage at run-time. Also, one of the arguments of the fun is the name of the field in the class which is known at compile-time, and the fun for decoding has unused arguments. How to fix the problems: At each call site where an open type should be encoded/decoded, call a specific generated function specialized for the actual object set and the name of the field in the class. When generating the specialized functions, make sure that we re-use a previously generated function if possible.
Diffstat (limited to 'lib/asn1/src/asn1ct_gen_per.erl')
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl634
1 files changed, 2 insertions, 632 deletions
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 2063cb12e5..8b999ddbf0 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -186,615 +186,14 @@ simplify_type(Type) ->
%% Object code generating for encoding and decoding
%% ------------------------------------------------
-gen_obj_code(Erules,_Module,Obj) when is_record(Obj,typedef) ->
- ObjName = Obj#typedef.name,
- Def = Obj#typedef.typespec,
- #'Externaltypereference'{module=Mod,type=ClassName} =
- Def#'Object'.classname,
- Class = asn1_db:dbget(Mod,ClassName),
- {object,_,Fields} = Def#'Object'.def,
- emit({nl,nl,nl,"%%================================"}),
- emit({nl,"%% ",ObjName}),
- emit({nl,"%%================================",nl}),
- EncConstructed =
- gen_encode_objectfields(Erules, ClassName,get_class_fields(Class),
- ObjName,Fields,[]),
- emit(nl),
- gen_encode_constr_type(Erules,EncConstructed),
- emit(nl),
- DecConstructed =
- gen_decode_objectfields(Erules, ClassName, get_class_fields(Class),
- ObjName, Fields, []),
- emit(nl),
- gen_decode_constr_type(Erules,DecConstructed),
- emit(nl).
-
-
-gen_encode_objectfields(Erule, ClassName,
- [{typefield,Name,OptOrMand}|Rest],
- ObjName, ObjectFields, ConstrAcc) ->
- EmitFuncClause =
- fun(V) ->
- emit(["'enc_",ObjName,"'(",{asis,Name},
- ",",V,",_RestPrimFieldName) ->",nl])
- end,
-% emit(["'enc_",ObjName,"'(",{asis,Name},
-% ", Val, _RestPrimFieldName) ->",nl]),
- MaybeConstr =
- case {get_object_field(Name,ObjectFields),OptOrMand} of
- {false,'OPTIONAL'} ->
- EmitFuncClause("Val"),
- emit(" Val"),
- [];
- {false,{'DEFAULT',DefaultType}} ->
- EmitFuncClause("Val"),
- gen_encode_default_call(Erule, ClassName, Name, DefaultType);
- {{Name,TypeSpec},_} ->
- %% A specified field owerwrites any 'DEFAULT' or
- %% 'OPTIONAL' field in the class
- EmitFuncClause("Val"),
- gen_encode_field_call(Erule, ObjName, Name, TypeSpec)
- end,
- case more_genfields(Rest) of
- true ->
- emit([";",nl]);
- false ->
- emit([".",nl])
- end,
- gen_encode_objectfields(Erule,ClassName,Rest,ObjName,ObjectFields,
- MaybeConstr++ConstrAcc);
-gen_encode_objectfields(Erule,ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest],
- ObjName,ObjectFields,ConstrAcc) ->
- CurrentMod = get(currmod),
- EmitFuncClause =
- fun(Attrs) ->
- emit(["'enc_",ObjName,"'(",{asis,Name},
- ",",Attrs,") ->",nl])
- end,
-% emit(["'enc_",ObjName,"'(",{asis,Name},
-% ", Val,[H|T]) ->",nl]),
- case {get_object_field(Name,ObjectFields),OptOrMand} of
- {false,'OPTIONAL'} ->
- EmitFuncClause("_,_"),
- emit([" exit({error,{'use of missing field in object', ",{asis,Name},
- "}})"]);
- {false,{'DEFAULT',_DefaultObject}} ->
- exit({error,{asn1,{"not implemented yet",Name}}});
- {{Name,#'Externalvaluereference'{module=CurrentMod,
- value=TypeName}},_} ->
- EmitFuncClause(" Val, [H|T]"),
- emit({indent(3),"'enc_",TypeName,"'(H, Val, T)"});
- {{Name,#'Externalvaluereference'{module=M,value=TypeName}},_} ->
- EmitFuncClause(" Val, [H|T]"),
- emit({indent(3),"'",M,"':'enc_",TypeName,"'(H, Val, T)"});
- {{Name,TypeSpec},_} ->
- EmitFuncClause("Val,[H|T]"),
- case TypeSpec#typedef.name of
- {ExtMod,TypeName} ->
- emit({indent(3),"'",ExtMod,"':'enc_",TypeName,
- "'(H, Val, T)"});
- TypeName ->
- emit({indent(3),"'enc_",TypeName,"'(H, Val, T)"})
- end
- end,
- case more_genfields(Rest) of
- true ->
- emit([";",nl]);
- false ->
- emit([".",nl])
- end,
- gen_encode_objectfields(Erule,ClassName,Rest,ObjName,ObjectFields,ConstrAcc);
-gen_encode_objectfields(Erule,ClassName,[_C|Cs],O,OF,Acc) ->
- gen_encode_objectfields(Erule,ClassName,Cs,O,OF,Acc);
-gen_encode_objectfields(_, _,[],_,_,Acc) ->
- Acc.
-
-
-gen_encode_constr_type(Erules,[TypeDef|Rest]) when is_record(TypeDef,typedef) ->
- case is_already_generated(enc,TypeDef#typedef.name) of
- true -> ok;
- _ ->
-%% FuncName = list_to_atom(lists:concat(["enc_",TypeDef#typedef.name])),
- FuncName = asn1ct_gen:list2rname(TypeDef#typedef.name ++ [enc]),
- emit(["'",FuncName,"'(Val) ->",nl]),
- Def = TypeDef#typedef.typespec,
- InnerType = asn1ct_gen:get_inner(Def#type.def),
- asn1ct_gen:gen_encode_constructed(Erules,TypeDef#typedef.name,
- InnerType,Def),
- gen_encode_constr_type(Erules,Rest)
- end;
-gen_encode_constr_type(_,[]) ->
+gen_obj_code(_Erules, _Module, #typedef{}) ->
ok.
-gen_encode_field_call(_Erules, _ObjName, _FieldName,
- #'Externaltypereference'{module=M,type=T}) ->
- CurrentMod = get(currmod),
- if
- M == CurrentMod ->
- emit({" 'enc_",T,"'(Val)"}),
- [];
- true ->
- emit({" '",M,"':'enc_",T,"'(Val)"}),
- []
- end;
-gen_encode_field_call(Erules, ObjName, FieldName, Type) ->
- Def = Type#typedef.typespec,
- case Type#typedef.name of
- {primitive,bif} ->
- gen_encode_prim(Erules, Def, "Val"),
- [];
- {constructed,bif} ->
- emit({" 'enc_",ObjName,'_',FieldName,
- "'(Val)"}),
-%% [Type#typedef{name=list_to_atom(lists:concat([ObjName,'_',FieldName]))}];
- [Type#typedef{name=[FieldName,ObjName]}];
- {ExtMod,TypeName} ->
- emit({" '",ExtMod,"':'enc_",TypeName,
- "'(Val)"}),
- [];
- TypeName ->
- emit({" 'enc_",TypeName,"'(Val)"}),
- []
- end.
-
-gen_encode_default_call(Erules, ClassName, FieldName, Type) ->
- CurrentMod = get(currmod),
- InnerType = asn1ct_gen:get_inner(Type#type.def),
- case asn1ct_gen:type(InnerType) of
- {constructed,bif} ->
-%% asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type);
- emit([" 'enc_",ClassName,'_',FieldName,"'(Val)"]),
-%% [#typedef{name=list_to_atom(lists:concat([ClassName,'_',FieldName])),
- [#typedef{name=[FieldName,ClassName],
- typespec=Type}];
- {primitive,bif} ->
- gen_encode_prim(Erules, Type, "Val"),
- [];
- #'Externaltypereference'{module=CurrentMod,type=Etype} ->
- emit([" 'enc_",Etype,"'(Val)",nl]),
- [];
- #'Externaltypereference'{module=Emod,type=Etype} ->
- emit([" '",Emod,"':'enc_",Etype,"'(Val)",nl]),
- []
- end.
-
-
-gen_decode_objectfields(Erules, ClassName,
- [{typefield,Name,OptOrMand}|Rest],
- ObjName, ObjectFields, ConstrAcc) ->
- EmitFuncClause =
- fun(Bytes) ->
- emit(["'dec_",ObjName,"'(",{asis,Name},",",Bytes,
- ",_,_RestPrimFieldName) ->",nl])
- end,
- MaybeConstr=
- case {get_object_field(Name,ObjectFields),OptOrMand} of
- {false,'OPTIONAL'} ->
- EmitFuncClause("Bytes"),
- emit([" {Bytes,[]}"]),
- [];
- {false,{'DEFAULT',DefaultType}} ->
- EmitFuncClause("Bytes"),
- gen_decode_default_call(Erules, ClassName, Name, "Bytes",
- DefaultType);
- {{Name,TypeSpec},_} ->
- %% A specified field owerwrites any 'DEFAULT' or
- %% 'OPTIONAL' field in the class
- EmitFuncClause("Bytes"),
- gen_decode_field_call(Erules, ObjName, Name, "Bytes", TypeSpec)
- end,
- case more_genfields(Rest) of
- true ->
- emit([";",nl]);
- false ->
- emit([".",nl])
- end,
- gen_decode_objectfields(Erules, ClassName, Rest, ObjName,
- ObjectFields, MaybeConstr++ConstrAcc);
-gen_decode_objectfields(Erules, ClassName,
- [{objectfield,Name,_,_,OptOrMand}|Rest],
- ObjName, ObjectFields, ConstrAcc) ->
- CurrentMod = get(currmod),
- EmitFuncClause =
- fun(Attrs) ->
- emit(["'dec_",ObjName,"'(",{asis,Name},
- ",",Attrs,") ->",nl])
- end,
-% emit(["'dec_",ObjName,"'(",{asis,Name},
-% ", Bytes,_,[H|T]) ->",nl]),
- case {get_object_field(Name,ObjectFields),OptOrMand} of
- {false,'OPTIONAL'} ->
- EmitFuncClause("_,_,_"),
- emit([" exit({error,{'illegal use of missing field in object', ",{asis,Name},
- "}})"]);
- {false,{'DEFAULT',_DefaultObject}} ->
- exit({error,{asn1,{"not implemented yet",Name}}});
- {{Name,#'Externalvaluereference'{module=CurrentMod,
- value=TypeName}},_} ->
- EmitFuncClause("Bytes,_,[H|T]"),
- emit({indent(3),"'dec_",TypeName,"'(H, Bytes, telltype, T)"});
- {{Name,#'Externalvaluereference'{module=M,value=TypeName}},_} ->
- EmitFuncClause("Bytes,_,[H|T]"),
- emit({indent(3),"'",M,"':'dec_",TypeName,
- "'(H, Bytes, telltype, T)"});
- {{Name,TypeSpec},_} ->
- EmitFuncClause("Bytes,_,[H|T]"),
- case TypeSpec#typedef.name of
- {ExtMod,TypeName} ->
- emit({indent(3),"'",ExtMod,"':'dec_",TypeName,
- "'(H, Bytes, telltype, T)"});
- TypeName ->
- emit({indent(3),"'dec_",TypeName,"'(H, Bytes, telltype, T)"})
- end
- end,
- case more_genfields(Rest) of
- true ->
- emit([";",nl]);
- false ->
- emit([".",nl])
- end,
- gen_decode_objectfields(Erules, ClassName, Rest, ObjName,
- ObjectFields, ConstrAcc);
-gen_decode_objectfields(Erules, CN, [_C|Cs], O, OF, CAcc) ->
- gen_decode_objectfields(Erules, CN, Cs, O, OF, CAcc);
-gen_decode_objectfields(_, _, [], _, _, CAcc) ->
- CAcc.
-
-
-
-gen_decode_field_call(_Erules, _ObjName, _FieldName, Bytes,
- #'Externaltypereference'{}=Etype) ->
- emit(" "),
- gen_dec_external(Etype, Bytes),
- [];
-gen_decode_field_call(Erules, ObjName, FieldName, Bytes, Type) ->
- Def = Type#typedef.typespec,
- case Type#typedef.name of
- {primitive,bif} ->
- gen_dec_prim(Erules, Def, Bytes),
- [];
- {constructed,bif} ->
- emit({" 'dec_",ObjName,'_',FieldName,
- "'(",Bytes,")"}),
-%% [Type#typedef{name=list_to_atom(lists:concat([ObjName,'_',FieldName]))}];
- [Type#typedef{name=[FieldName,ObjName]}];
- {ExtMod,TypeName} ->
- emit({" '",ExtMod,"':'dec_",TypeName,
- "'(",Bytes,")"}),
- [];
- TypeName ->
- emit({" 'dec_",TypeName,"'(",Bytes,")"}),
- []
- end.
-
-gen_decode_default_call(Erules, ClassName, FieldName, Bytes, Type) ->
- InnerType = asn1ct_gen:get_inner(Type#type.def),
- case asn1ct_gen:type(InnerType) of
- {constructed,bif} ->
- DecFunc = dec_func(lists:concat([ClassName,'_',FieldName])),
- emit([" ",{asis,DecFunc},"(",Bytes,")"]),
- [#typedef{name=[FieldName,ClassName],
- typespec=Type}];
- {primitive,bif} ->
- gen_dec_prim(Erules, Type, Bytes),
- [];
- #'Externaltypereference'{}=Etype ->
- asn1ct_gen_per:gen_dec_external(Etype, Bytes),
- []
- end.
-
-
-gen_decode_constr_type(Erules,[TypeDef|Rest]) when is_record(TypeDef,typedef) ->
- case is_already_generated(dec,TypeDef#typedef.name) of
- true -> ok;
- _ ->
- gen_decode(Erules,TypeDef#typedef{name=asn1ct_gen:list2rname(TypeDef#typedef.name)})
- end,
- gen_decode_constr_type(Erules,Rest);
-gen_decode_constr_type(_,[]) ->
- ok.
-
-
-more_genfields([]) ->
- false;
-more_genfields([Field|Fields]) ->
- case element(1,Field) of
- typefield ->
- true;
- objectfield ->
- true;
- _ ->
- more_genfields(Fields)
- end.
-
%% Object Set code generating for encoding and decoding
%% ----------------------------------------------------
-gen_objectset_code(Erules,ObjSet) ->
- ObjSetName = ObjSet#typedef.name,
- Def = ObjSet#typedef.typespec,
-%% {ClassName,ClassDef} = Def#'ObjectSet'.class,
- #'Externaltypereference'{module=ClassModule,
- type=ClassName} = Def#'ObjectSet'.class,
- ClassDef = asn1_db:dbget(ClassModule,ClassName),
- UniqueFName = Def#'ObjectSet'.uniquefname,
- Set = Def#'ObjectSet'.set,
- emit({nl,nl,nl,"%%================================"}),
- emit({nl,"%% ",ObjSetName}),
- emit({nl,"%%================================",nl}),
- case ClassName of
- {_Module,ExtClassName} ->
- gen_objset_code(Erules,ObjSetName,UniqueFName,Set,
- ExtClassName,ClassDef);
- _ ->
- gen_objset_code(Erules,ObjSetName,UniqueFName,Set,
- ClassName,ClassDef)
- end,
- emit(nl).
-
-gen_objset_code(Erules,ObjSetName,UniqueFName,Set,ClassName,ClassDef)->
- ClassFields = (ClassDef#classdef.typespec)#objectclass.fields,
- InternalFuncs=
- gen_objset_enc(Erules,ObjSetName,UniqueFName,Set,ClassName,ClassFields,1,[]),
- gen_objset_dec(Erules, ObjSetName,UniqueFName,Set,ClassName,ClassFields,1),
- gen_internal_funcs(Erules,InternalFuncs).
-
-%% gen_objset_enc iterates over the objects of the object set
-gen_objset_enc(_,_,{unique,undefined},_,_,_,_,_) ->
- %% There is no unique field in the class of this object set
- %% don't bother about the constraint
- [];
-gen_objset_enc(Erule, ObjSetName, UniqueName, [{ObjName,Val,Fields}|T],
- ClName, ClFields, NthObj, Acc)->
- emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl]),
- CurrMod = get(currmod),
- {InternalFunc,NewNthObj}=
- case ObjName of
- {no_mod,no_name} ->
- gen_inlined_enc_funs(Erule, Fields, ClFields,
- ObjSetName, NthObj);
- {CurrMod,Name} ->
- emit({" fun 'enc_",Name,"'/3"}),
- {[],NthObj};
- {ModName,Name} ->
- emit_ext_encfun(ModName,Name),
- {[],NthObj};
- _Other ->
- emit({" fun 'enc_",ObjName,"'/3"}),
- {[],NthObj}
- end,
- emit({";",nl}),
- gen_objset_enc(Erule, ObjSetName, UniqueName, T, ClName, ClFields,
- NewNthObj, InternalFunc ++ Acc);
-gen_objset_enc(_, ObjSetName, _UniqueName, ['EXTENSIONMARK'],
- _ClName, _ClFields, _NthObj, Acc) ->
- emit(["'getenc_",ObjSetName,"'(_) ->",nl]),
- emit({indent(3),"fun(_, Val, _) ->",nl}),
- emit([indent(6),"Val",nl,
- indent(3),"end.",nl,nl]),
- Acc;
-gen_objset_enc(_, ObjSetName, UniqueName, [], _, _, _, Acc) ->
- emit_default_getenc(ObjSetName, UniqueName),
- emit([".",nl,nl]),
- Acc.
-
-emit_ext_encfun(ModuleName,Name) ->
- emit([indent(4),"fun(T,V,O) -> '",ModuleName,"':'enc_",
- Name,"'(T,V,O) end"]).
-
-emit_default_getenc(ObjSetName,UniqueName) ->
- emit(["'getenc_",ObjSetName,"'(ErrV) ->",nl]),
- emit([indent(4),"fun(C,V,_) -> exit({'Type not compatible with table constraint',{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},",ErrV}}) end"]).
-
-
-%% gen_inlined_enc_funs for each object iterates over all fields of a
-%% class, and for each typefield it checks if the object has that
-%% field and emits the proper code.
-gen_inlined_enc_funs(Erule, Fields, [{typefield,_,_}|_]=T,
- ObjSetName, NthObj) ->
- emit([indent(3),"fun(Type, Val, _) ->",nl,
- indent(6),"case Type of",nl]),
- gen_inlined_enc_funs1(Erule, Fields, T, ObjSetName, [], NthObj, []);
-gen_inlined_enc_funs(Erule,Fields,[_H|Rest],ObjSetName,NthObj) ->
- gen_inlined_enc_funs(Erule,Fields,Rest,ObjSetName,NthObj);
-gen_inlined_enc_funs(_,_,[],_,NthObj) ->
- {[],NthObj}.
-
-gen_inlined_enc_funs1(Erule, Fields, [{typefield,Name,_}|Rest], ObjSetName,
- Sep0, NthObj, Acc0) ->
- emit(Sep0),
- Sep = [";",nl],
- CurrentMod = get(currmod),
- InternalDefFunName = asn1ct_gen:list2name([NthObj,Name,ObjSetName]),
- {Acc,NAdd} =
- case lists:keyfind(Name, 1, Fields) of
- {_,#type{}=Type} ->
- {Ret,N} = emit_inner_of_fun(Erule, Type, InternalDefFunName),
- {Ret++Acc0,N};
- {_,#typedef{}=Type} ->
- emit([indent(9),{asis,Name}," ->",nl]),
- {Ret,N} = emit_inner_of_fun(Erule, Type, InternalDefFunName),
- {Ret++Acc0,N};
- {_,#'Externaltypereference'{module=CurrentMod,type=T}} ->
- emit([indent(9),{asis,Name}," ->",nl,
- indent(12),"'enc_",T,"'(Val)"]),
- {Acc0,0};
- {_,#'Externaltypereference'{module=M,type=T}} ->
- emit([indent(9),{asis,Name}," ->",nl,
- indent(12),"'",M,"'",":'enc_",T,"'(Val)"]),
- {Acc0,0};
- false ->
- emit([indent(9),{asis,Name}," ->",nl,
- indent(12),"Val",nl]),
- {Acc0,0}
- end,
- gen_inlined_enc_funs1(Erule, Fields, Rest, ObjSetName, Sep,
- NthObj+NAdd, Acc);
-gen_inlined_enc_funs1(Erule, Fields, [_|T], ObjSetName, Sep, NthObj, Acc)->
- gen_inlined_enc_funs1(Erule, Fields, T, ObjSetName, Sep, NthObj, Acc);
-gen_inlined_enc_funs1(_, _, [], _, _, NthObj, Acc) ->
- emit([nl,indent(6),"end",nl,
- indent(3),"end"]),
- {Acc,NthObj}.
-
-emit_inner_of_fun(Erule, #typedef{name={ExtMod,Name},typespec=Type}=TDef,
- InternalDefFunName) ->
- case {ExtMod,Name} of
- {primitive,bif} ->
- emit(indent(12)),
- gen_encode_prim(Erule, Type, "Val"),
- {[],0};
- {constructed,bif} ->
- emit([indent(12),"'enc_",
- InternalDefFunName,"'(Val)"]),
- {[TDef#typedef{name=InternalDefFunName}],1};
- _ ->
- emit({indent(12),"'",ExtMod,"':'enc_",Name,"'(Val)"}),
- {[],0}
- end;
-emit_inner_of_fun(_Erule, #typedef{name=Name}, _) ->
- emit({indent(12),"'enc_",Name,"'(Val)"}),
- {[],0};
-emit_inner_of_fun(Erule, #type{}=Type, _) ->
- CurrMod = get(currmod),
- case Type#type.def of
- Def when is_atom(Def) ->
- emit({indent(9),Def," ->",nl,indent(12)}),
- gen_encode_prim(Erule, Type, "Val");
- #'Externaltypereference'{module=CurrMod,type=T} ->
- emit({indent(9),T," ->",nl,indent(12),"'enc_",T,"'(Val)"});
- #'Externaltypereference'{module=ExtMod,type=T} ->
- emit({indent(9),T," ->",nl,indent(12),ExtMod,":'enc_",
- T,"'(Val)"})
- end,
- {[],0}.
-
-indent(N) ->
- lists:duplicate(N,32). % 32 = space
-
-
-gen_objset_dec(_, _, {unique,undefined}, _, _, _, _) ->
- %% There is no unique field in the class of this object set
- %% don't bother about the constraint
- ok;
-gen_objset_dec(Erule, ObjSName, UniqueName, [{ObjName,Val,Fields}|T], ClName,
- ClFields, NthObj)->
- emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl]),
- CurrMod = get(currmod),
- NewNthObj=
- case ObjName of
- {no_mod,no_name} ->
- gen_inlined_dec_funs(Erule, Fields, ClFields,
- ObjSName, NthObj);
- {CurrMod,Name} ->
- emit([" fun 'dec_",Name,"'/4"]),
- NthObj;
- {ModName,Name} ->
- emit_ext_decfun(ModName,Name),
- NthObj;
- _Other ->
- emit({" fun 'dec_",ObjName,"'/4"}),
- NthObj
- end,
- emit({";",nl}),
- gen_objset_dec(Erule, ObjSName, UniqueName, T, ClName, ClFields, NewNthObj);
-gen_objset_dec(_Erule, ObjSetName, _UniqueName, ['EXTENSIONMARK'],
- _ClName, _ClFields, _NthObj) ->
- emit(["'getdec_",ObjSetName,"'(_) ->",nl]),
- emit({indent(3),"fun(Attr1, Bytes, _,_) ->",nl}),
- emit({indent(6),"{Bytes,Attr1}",nl}),
- emit({indent(3),"end.",nl,nl}),
- ok;
-gen_objset_dec(_Erule, ObjSetName, UniqueName, [], _, _, _) ->
- emit_default_getdec(ObjSetName, UniqueName),
- emit([".",nl,nl]),
+gen_objectset_code(_Erules, _ObjSet) ->
ok.
-emit_ext_decfun(ModuleName,Name) ->
- emit([indent(3),"fun(T,V,O1,O2) -> '",ModuleName,"':'dec_",
- Name,"'(T,V,O1,O2) end"]).
-
-emit_default_getdec(ObjSetName,UniqueName) ->
- emit(["'getdec_",ObjSetName,"'(ErrV) ->",nl]),
- emit([indent(2), "fun(C,V,_,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},",ErrV}}) end"]).
-
-
-gen_inlined_dec_funs(Erule, Fields, List, ObjSetName, NthObj0) ->
- emit([indent(3),"fun(Type, Val, _, _) ->",nl,
- indent(6),"case Type of",nl]),
- NthObj = gen_inlined_dec_funs1(Erule, Fields, List,
- ObjSetName, "", NthObj0),
- emit([nl,indent(6),"end",nl,
- indent(3),"end"]),
- NthObj.
-
-gen_inlined_dec_funs1(Erule, Fields, [{typefield,Name,_}|Rest],
- ObjSetName, Sep0, NthObj) ->
- InternalDefFunName = [NthObj,Name,ObjSetName],
- emit(Sep0),
- Sep = [";",nl],
- N = case lists:keyfind(Name, 1, Fields) of
- {_,#type{}=Type} ->
- emit_inner_of_decfun(Erule, Type, InternalDefFunName);
- {_,#typedef{}=Type} ->
- emit([indent(9),{asis,Name}," ->",nl]),
- emit_inner_of_decfun(Erule, Type, InternalDefFunName);
- {_,#'Externaltypereference'{}=Etype} ->
- emit([indent(9),{asis,Name}," ->",nl,
- indent(12)]),
- gen_dec_external(Etype, "Val"),
- 0;
- false ->
- emit([indent(9),{asis,Name}," -> {Val,Type}"]),
- 0
- end,
- gen_inlined_dec_funs1(Erule, Fields, Rest, ObjSetName, Sep, NthObj+N);
-gen_inlined_dec_funs1(Erule, Fields, [_|Rest], ObjSetName, Sep, NthObj) ->
- gen_inlined_dec_funs1(Erule, Fields, Rest, ObjSetName, Sep, NthObj);
-gen_inlined_dec_funs1(_, _, [], _, _, NthObj) -> NthObj.
-
-emit_inner_of_decfun(Erule, #typedef{name={ExtName,Name},typespec=Type},
- InternalDefFunName) ->
- case {ExtName,Name} of
- {primitive,bif} ->
- emit(indent(12)),
- gen_dec_prim(Erule, Type, "Val"),
- 0;
- {constructed,bif} ->
- emit({indent(12),"'dec_",
- asn1ct_gen:list2name(InternalDefFunName),"'(Val)"}),
- 1;
- _ ->
- emit({indent(12),"'",ExtName,"':'dec_",Name,"'(Val)"}),
- 0
- end;
-emit_inner_of_decfun(_Erule, #typedef{name=Name}, _) ->
- emit({indent(12),"'dec_",Name,"'(Val)"}),
- 0;
-emit_inner_of_decfun(Erule, #type{}=Type, _) ->
- CurrMod = get(currmod),
- case Type#type.def of
- Def when is_atom(Def) ->
- emit({indent(9),Def," ->",nl,indent(12)}),
- gen_dec_prim(Erule, Type, "Val");
- #'Externaltypereference'{module=CurrMod,type=T} ->
- emit({indent(9),T," ->",nl,indent(12),"'dec_",T,"'(Val)"});
- #'Externaltypereference'{module=ExtMod,type=T} ->
- emit({indent(9),T," ->",nl,indent(12),ExtMod,":'dec_",
- T,"'(Val)"})
- end,
- 0.
-
-
-gen_internal_funcs(_,[]) ->
- ok;
-gen_internal_funcs(Erules,[TypeDef|Rest]) ->
- gen_encode_user(Erules,TypeDef),
- emit([nl,nl,"'dec_",TypeDef#typedef.name,"'(Bytes) ->",nl]),
- gen_decode_user(Erules,TypeDef),
- gen_internal_funcs(Erules,Rest).
-
-
-
%% DECODING *****************************
%%***************************************
@@ -979,35 +378,6 @@ gen_dec_prim(Erule, Type, BytesVar) ->
Imm = gen_dec_imm(Erule, Type),
asn1ct_imm:dec_code_gen(Imm, BytesVar).
-is_already_generated(Operation,Name) ->
- case get(class_default_type) of
- undefined ->
- put(class_default_type,[{Operation,Name}]),
- false;
- GeneratedList ->
- case lists:member({Operation,Name},GeneratedList) of
- true ->
- true;
- false ->
- put(class_default_type,[{Operation,Name}|GeneratedList]),
- false
- end
- end.
-
-get_class_fields(#classdef{typespec=ObjClass}) ->
- ObjClass#objectclass.fields;
-get_class_fields(#objectclass{fields=Fields}) ->
- Fields;
-get_class_fields(_) ->
- [].
-
-
-get_object_field(Name,ObjectFields) ->
- case lists:keysearch(Name,1,ObjectFields) of
- {value,Field} -> Field;
- false -> false
- end.
-
%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
%% the components within the ExtensionAdditionGroup is treated in a similar way as if they