aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2017-07-13 01:28:06 +0200
committerAnders Svensson <[email protected]>2017-08-03 17:14:28 +0200
commite0603ba18a67c1ef33f60122fe6f00393c0c0203 (patch)
tree3ee53cc9989492b83de76014bbe15f14aa867af5 /lib/diameter/src/base
parent58f9d631df0c256f7bc4ff3de2670b3b04e265f7 (diff)
downloadotp-e0603ba18a67c1ef33f60122fe6f00393c0c0203.tar.gz
otp-e0603ba18a67c1ef33f60122fe6f00393c0c0203.tar.bz2
otp-e0603ba18a67c1ef33f60122fe6f00393c0c0203.zip
Tweak map-valued decode
Use the same [MsgName | Avps] representation as for the list decode, but with Avps a map instead of a AVP name/values list. As a result, don't set the message/AVP name on an additional key in the map, which felt a bit odd. Messages are [MsgName :: atom() | map()], Grouped AVPs are just map(). Fix at least one problem in the traffic suite along the way: with decode_format false, the own decode in to_map/2 didn't know whether or not to decode strings, resulting on some failures.
Diffstat (limited to 'lib/diameter/src/base')
-rw-r--r--lib/diameter/src/base/diameter_codec.erl7
-rw-r--r--lib/diameter/src/base/diameter_gen.erl13
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl58
3 files changed, 30 insertions, 48 deletions
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index 275e80b9bb..9b21bf4141 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -275,9 +275,6 @@ rec2msg(_, [Name|_])
when is_atom(Name) ->
Name;
-rec2msg(_, #{':name' := Name}) ->
- Name;
-
rec2msg(Mod, Rec) ->
Mod:rec2msg(element(1, Rec)).
@@ -383,7 +380,9 @@ decode_avps(MsgName, Mod, AppMod, Opts, Pkt, Avps) -> %% ... or not
errors = Errors,
avps = As}.
-reformat(MsgName, Avps, #{decode_format := list}) ->
+reformat(MsgName, Avps, #{decode_format := T})
+ when T == map;
+ T == list ->
[MsgName | Avps];
reformat(_, Msg, _) ->
diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl
index 78d8bd2fa3..597ec143a8 100644
--- a/lib/diameter/src/base/diameter_gen.erl
+++ b/lib/diameter/src/base/diameter_gen.erl
@@ -186,7 +186,7 @@ decode_avps(Name, Recs, #{module := Mod, decode_format := Fmt} = Opts) ->
%% AM counts the number of top-level AVPs, which missing/4 then
%% uses when adding 5005 errors.
Arities = Mod:avp_arity(Name),
- {reformat(Rec, Arities, Mod, Fmt),
+ {reformat(Name, Rec, Arities, Mod, Fmt),
Avps,
Failed ++ missing(Arities, Opts, Mod, AM)}.
@@ -752,8 +752,8 @@ newrec(_, _, false = No) ->
newrec(Mod, Name, record) ->
newrec(Mod, Name);
-newrec(_, Name, _) ->
- #{':name' => Name}.
+newrec(_, _, _) ->
+ #{}.
%% newrec/2
@@ -762,15 +762,14 @@ newrec(Mod, Name) ->
%% reformat/4
-reformat(Map, Arities, _Mod, list) ->
+reformat(_, Map, Arities, _Mod, list) ->
[{F,V} || {F,_} <- Arities, #{F := V} <- [Map]];
-reformat(Map, Arities, Mod, record_from_map) ->
- #{':name' := Name} = Map,
+reformat(Name, Map, Arities, Mod, record_from_map) ->
RecName = Mod:name2rec(Name),
list_to_tuple([RecName | [maps:get(F, Map, def(A)) || {F,A} <- Arities]]);
-reformat(Rec, _, _, _) ->
+reformat(_, Rec, _, _, _) ->
Rec.
%% def/1
diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl
index f684f60cb7..e9c422d6ab 100644
--- a/lib/diameter/src/base/diameter_traffic.erl
+++ b/lib/diameter/src/base/diameter_traffic.erl
@@ -621,16 +621,10 @@ is_answer_message(#diameter_packet{msg = Msg}, Dict0) ->
is_answer_message([#diameter_header{is_request = R, is_error = E} | _], _) ->
E andalso not R;
-%% Message sent as a tagged avp/value list.
+%% Message sent as a map or tagged avp/value list.
is_answer_message([Name | _], _) ->
Name == 'answer-message';
-%% Message sent as a map.
-is_answer_message(Map, _)
- when is_map(Map) ->
- #{':name' := Name} = Map,
- Name == 'answer-message';
-
%% Message sent as a record.
is_answer_message(Rec, Dict) ->
try
@@ -875,15 +869,13 @@ reset(Msg, [RC | Avps], Dict) ->
%% set/3
-%% Reply as name and tuple list ...
+%% Reply as name/values list ...
+set([Name|As], Avps, _)
+ when is_map(As) ->
+ [Name | maps:merge(As, maps:from_list(Avps))];
set([_|_] = Ans, Avps, _) ->
Ans ++ Avps; %% Values nearer tail take precedence.
-%% ... a map ...
-set(Ans, Avps, _)
- when is_map(Ans) ->
- maps:merge(Ans, maps:from_list(Avps));
-
%% ... or record.
set(Rec, Avps, Dict) ->
Dict:'#set-'(Avps, Rec).
@@ -902,9 +894,6 @@ rc([MsgName | _], RC, Dict) ->
_ -> []
end;
-rc(#{':name' := Name}, RC, Dict) ->
- rc([Name], RC, Dict);
-
rc(Rec, RC, Dict) ->
rc([Dict:rec2msg(element(1, Rec))], RC, Dict).
@@ -937,10 +926,6 @@ failed(Msg, FailedAvp, Dict) ->
msg2rec([MsgName | _], Dict) ->
Dict:msg2rec(MsgName);
-%% ... map ...
-msg2rec(#{':name' := MsgName}, Dict) ->
- Dict:msg2rec(MsgName);
-
%% ... or record.
msg2rec(Rec, _) ->
element(1, Rec).
@@ -949,12 +934,11 @@ msg2rec(Rec, _) ->
%% Message as name/values list ...
values([_ | Avps], F, _) ->
- proplists:get_value(F, Avps, []);
-
-%% ... map ...
-values(Msg, F, _)
- when is_map(Msg) ->
- maps:get(F, Msg, []);
+ if is_map(Avps) ->
+ maps:get(F, Avps, []);
+ is_list(Avps) ->
+ proplists:get_value(F, Avps, [])
+ end;
%% ... or record.
values(Rec, F, Dict) ->
@@ -1906,23 +1890,13 @@ get_avp(Dict, Name, [#diameter_header{} | Avps]) ->
%% Message as name/values list ...
get_avp(_, Name, [_MsgName | Avps]) ->
- case lists:keyfind(Name, 1, Avps) of
+ case find(Name, Avps) of
{_, V} ->
#diameter_avp{name = Name, value = V};
_ ->
undefined
end;
-%% ... map ...
-get_avp(_, Name, Map)
- when is_map(Map) ->
- case maps:find(Name, Map) of
- {ok, V} ->
- #diameter_avp{name = Name, value = V};
- error ->
- undefined
- end;
-
%% ... or record (but not necessarily).
get_avp(Dict, Name, Rec) ->
try
@@ -1932,6 +1906,16 @@ get_avp(Dict, Name, Rec) ->
undefined
end.
+%% find/2
+
+find(Key, Map)
+ when is_map(Map) ->
+ maps:find(Key, Map);
+
+find(Key, List)
+ when is_list(List) ->
+ lists:keyfind(Key, 1, List).
+
%% get_avp_value/3
get_avp_value(Dict, Name, Msg) ->