142
142
case D#type.def of
144
144
emit({"?RT_PER:encode_integer(", %fel
145
{asis,Constraint},",",Value,")"});
145
{asis,effective_constraint(integer,Constraint)},",",Value,")"});
146
146
{'INTEGER',NamedNumberList} ->
147
147
emit({"?RT_PER:encode_integer(",
148
{asis,Constraint},",",Value,",",
148
{asis,effective_constraint(integer,Constraint)},",",Value,",",
149
149
{asis,NamedNumberList},")"});
150
150
{'ENUMERATED',{Nlist1,Nlist2}} ->
151
151
NewList = lists:concat([[{0,X}||{X,_} <- Nlist1],['EXT_MARK'],[{1,X}||{X,_} <- Nlist2]]),
257
257
emit_enc_enumerated_case(C, EnumName, Count) ->
258
258
emit(["'",EnumName,"' -> ?RT_PER:encode_integer(",{asis,C},", ",Count,")"]).
260
%% effective_constraint(Type,C)
263
%% C1 = {'SingleValue',SV} | {'ValueRange',VR} | {atom(),term()}
264
%% SV = integer() | [integer(),...]
266
%% Lb = 'MIN' | integer()
267
%% Ub = 'MAX' | integer()
268
%% Returns a single value if C only has a single value constraint, and no
269
%% value range constraints, that constrains to a single value, otherwise
270
%% returns a value range that has the lower bound set to the lowest value
271
%% of all single values and lower bound values in C and the upper bound to
272
%% the greatest value.
273
effective_constraint(integer,[C={{_,_},_}|_Rest]) -> % extension
274
[C]; %% [C|effective_constraint(integer,Rest)]; XXX what is possible ???
275
effective_constraint(integer,C) ->
276
SVs = get_constraints(C,'SingleValue'),
277
SV = effective_constr('SingleValue',SVs),
278
VRs = get_constraints(C,'ValueRange'),
279
VR = effective_constr('ValueRange',VRs),
280
greatest_common_range(SV,VR);
281
% effective_constraint(bitstring,C) ->
282
% Constr=get_constraints(C,'SizeConstraint'),
285
% [{'SizeConstraint',Val}] -> Val;
288
% get_constraint(C,'SizeConstraint');
289
effective_constraint(Type,C) ->
290
io:format("Effective constraint for ~p, not implemented yet.~n",[Type]),
293
effective_constr(_,[]) ->
295
effective_constr('SingleValue',List) ->
296
SVList = lists:flatten(lists:map(fun(X)->element(2,X)end,List)),
297
% sort and remove duplicates
298
% SortedSVList = lists:sort(SVList),
299
RemoveDup = fun([],_) ->[];
301
([H,H|T],F) -> F([H|T],F);
302
([H|T],F) -> [H|F(T,F)]
305
case RemoveDup(SVList,RemoveDup) of
309
[{'ValueRange',{hd(L),lists:last(L)}}]
311
effective_constr('ValueRange',List) ->
312
LBs = lists:map(fun({_,{Lb,_}})-> Lb end,List),
313
UBs = lists:map(fun({_,{_,Ub}})-> Ub end,List),
315
[{'ValueRange',{Lb,lists:max(UBs)}}].
317
greatest_common_range([],VR) ->
319
greatest_common_range(SV,[]) ->
321
greatest_common_range([{_,Int}],[{_,{'MIN',Ub}}]) when integer(Int),
323
[{'ValueRange',{'MIN',Int}}];
324
greatest_common_range([{_,Int}],[{_,{Lb,Ub}}]) when integer(Int),
326
[{'ValueRange',{Int,Ub}}];
327
greatest_common_range([{_,Int}],VR=[{_,{_Lb,_Ub}}]) when integer(Int) ->
329
greatest_common_range([{_,L}],[{_,{Lb,Ub}}]) when list(L) ->
330
Min = least_Lb([Lb|L]),
331
Max = greatest_Ub([Ub|L]),
332
[{'ValueRange',{Min,Max}}].
336
case lists:member('MIN',L) of
342
case lists:member('MAX',L) of
348
get_constraints(L=[{Key,_}],Key) ->
350
get_constraints([],_) ->
352
get_constraints(C,Key) ->
353
{value,L} = keysearch_allwithkey(Key,1,C,[]),
356
keysearch_allwithkey(Key,Ix,C,Acc) ->
357
case lists:keysearch(Key,Ix,C) of
361
RestC = lists:delete(T,C),
362
keysearch_allwithkey(Key,Ix,RestC,[T|Acc])
261
366
%% Object code generating for encoding and decoding
262
367
%% ------------------------------------------------
783
888
ClName,ClFields,NthObj,Acc)->
784
889
emit({"'getenc_",ObjSName,"'(",{asis,UniqueName},",",{asis,Val},
891
CurrMod = get(currmod),
786
892
{InternalFunc,NewNthObj}=
789
895
gen_inlined_enc_funs(Fields,ClFields,ObjSName,NthObj);
897
emit({" fun 'enc_",Name,"'/3"}),
900
emit_ext_encfun(ModName,Name),
901
% emit([" {'",ModName,"', 'enc_",Name,"'}"]),
791
904
emit({" fun 'enc_",ObjName,"'/3"}),
800
913
emit({"'getenc_",ObjSetName,"'(",{asis,UniqueName},",",
801
914
{asis,Val},") ->",nl}),
915
CurrMod = get(currmod),
802
916
{InternalFunc,_}=
805
919
gen_inlined_enc_funs(Fields,ClFields,ObjSetName,NthObj);
921
emit({" fun 'enc_",Name,"'/3"}),
924
emit_ext_encfun(ModName,Name),
925
% emit([" {'",ModName,"', 'enc_",Name,"'}"]),
807
928
emit({" fun 'enc_",ObjName,"'/3"}),
932
emit_default_getenc(ObjSetName,UniqueName),
810
933
emit({".",nl,nl}),
811
934
InternalFunc++Acc;
812
935
gen_objset_enc(ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
819
942
gen_objset_enc(_,_,[],_,_,_,Acc) ->
945
emit_ext_encfun(ModuleName,Name) ->
946
emit([indent(4),"fun(T,V,O) -> '",ModuleName,"':'enc_",
947
Name,"'(T,V,O) end"]).
949
emit_default_getenc(ObjSetName,UniqueName) ->
950
emit(["'getenc_",ObjSetName,"'(",{asis,UniqueName},", _) ->",nl]),
951
emit([indent(4),"fun(C,V,_) -> exit({'Type not compatible with table constraint',{component,C},{value,V}}) end"]).
822
954
%% gen_inlined_enc_funs for each object iterates over all fields of a
823
955
%% class, and for each typefield it checks if the object has that
824
956
%% field and emits the proper code.
955
1095
emit({"'getdec_",ObjSetName,"'(",{asis,UniqueName},",",{asis,Val},
1097
CurrMod=get(currmod),
959
1100
gen_inlined_dec_funs(Fields,ClFields,ObjSetName,NthObj);
1102
emit([" fun 'dec_",Name,"'/4"]);
1104
emit_ext_decfun(ModName,Name);
1105
% emit([" {'",ModName,"', 'dec_",Name,"'}"]);
961
1107
emit({" fun 'dec_",ObjName,"'/4"})
1110
emit_default_getdec(ObjSetName,UniqueName),
963
1111
emit({".",nl,nl}),
965
1113
gen_objset_dec(ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,_ClFields,
973
1121
gen_objset_dec(_,_,[],_,_,_) ->
1124
emit_ext_decfun(ModuleName,Name) ->
1125
emit([indent(3),"fun(T,V,O1,O2) -> '",ModuleName,"':'dec_",
1126
Name,"'(T,V,O1,O2) end"]).
1128
emit_default_getdec(ObjSetName,UniqueName) ->
1129
emit(["'getdec_",ObjSetName,"'(",{asis,UniqueName},", _) ->",nl]),
1130
emit([indent(2), "fun(C,V,_,_) -> exit({{component,C},{value,V}}) end"]).
976
1133
gen_inlined_dec_funs(Fields,[{typefield,Name,_}|Rest],
977
1134
ObjSetName,NthObj) ->
978
1135
CurrMod = get(currmod),