📄 megaco_text_parser_v1.hrl
字号:
{topology, Desc} -> TopReq2 = Desc ++ TopReq, %% OTP-4088 do_merge_action_requests(ContextId, CtxReq, CtxAuditReq, CmdReq, TopReq2, T); priorityAudit when CtxAuditReq#'ContextAttrAuditRequest'.priority == asn1_NOVALUE -> CtxAuditReq2 = CtxAuditReq#'ContextAttrAuditRequest'{priority = 'NULL'}, do_merge_action_requests(ContextId, CtxReq, CtxAuditReq2, CmdReq, TopReq, T); emergencyAudit when CtxAuditReq#'ContextAttrAuditRequest'.emergency == asn1_NOVALUE -> CtxAuditReq2 = CtxAuditReq#'ContextAttrAuditRequest'{emergency = 'NULL'}, do_merge_action_requests(ContextId, CtxReq, CtxAuditReq2, CmdReq, TopReq, T); topologyAudit when CtxAuditReq#'ContextAttrAuditRequest'.topology == asn1_NOVALUE -> CtxAuditReq2 = CtxAuditReq#'ContextAttrAuditRequest'{topology = 'NULL'}, do_merge_action_requests(ContextId, CtxReq, CtxAuditReq2, CmdReq, TopReq, T) end;do_merge_action_requests(ContextId, CtxReq, CtxAuditReq, CmdReq, TopReq, []) -> #'ActionRequest'{contextId = ContextId, contextRequest = strip_contextRequest(CtxReq, TopReq), contextAttrAuditReq = strip_contextAttrAuditRequest(CtxAuditReq), commandRequests = lists:reverse(CmdReq)}.%% OTP-5085: %% In order to solve a problem in the parser, the error descriptor%% has been put last in the non-empty commandReplyList, if it is not %% asn1_NOVALUEmerge_action_reply(ReplyList) -> CtxReq = #'ContextRequest'{}, TopReq = [], CmdList = [], case lists:reverse(ReplyList) of [ED|RL2] when record(ED, 'ErrorDescriptor') -> AR = do_merge_action_reply(lists:reverse(RL2), CtxReq, TopReq, CmdList), AR#'ActionReply'{errorDescriptor = ED}; _ -> do_merge_action_reply(ReplyList, CtxReq, TopReq, CmdList) end.do_merge_action_reply([H | T], CtxReq, TopReq, CmdList) -> case H of {command, Cmd} -> do_merge_action_reply(T, CtxReq, TopReq, [Cmd | CmdList]); {context, Ctx} -> case Ctx of {priority, Int} when CtxReq#'ContextRequest'.priority == asn1_NOVALUE -> CtxReq2 = CtxReq#'ContextRequest'{priority = Int}, do_merge_action_reply(T, CtxReq2, TopReq, CmdList); {emergency, Bool} when CtxReq#'ContextRequest'.emergency == asn1_NOVALUE -> CtxReq2 = CtxReq#'ContextRequest'{emergency = Bool}, do_merge_action_reply(T, CtxReq2, TopReq, CmdList); {topology, Desc} -> TopReq2 = Desc ++ TopReq, %% OTP-4088 do_merge_action_reply(T, CtxReq, TopReq2, CmdList) end end;do_merge_action_reply([], CtxReq, TopReq, CmdList) -> #'ActionReply'{contextReply = strip_contextRequest(CtxReq, TopReq), commandReply = lists:reverse(CmdList)}.strip_contextRequest(R, TopReq) when R#'ContextRequest'.priority == asn1_NOVALUE, R#'ContextRequest'.emergency == asn1_NOVALUE, TopReq == [] -> asn1_NOVALUE;strip_contextRequest(R, []) -> R#'ContextRequest'{topologyReq = asn1_NOVALUE};strip_contextRequest(R, TopReq) -> R#'ContextRequest'{topologyReq = TopReq}. %% OTP-4088strip_contextAttrAuditRequest(R) when R#'ContextAttrAuditRequest'.priority == asn1_NOVALUE, R#'ContextAttrAuditRequest'.emergency == asn1_NOVALUE, R#'ContextAttrAuditRequest'.topology == asn1_NOVALUE -> asn1_NOVALUE;strip_contextAttrAuditRequest(R) -> R.make_commandRequest({CmdTag, {_TokenTag, _Line, Text}}, Cmd) -> Req = #'CommandRequest'{command = {CmdTag, Cmd}}, case Text of [$w, $- | _] -> Req#'CommandRequest'{wildcardReturn = 'NULL'}; [$o, $-, $w, $- | _] -> Req#'CommandRequest'{optional = 'NULL', wildcardReturn = 'NULL'}; [$o, $- | _] -> Req#'CommandRequest'{optional = 'NULL'}; _ -> Req end.merge_terminationAudit(AuditReturnParameters) -> lists:reverse(do_merge_terminationAudit(AuditReturnParameters, [], [])).do_merge_terminationAudit([H| T], ARPs, AuditItems) -> case H of {auditReturnItem, AuditItem} -> do_merge_terminationAudit(T, ARPs, [AuditItem | AuditItems]); AuditReturnParameter -> do_merge_terminationAudit(T, [AuditReturnParameter | ARPs], AuditItems) end;do_merge_terminationAudit([], AuditReturnParameters, []) -> AuditReturnParameters;do_merge_terminationAudit([], AuditReturnParameters, AuditItems) -> AuditDescriptor = #'AuditDescriptor'{auditToken = AuditItems}, AuditReturnParameter = {emptyDescriptors, AuditDescriptor}, [AuditReturnParameter | AuditReturnParameters]. merge_mediaDescriptor(MediaParms) -> do_merge_mediaDescriptor(MediaParms, asn1_NOVALUE, [], []).do_merge_mediaDescriptor([H | T], TS, One, Multi) -> case H of {streamParm, Parm} when Multi == [] -> do_merge_mediaDescriptor(T, TS, [Parm | One], Multi); {streamDescriptor, Desc} when One == [] -> do_merge_mediaDescriptor(T, TS, One, [Desc | Multi]); {termState, TS2} when TS == asn1_NOVALUE -> do_merge_mediaDescriptor(T, TS2, One, Multi); _ -> return_error(0, {bad_merge_mediaDescriptor, [H, TS, One, Multi]}) end;do_merge_mediaDescriptor([], TS, One, Multi) -> if One == [], Multi == [] -> #'MediaDescriptor'{streams = asn1_NOVALUE, termStateDescr = TS}; One /= [], Multi == [] -> #'MediaDescriptor'{streams = {oneStream, merge_streamParms(One)}, termStateDescr = TS}; One == [], Multi /= [] -> #'MediaDescriptor'{streams = {multiStream, lists:reverse(Multi)}, termStateDescr = TS} end. merge_streamParms(TaggedStreamParms) -> SP = #'StreamParms'{}, do_merge_streamParms(TaggedStreamParms, SP).do_merge_streamParms([{Tag, D} | T] = All, SP) -> case Tag of local when SP#'StreamParms'.localDescriptor == asn1_NOVALUE -> do_merge_streamParms(T, SP#'StreamParms'{localDescriptor = D}); remote when SP#'StreamParms'.remoteDescriptor == asn1_NOVALUE -> do_merge_streamParms(T, SP#'StreamParms'{remoteDescriptor = D}); control -> LCD = case SP#'StreamParms'.localControlDescriptor of asn1_NOVALUE -> #'LocalControlDescriptor'{propertyParms = []}; PrevLCD -> PrevLCD end, LCD2 = do_merge_control_streamParms(D, LCD), do_merge_streamParms(T, SP#'StreamParms'{localControlDescriptor = LCD2}); _ -> return_error(0, {do_merge_streamParms, [All, SP]}) end;do_merge_streamParms([], SP) when record(SP#'StreamParms'.localControlDescriptor, 'LocalControlDescriptor') -> LCD = SP#'StreamParms'.localControlDescriptor, PP = LCD#'LocalControlDescriptor'.propertyParms, LCD2 = LCD#'LocalControlDescriptor'{propertyParms = lists:reverse(PP)}, SP#'StreamParms'{localControlDescriptor = LCD2};do_merge_streamParms([], SP) -> SP.do_merge_control_streamParms([{SubTag, SD} | T] = All, LCD) -> case SubTag of group when LCD#'LocalControlDescriptor'.reserveGroup == asn1_NOVALUE -> LCD2 = LCD#'LocalControlDescriptor'{reserveGroup = SD}, do_merge_control_streamParms(T, LCD2); value when LCD#'LocalControlDescriptor'.reserveValue == asn1_NOVALUE -> LCD2 = LCD#'LocalControlDescriptor'{reserveValue = SD}, do_merge_control_streamParms(T, LCD2); mode when LCD#'LocalControlDescriptor'.streamMode == asn1_NOVALUE -> LCD2 = LCD#'LocalControlDescriptor'{streamMode = SD}, do_merge_control_streamParms(T, LCD2); prop -> PP = LCD#'LocalControlDescriptor'.propertyParms, LCD2 = LCD#'LocalControlDescriptor'{propertyParms = [SD | PP]}, do_merge_control_streamParms(T, LCD2); _ -> return_error(0, {do_merge_control_streamParms, [All, LCD]}) end;do_merge_control_streamParms([], LCD) -> LCD.merge_terminationStateDescriptor(Parms) -> TSD = #'TerminationStateDescriptor'{propertyParms = []}, do_merge_terminationStateDescriptor(Parms, TSD).do_merge_terminationStateDescriptor([{Tag, Val} | T], TSD) -> case Tag of serviceState when TSD#'TerminationStateDescriptor'.serviceState == asn1_NOVALUE -> TSD2 = TSD#'TerminationStateDescriptor'{serviceState = Val}, do_merge_terminationStateDescriptor(T, TSD2); eventBufferControl when TSD#'TerminationStateDescriptor'.eventBufferControl == asn1_NOVALUE-> TSD2 = TSD#'TerminationStateDescriptor'{eventBufferControl = Val}, do_merge_terminationStateDescriptor(T, TSD2); propertyParm -> PP = TSD#'TerminationStateDescriptor'.propertyParms, TSD2 = TSD#'TerminationStateDescriptor'{propertyParms = [Val | PP]}, do_merge_terminationStateDescriptor(T, TSD2) end;do_merge_terminationStateDescriptor([], TSD) -> PP = TSD#'TerminationStateDescriptor'.propertyParms, TSD#'TerminationStateDescriptor'{propertyParms = lists:reverse(PP)}.ensure_prop_groups({_TokenTag, _Line, Text}) -> Group = [], Groups = [], parse_prop_name(Text, Group, Groups).parse_prop_name([Char | Rest] = All, Group, Groups) -> case ?classify_char(Char) of white_space -> parse_prop_name(Rest, Group, Groups); end_of_line -> parse_prop_name(Rest, Group, Groups); _ -> Name = [], do_parse_prop_name(All, Name, Group, Groups) end;parse_prop_name([] = All, Group, Groups) -> Name = [], do_parse_prop_name(All, Name, Group, Groups).do_parse_prop_name([Char | Rest], Name, Group, Groups) -> case ?classify_char(Char) of safe_char_upper -> do_parse_prop_name(Rest, [Char | Name], Group, Groups); safe_char -> do_parse_prop_name(Rest, [Char | Name], Group, Groups); rest_char when Char == $=, Name /= [] -> %% Now we have a complete name if Name == "v", Group /= [] -> %% v= is a property group delimiter, %% lets create yet another property group. Groups2 = [lists:reverse(Group) | Groups], Group2 = [], parse_prop_value(Rest, Name, Group2, Groups2); true -> %% Use current property group parse_prop_value(Rest, Name, Group, Groups) end; _ -> return_error(0, {bad_prop_name, lists:reverse(Name), Char}) end;do_parse_prop_name([], [], [], Groups) -> lists:reverse(Groups);do_parse_prop_name([], [], Group, Groups) -> Group2 = lists:reverse(Group), lists:reverse([Group2 | Groups]);do_parse_prop_name([], Name, Group, Groups) when Name /= [] -> %% Assume end of line Value = [], PP = make_prop_parm(Name, Value), Group2 = lists:reverse([PP | Group]), lists:reverse([Group2 | Groups]). parse_prop_value(Chars, Name, Group, Groups) -> Value = [], do_parse_prop_value(Chars, Name, Value, Group, Groups).do_parse_prop_value([Char | Rest], Name, Value, Group, Groups) -> case ?classify_char(Char) of end_of_line -> %% Now we have a complete "name=value" pair PP = make_prop_parm(Name, Value), parse_prop_name(Rest, [PP | Group], Groups); _ -> do_parse_prop_value(Rest, Name, [Char | Value], Group, Groups) end;do_parse_prop_value([], Name, Value, Group, Groups) -> %% Assume end of line PP = make_prop_parm(Name, Value), Group2 = lists:reverse([PP | Group]), lists:reverse([Group2 | Groups]).make_prop_parm(Name, Value) -> #'PropertyParm'{name = lists:reverse(Name), value = [lists:reverse(Value)]}.ensure_uint({_TokenTag, Line, Val}, Min, Max) when integer(Val) -> if integer(Min), Val >= Min -> if integer(Max), Val =< Max -> Val; Max == infinity -> Val; true -> return_error(Line, {too_large_integer, Val, Max}) end; true -> return_error(Line, {too_small_integer, Val, Min}) end;ensure_uint({TokenTag, Line, Text}, Min, Max) -> case catch list_to_integer(Text) of {'EXIT', _} -> return_error(Line, {not_an_integer, Text}); Val when integer(Val) -> ensure_uint({TokenTag, Line, Val}, Min, Max) end;ensure_uint(Val, Min, Max) -> ensure_uint({uint, 0, Val}, Min, Max).ensure_uint16(Int) -> ensure_uint(Int, 0, 65535).ensure_uint32(Int) -> ensure_uint(Int, 0, 4294967295) .%% OTP-4710ensure_hex({_TokenTag, _Line, [$0, $x |Chars]}, Min, Max) -> ensure_uint(length(Chars), Min, Max), hex_to_int(Chars, []);ensure_hex({_TokenTag, _Line, [$0, $X |Chars]}, Min, Max) -> ensure_uint(length(Chars), Min, Max), hex_to_int(Chars, []);ensure_hex([$0, $x |Chars], Min, Max) -> ensure_uint(length(Chars), Min, Max), hex_to_int(Chars, []);ensure_hex([$0, $X |Chars], Min, Max) -> ensure_uint(length(Chars), Min, Max), hex_to_int(Chars, []).%% OTP-4710hex_to_int([], Acc) -> lists:reverse(Acc);hex_to_int([Char1,Char2|Tail], Acc) -> Int1 = hchar_to_int(Char1), Int2 = hchar_to_int(Char2), Val = Int2 bor (Int1 bsl 4), hex_to_int(Tail, [Val| Acc]);hex_to_int([Char], Acc) -> Int = hchar_to_int(Char), lists:reverse([Int|Acc]).hchar_to_int(Char) when $0 =< Char, Char =< $9 -> Char - $0;hchar_to_int(Char) when $A =< Char, Char =< $F -> Char - $A + 10; % OTP-4710hchar_to_int(Char) when $a =< Char, Char =< $f -> Char - $a + 10. % OTP-4710value_of({_TokenTag, _Line, Text}) -> Text.% d(F) ->% d(F,[]).% d(F, A) ->% io:format("~p:" ++ F ++ "~n", [?MODULE | A]).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -