2016-03-28 1 views
0

私はgen_fsmの2つのバージョンを書いて、バイトストリームを解析しました。私は文字列snpで始まり、pの後に次の20バイトを保存するパケットを探しています。このコードはヘッダーの検索にのみ関係します。私は、より慣用的なErlangまたはそれを書く良い方法について、いくつかのアドバイスが必要です。どちらがもっと慣用ですか?

オプション1

parse_header({parse, Byte}, {Header, [Next | Rest]}) -> 
    case Byte of 
    Next when length(Rest) > 0 -> {next_state, parse_header, {Header, Rest}}; 
    Next when length(Rest) == 0 -> {next_state, parse_data, []}; 
    $s  -> parse_header({parse, Byte}, {Header, Header}); 
    _   -> {next_state, parse_header, {Header, Header}} 
end. 

オプション2

parse_start({parse, Byte}, State) when Byte == $s -> 
    {next_state, parse_new, State}; 
parse_start({parse, Byte}, State) when Byte /= $s -> 
    {next_state, parse_start, State}. 

parse_new({parse, Byte}, State) when Byte == $n -> 
    {next_state, parse_packet, State}; 
parse_new({parse, Byte}, State) when Byte == $s -> 
    parse_start({parse, Byte}, State); 
parse_new({parse, _Byte}, State) -> 
    {next_state, parse_start, State}. 

parse_packet({parse, Byte}, State) when Byte == $p -> 
    {next_state, parse_data, State}; 
parse_packet({parse, Byte}, State) when Byte == $s -> 
    parse_start({parse, Byte}, State); 
parse_packet({parse, _Byte}, State) -> 
    {next_state, parse_start, State}. 

答えて

1

両方の実装が微細で、しかし、あなたがgen_fsmループへの旅行を最小限に実装を好むべきである、このよう徹底的データを解析パースするその他のものがなくなるまで、制御をgen_fsmに戻します。

したがって、最初の実装ではその点で優れています。また、実装が短ければ、通常は理由を考えるのが簡単になります。したがって、最初の解決策のポイントもあります。

しかし、2番目の実装は(間違いなく)明らかであり、gen_fsmのアプローチに適しているため、必要に応じて維持したり拡張したりする方が簡単でしょう。

おそらく、両方から最良の部品を取るソリューションを見つけることができますか?たとえば、どのようにこの1について:

parse_header([ $s, $n, $p | Rest]) -> copy_data(Rest, 20, []); 
parse_header([ _ | T ]) -> parse_header(T); 
parse_header(List) when length(List) < 3 -> {next_state, parse_header}. 

copy_data(_, 0, Acc) -> lists:reverse(Acc); 
copy_data([], X, Acc) -> {next_state, {copy_data, X, Acc}}; 
copy_data([H | T], X, Acc) -> copy_data(T, X - 1, [H | Acc]). 

それは徹底的入力を読み取ろうとすると、読み取り専用にこれ以上データがない場合、バックgen_fsmに制御を返します。 2番目のソリューションと同様に、ヘッダーの解析とデータの読み込みを分けています。

これはもちろん、残りのコードや正確な要件がわからないため、どのように問題に近づいているかの例だけです。

関連する問題