File 2412-Refactor-encoding-of-optional-values.patch of Package erlang

From a586ed43fc47bed6e3ff1d162ef0e1844de6ac50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 20 Jan 2017 10:27:08 +0100
Subject: [PATCH 12/14] Refactor encoding of optional values

As a preparation for supporting maps in a future commit, refactor
the functions for encoding optional values.
---
 lib/asn1/src/asn1ct_constructed_per.erl | 59 ++++++++++++++++++---------------
 lib/asn1/src/asn1ct_imm.erl             | 25 +++++---------
 2 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index 412114622..15fc91377 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -59,7 +59,7 @@ gen_encode_constructed(Erule, Typename, #type{}=D) ->
     asn1ct_imm:enc_cg(Imm, is_aligned(Erule)),
     emit([".",nl]).
 
-gen_encode_constructed_imm(Erule, Typename, #type{}=D) ->
+gen_encode_constructed_imm(Gen, Typename, #type{}=D) ->
     {CompList,TableConsInfo} = enc_complist(D),
     ExternalImm =
 	case Typename of
@@ -71,12 +71,10 @@ gen_encode_constructed_imm(Erule, Typename, #type{}=D) ->
 	    _ ->
 		[]
 	end,
-    Aligned = is_aligned(Erule),
-    Value0 = make_var(val),
     Optionals = optionals(to_textual_order(CompList)),
-    ImmOptionals = [asn1ct_imm:per_enc_optional(Value0, Opt, Aligned) ||
-		       Opt <- Optionals],
+    ImmOptionals = enc_optionals(Gen, Optionals),
     Ext = extensible_enc(CompList),
+    Aligned = is_aligned(Gen),
     ExtImm = case Ext of
 		 {ext,ExtPos,NumExt} when NumExt > 0 ->
 		     gen_encode_extaddgroup(CompList),
@@ -96,7 +94,7 @@ gen_encode_constructed_imm(Erule, Typename, #type{}=D) ->
 	    _ ->
 		[]
 	end,
-    ImmBody = gen_enc_components_call(Erule, Typename, CompList, EncObj, Ext),
+    ImmBody = gen_enc_components_call(Gen, Typename, CompList, EncObj, Ext),
     ExternalImm ++ ExtImm ++ ObjSetImm ++
 	asn1ct_imm:enc_append([ImmSetExt] ++ ImmOptionals ++ ImmBody).
 
@@ -149,6 +147,17 @@ enc_table(_Gen, _, #type{tablecinf=TCInf}) ->
             {false,[]}
     end.
 
+enc_optionals(Gen, Optionals) ->
+    Var = make_var(val),
+    enc_optionals_1(Gen, Optionals, Var).
+
+enc_optionals_1(Gen, [{Pos,DefVals}|T], Var) ->
+    {Imm0,Element} = asn1ct_imm:enc_element(Pos+1, Var),
+    Imm = asn1ct_imm:per_enc_optional(Element, DefVals),
+    [Imm0++Imm|enc_optionals_1(Gen, T, Var)];
+enc_optionals_1(_, [], _) ->
+    [].
+
 gen_encode_extaddgroup(CompList) ->
     case extgroup_pos_and_length(CompList) of
 	{extgrouppos,[]} ->
@@ -729,28 +738,26 @@ gen_dec_optionals(Optionals) ->
     {imm,Imm0,E}.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Produce a list with positions (in the Value record) where
-%% there are optional components, start with 2 because first element
-%% is the record name
-
-optionals({L1,Ext,L2}) ->
-    Opt1 = optionals(L1,[],2),
-    ExtComps = length([C||C = #'ComponentType'{}<-Ext]),
-    Opt2 = optionals(L2,[],2+length(L1)+ExtComps),
-    Opt1 ++ Opt2;
-optionals({L,_Ext}) -> optionals(L,[],2); 
-optionals(L) -> optionals(L,[],2).
 
-optionals([#'ComponentType'{prop='OPTIONAL'}|Rest], Acc, Pos) ->
-    optionals(Rest, [Pos|Acc], Pos+1);
-optionals([#'ComponentType'{typespec=T,prop={'DEFAULT',Val}}|Rest],
-	  Acc, Pos) ->
+optionals({Root1,Ext,Root2}) ->
+    Opt1 = optionals(Root1, 1),
+    ExtComps = length([C || C = #'ComponentType'{} <- Ext]),
+    Opt2 = optionals(Root2, 1 + length(Root1) + ExtComps),
+    Opt1 ++ Opt2;
+optionals({L,_Ext}) ->
+    optionals(L, 1);
+optionals(L) ->
+    optionals(L, 1).
+
+optionals([#'ComponentType'{prop='OPTIONAL'}|Rest], Pos) ->
+    [{Pos,[asn1_NOVALUE]}|optionals(Rest, Pos+1)];
+optionals([#'ComponentType'{typespec=T,prop={'DEFAULT',Val}}|Cs], Pos) ->
     Vals = def_values(T, Val),
-    optionals(Rest, [{Pos,Vals}|Acc], Pos+1);
-optionals([#'ComponentType'{}|Rest], Acc, Pos) ->
-    optionals(Rest, Acc, Pos+1);
-optionals([], Acc, _) ->
-    lists:reverse(Acc).
+    [{Pos,Vals}|optionals(Cs, Pos+1)];
+optionals([#'ComponentType'{}|Rest], Pos) ->
+    optionals(Rest, Pos+1);
+optionals([], _) ->
+    [].
 
 %%%%%%%%%%%%%%%%%%%%%%
 %% create_optionality_table(Cs=[#'ComponentType'{textual_order=undefined}|_]) ->
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index 8b96242c5..741d54c32 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -37,7 +37,7 @@
 	 per_enc_open_type/2,
 	 per_enc_restricted_string/3,
 	 per_enc_small_number/2]).
--export([per_enc_extension_bit/2,per_enc_extensions/4,per_enc_optional/3]).
+-export([per_enc_extension_bit/2,per_enc_extensions/4,per_enc_optional/2]).
 -export([per_enc_sof/5]).
 -export([enc_absent/3,enc_append/1,enc_element/2]).
 -export([enc_cg/2]).
@@ -349,27 +349,18 @@ per_enc_extensions(Val0, Pos0, NumBits, Aligned) when NumBits > 0 ->
 			['_'|Length ++ PutBits]]}],
 	 {var,"Extensions"}}].
 
-per_enc_optional(Val0, {Pos,DefVals}, _Aligned) when is_integer(Pos),
-						     is_list(DefVals) ->
-    {B,Val} = enc_element(Pos, Val0),
+per_enc_optional(Val, DefVals) when is_list(DefVals) ->
     Zero = {put_bits,0,1,[1]},
     One = {put_bits,1,1,[1]},
-    B++[{'cond',
-	 [[{eq,Val,DefVal},Zero] || DefVal <- DefVals] ++ [['_',One]]}];
-per_enc_optional(Val0, {Pos,{call,M,F,A}}, _Aligned) when is_integer(Pos) ->
-    {B,Val} = enc_element(Pos, Val0),
+    [{'cond',
+      [[{eq,Val,DefVal},Zero] || DefVal <- DefVals] ++ [['_',One]]}];
+per_enc_optional(Val, {call,M,F,A}) ->
     {[],[[],Tmp]} = mk_vars([], [tmp]),
     Zero = {put_bits,0,1,[1]},
     One = {put_bits,1,1,[1]},
-    B++[{call,M,F,[Val|A],Tmp},
-	{'cond',
-	 [[{eq,Tmp,true},Zero],['_',One]]}];
-per_enc_optional(Val0, Pos, _Aligned) when is_integer(Pos) ->
-    {B,Val} = enc_element(Pos, Val0),
-    Zero = {put_bits,0,1,[1]},
-    One = {put_bits,1,1,[1]},
-    B++[{'cond',[[{eq,Val,asn1_NOVALUE},Zero],
-		 ['_',One]]}].
+    [{call,M,F,[Val|A],Tmp},
+     {'cond',
+      [[{eq,Tmp,true},Zero],['_',One]]}].
 
 per_enc_sof(Val0, Constraint, ElementVar, ElementImm, Aligned) ->
     {B,[Val,Len]} = mk_vars(Val0, [len]),
-- 
2.11.1

openSUSE Build Service is sponsored by