cosnotification_filter.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 964 行 · 第 1/3 页
ERL
964 行
lookup(['_type_id'], S, _Op) when tuple(S) -> M=element(1, S), Name = case catch M:tc() of {tk_union,_,ID,_,_,_} -> ID; {tk_enum, _, ID, _} -> ID; {tk_exception, _, ID, _} -> ID; {tk_alias, _, ID, _} -> ID; {tk_struct,_,ID,_} -> ID end, {ok, Name};lookup(['_repos_id'], S, _Op) when record(S,'CosNotification_StructuredEvent') -> {ok, 'CosNotification_StructuredEvent':id()};lookup(['_repos_id'], S, _Op) when record(S,'CosNotification_EventHeader') -> {ok, 'CosNotification_EventHeader':id()};lookup(['_repos_id'], S, _Op) when record(S,'CosNotification_FixedEventHeader') -> {ok, 'CosNotification_FixedEventHeader':id()};lookup(['_repos_id'], S, _Op) when record(S,'CosNotification_EventType') -> {ok, 'CosNotification_EventType':id()};lookup(['_repos_id'], S, _Op) when record(S,'CosNotification_Property') -> {ok, 'CosNotification_Property':id()};lookup(['_repos_id'], S, _Op) when tuple(S) -> M = element(1, S), {ok, M:id()};lookup(_, _, _) -> error.%%------------------------------------------------------------%% function : locate_var%% Arguments: Paths - A list of path-lists which tells us where%% to search for runtime variables and in which%% order.%% S - Data%% Op - se lookup/3%% Returns : {error, _} |%% {ok, Val}%%------------------------------------------------------------locate_var([], _S, _) -> {error, "not found"};locate_var([H|T], S, Op) -> case catch lookup(H, S, Op) of {ok, Val} -> {ok,Val}; _ -> locate_var(T, S, Op) end.%%------------------------------------------------------------%% function : id2switch%% Arguments: UList - The list of elements contained in the %% Union TypeCode.%% ID - string() eq name of element.%% Returns : Acc - A list of switches related to given ID.%%------------------------------------------------------------id2switch(UList, ID) -> id2switch(UList, ID, [], false).id2switch([], _, Acc, _) -> Acc;id2switch([{Sw, ID, _}|T], ID, Acc, _) -> id2switch(T, ID, [Sw|Acc], true);id2switch([_|_T], _ID, Acc, true) -> Acc;id2switch([_|T], ID, Acc, Found) -> id2switch(T, ID, Acc, Found).%%------------------------------------------------------------%% function : switch2alias%% Arguments: UList - The list of elements contained in the %% Union TypeCode.%% Switch - the union discriminator.%% Returns : Acc - A list of switches that are defined with the same %% ID - The switches common ID.%% Comment : A union IDL code can look like:%% union Union switch(long) {%% case 1:%% case 2: long ID; };%% In this case supplying Switch == 1 (or) the result%% should be {ok, [1,2], "ID"}%%------------------------------------------------------------switch2alias([], _Switch) -> %% Is it really possible to define an empty union?? {ok, [], undefined};switch2alias([{Sw, ID, TC}|UList], Switch) -> switch2alias([{Sw, ID, TC}|UList], Switch, [], ID, false).switch2alias([{default, ID, _}], _, _, _, false) -> {ok, default, ID};switch2alias([], _, _Acc, _, false) -> {ok, [], undefined};switch2alias([], _, Acc, PreviousID, _) -> {ok, Acc, PreviousID};%% Seen the ID before but just found the correct switch, e.g.,%% [... {0,"K",{tk_string,0}}, {2,"K",{tk_string,0}}...] and switch eq '2'switch2alias([{Switch, PreviousID, _}|T], Switch, Acc, PreviousID, _Found) -> switch2alias(T, Switch, [Switch|Acc], PreviousID, true);%% First time for this ID and found the correct switchswitch2alias([{Switch, ID, _}|T], Switch, _Acc, _PreviousID, false) -> switch2alias(T, Switch, [Switch], ID, true);%% Seen this ID and found the correct switch before.switch2alias([{Sw, PreviousID, _}|T], Switch, Acc, PreviousID, true) -> switch2alias(T, Switch, [Sw|Acc], PreviousID, true);%% Seen this ID but not found the correct switch.switch2alias([{Sw, PreviousID, _}|T], Switch, Acc, PreviousID, false) -> switch2alias(T, Switch, [Sw|Acc], PreviousID, false);%% No more of the correct ID/Switch. Done.switch2alias([{_, _ID, _}|_], _, Acc, PreviousID, true) -> {ok, Acc, PreviousID};%% Not found correct switch and ID is updated.switch2alias([{Sw, ID, _}|T], Switch, _Acc, _PreviousID, Found) -> switch2alias(T, Switch, [Sw], ID, Found).%%------------------------------------------------------------%% function : get_field%% Arguments: ID - element name%% List - The list of elements contained in the %% TypeCode.%% Returns : false |%% offset%%------------------------------------------------------------get_field(ID, List) -> get_field(ID, List, 2).get_field(_ID, [], _) -> false;get_field(ID, [ID|_], I) -> %% Memberlists in enum. I;get_field(ID, [{ID,_}|_], I) -> %% Memberlists in structs. I;get_field(ID, [_|T], I) -> get_field(ID, T, I+1).%%------------------------------------------------------------%% function : check_types%% Arguments: A sequence of CosNotification::EventType{}, i.e., %% name-value pairs.%% Returns : {ok, WhichType, WC}%% WhichType - type/domain/both%% WC - [Types using wildcard]%%------------------------------------------------------------%% With check_types we try to determin if one or more EventTypes force us to check%% all events against this constraint. For example:%% EventType A1 has domain_name="car",type_name = "*"%% EventType A2 has domain_name="*",type_name = "DodgeViper"%% Since A1 says that we must test against any type_name and A2 %% against any domain_name, we must test all events using these permutations.%% It's better to do these test now instead of when we are up and running. But%% if a client change the constraints VERY often it's up to them and they have%% to accept the delay.%%------------------------------------------------------------%% If types is an empty list it means that this constraint must be used %% for all events.check_types([]) -> true;check_types(Types) -> check_types(Types, both, []).check_types([], Which, WildCard) -> {ok, Which, WildCard};%% The following cases means that all events matches.check_types([#'CosNotification_EventType'{domain_name="",type_name = ""}|_T],_,_) -> true;check_types([#'CosNotification_EventType'{domain_name="",type_name = "*"}|_T],_,_) -> true;check_types([#'CosNotification_EventType'{domain_name="*",type_name = ""}|_T],_,_) -> true;check_types([#'CosNotification_EventType'{domain_name="*",type_name = "*"}|_T],_,_) -> true;%% The following cases means that all events must be tested using this constraint.check_types([#'CosNotification_EventType'{domain_name="",type_name = Ty}|T], domain,WC) when list(Ty) -> check_wildcard(T, all, WC, "", Ty);check_types([#'CosNotification_EventType'{domain_name="*",type_name = Ty}|T], domain, WC) when list(Ty) -> check_wildcard(T, all, WC, "", Ty);check_types([#'CosNotification_EventType'{domain_name=Do,type_name = ""}|T], type,WC) when list(Do) -> check_wildcard(T, all, WC, Do, "");check_types([#'CosNotification_EventType'{domain_name=Do,type_name = "*"}|T], type,WC) when list(Do) -> check_wildcard(T, all, WC, Do, "");%% The following cases is used to prevent other cases from converting,%% for example, all->type.check_types([#'CosNotification_EventType'{domain_name="",type_name = Ty}|T], all,WC) when list(Ty) -> check_wildcard(T, all, WC, "", Ty);check_types([#'CosNotification_EventType'{domain_name="*",type_name = Ty}|T], all,WC) when list(Ty) -> check_wildcard(T, all, WC, "", Ty);check_types([#'CosNotification_EventType'{domain_name=Do,type_name = ""}|T], all,WC) when list(Do) -> check_wildcard(T, all, WC, Do, "");check_types([#'CosNotification_EventType'{domain_name=Do,type_name = "*"}|T], all,WC) when list(Do) -> check_wildcard(T, all, WC, Do, "");%% The following cases means that all events with matching Type must be %% tested using this constraint.check_types([#'CosNotification_EventType'{domain_name="",type_name = Ty}|T], _W,WC) when list(Ty) -> check_wildcard(T, type, WC, "", Ty);check_types([#'CosNotification_EventType'{domain_name="*",type_name = Ty}|T], _W,WC) when list(Ty) -> check_wildcard(T, type, WC, "", Ty);%% The following cases means that all events with matching Domain must be %% tested using this constraint.check_types([#'CosNotification_EventType'{domain_name=Do,type_name = ""}|T], _W,WC) when list(Do) -> check_wildcard(T, domain, WC, Do, "");check_types([#'CosNotification_EventType'{domain_name=Do,type_name = "*"}|T], _W,WC) when list(Do) -> check_wildcard(T, domain, WC, Do, "");%% Sorry, no shortcuts.check_types([#'CosNotification_EventType'{domain_name=Do,type_name=Ty}|T], W,WC) when list(Do), list(Ty) -> check_wildcard(T, W, WC, Do, Ty);check_types([H|_], _,_) when record(H, 'CosNotification_EventType') -> %% Not valid. corba:raise(#'CosNotifyComm_InvalidEventType'{type=H});check_types(_,_,_) -> %% Wasn't even a correct input. corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).check_wildcard(Types, Which, WC, Domain, Type) -> NewWC = case {string:chr(Domain, $*), string:chr(Type, $*)} of {0, 0} -> WC; {0, _}-> [{type, Domain, convert_wildcard(Type, [])}|WC]; {_, 0}-> [{domain, convert_wildcard(Domain, []), Type}|WC]; _-> [{both, convert_wildcard(Domain, []), convert_wildcard(Type, [])}|WC] end, check_types(Types, Which, NewWC).%% Change '*' to '.*', see regexp:parse/2 documentation.convert_wildcard([], Acc) -> case regexp:parse(lists:reverse(Acc)) of {ok, Expr} -> Expr; _ -> corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) end;convert_wildcard([$*|T], Acc) -> convert_wildcard(T, [$*, $.|Acc]);convert_wildcard([H|T], Acc) -> convert_wildcard(T, [H|Acc]). %%------------------------------------------------------------%% function : match_types%% Arguments: A sequence of {Which, Domain, Type}, i.e., the same as%% returned from cosNotification_Filter:check_types/3%% Returns : bolean()%%------------------------------------------------------------match_types(_, _, []) -> false;match_types(Domain, Type, [{domain, WCDomain, Type}|T]) -> L=length(Domain), case catch regexp:matches(Domain, WCDomain) of {match, []} -> match_types(Domain, Type, T); {match, [{1, L}]} -> true; _-> match_types(Domain, Type, T) end;match_types(Domain, Type, [{type, Domain, WCType}|T]) -> L=length(Type), case catch regexp:matches(Type, WCType) of {match, []} -> match_types(Domain, Type, T); {match, [{1, L}]} -> true; _-> match_types(Domain, Type, T) end;match_types(Domain, Type, [{both, WCDomain, WCType}|T]) -> L1=length(Domain), case catch regexp:matches(Domain, WCDomain) of {match, []} -> match_types(Domain, Type, T); {match, [{1, L1}]} -> L2=length(Type), case catch regexp:matches(Type, WCType) of {match, []} -> match_types(Domain, Type, T); {match, [{1, L2}]} -> true; _-> match_types(Domain, Type, T) end; _-> match_types(Domain, Type, T) end;match_types(Domain, Type, [_|T]) -> match_types(Domain, Type, T).%%------------------------------------------------------------%% function : validate_types%% Arguments: A sequence of CosNotification::EventType{}, i.e., %% name-value pairs.%% Returns : ok |%% {'EXCEPTION', #'CosNotifyComm_InvalidEventType'{}}%%------------------------------------------------------------validate_types([]) -> ok;validate_types([#'CosNotification_EventType'{domain_name=Do,type_name=Ty}|T]) when list(Do), list(Ty) -> validate_types(T);validate_types([H|_]) when record(H, 'CosNotification_EventType') -> %% Not valid. corba:raise(#'CosNotifyComm_InvalidEventType'{type=H});validate_types(_) -> %% Wasn't even a correct input. corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).%%--------------- END OF MODULE ------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?