From 796d5df1c0ea1fded71549f6874be075bd55c9b6 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 16 Feb 2017 11:17:57 +0800 Subject: [PATCH] Upgrade parse/2 function --- src/emqttd_topic.erl | 57 ++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/emqttd_topic.erl b/src/emqttd_topic.erl index 0afeacae8..458a41f7d 100644 --- a/src/emqttd_topic.erl +++ b/src/emqttd_topic.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2012-2017 Feng Lee . +%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -16,8 +16,12 @@ -module(emqttd_topic). +-author("Feng Lee "). + -include("emqttd_protocol.hrl"). +-include("emqttd_internal.hrl"). + -import(lists, [reverse/1]). -export([match/2, validate/1, triples/1, words/1, wildcard/1]). @@ -55,8 +59,8 @@ wildcard([_H|T]) -> %% @doc Match Topic name with filter -spec(match(Name, Filter) -> boolean() when - Name :: topic() | words(), - Filter :: topic() | words()). + Name :: topic() | words(), + Filter :: topic() | words()). match(Name, Filter) when is_binary(Name) and is_binary(Filter) -> match(words(Name), words(Filter)); match([], []) -> @@ -94,17 +98,14 @@ validate2([]) -> true; validate2(['#']) -> % end with '#' true; -validate2(['#'|Words]) when length(Words) > 0 -> - false; +validate2(['#'|Words]) when length(Words) > 0 -> + false; validate2([''|Words]) -> validate2(Words); validate2(['+'|Words]) -> validate2(Words); validate2([W|Words]) -> - case validate3(W) of - true -> validate2(Words); - false -> false - end. + case validate3(W) of true -> validate2(Words); false -> false end. validate3(<<>>) -> true; @@ -180,24 +181,28 @@ join(Words) -> parse(Topic) when is_binary(Topic) -> parse(Topic, []). -parse(Topic = <<"$local/", Topic1/binary>>, Options) -> - case lists:member(local, Options) of - true -> error({invalid_topic, Topic}); - false -> parse(Topic1, [local | Options]) - end; +parse(<<"$local/", Topic1/binary>>, Options) -> + if_not_contain(local, Options, fun() -> + parse(Topic1, [local | Options]) + end); -parse(Topic = <<"$queue/", Topic1/binary>>, Options) -> - case lists:keyfind(share, 1, Options) of - {share, _} -> error({invalid_topic, Topic}); - false -> parse(Topic1, [{share, '$queue'} | Options]) - end; +parse(<<"$queue/", Topic1/binary>>, Options) -> + if_not_contain(share, Options,fun() -> + parse(Topic1, [{share, '$queue'} | Options]) + end); -parse(Topic = <<"$share/", Topic1/binary>>, Options) -> - case lists:keyfind(share, 1, Options) of - {share, _} -> error({invalid_topic, Topic}); - false -> [Share, Topic2] = binary:split(Topic1, <<"/">>), - {Topic2, [{share, Share} | Options]} - end; +parse(<<"$share/", Topic1/binary>>, Options) -> + if_not_contain(share, Options, fun() -> + [Share, Topic2] = binary:split(Topic1, <<"/">>), + {Topic2, [{share, Share} | Options]} + end); -parse(Topic, Options) -> {Topic, Options}. +parse(Topic, Options) -> + {Topic, Options}. + +if_not_contain(local, Options, Fun) -> + ?IF(lists:member(local, Options), error(invalid_topic), Fun()); + +if_not_contain(share, Options, Fun) -> + ?IF(lists:keyfind(share, 1, Options), error(invalid_topic), Fun()).