3

私はかなり単純なバイナリ プロトコル用の Ragel マシンを作成しています。ここで提示するのは、解決しようとしている問題を示すためだけに、エラー回復を一切行わない、さらに単純化したバージョンです。

したがって、ここで解析されるメッセージは次のようになります。

<1 byte: length> <$length bytes: user data> <1 byte: checksum>

マシンは次のようになります。

%%{
   machine my_machine;
   write data;
   alphtype unsigned char;
}%%

%%{
   action message_reset {
      /* TODO */
      data_received = 0;
   }

   action got_len {
      len = fc;
   }

   action got_data_byte {
      /* TODO */
   }

   action message_received {
      /* TODO */
   }

   action is_waiting_for_data {
      (data_received++ < len);
   }

   action is_checksum_correct {
      1/*TODO*/
   }


   len = (any);
   fmt_separate_len = (0x80 any);
   data = (any);
   checksum = (any);

   message = 
      (
         # first byte: length of the data
         (len                                   @got_len)
         # user data
         (data       when is_waiting_for_data   @got_data_byte )*
         # place higher priority on the previous machine (i.e. data)
         <: 
         # last byte: checksum
         (checksum   when is_checksum_correct   @message_received)
      ) >to(message_reset)
      ;

   main := (msg_start: message)*;

   # Initialize and execute.
   write init;
   write exec;
}%%

ご覧のとおり、最初に長さを表す 1 バイトを受け取ります。次に、data必要な量のバイトを受信するまでバイトを受信し (チェックは によって行われますis_waiting_for_data)、次の (追加の) バイトを受信すると、それが正しいチェックサムであるかどうかをチェックします ( によってis_checksum_correct)。そうであれば、マシンは次のメッセージを待ちます。そうしないと、この特定のマシンが停止します (図を簡略化するために、ここでは意図的にエラー回復を含めていません)。

その図は次のようになります。

$ ragel -Vp ./msg.rl | dot -Tpng -o msg.png

クリックして画像を表示

ご覧のとおり、状態 1 では、ユーザー データを受信して​​いる間、条件は次のとおりです。

0..255(is_waiting_for_data, !is_checksum_correct),
0..255(is_waiting_for_data, is_checksum_correct)

そのため、すべてのデータ バイトで冗長に を呼び出しますis_checksum_correctが、結果はまったく問題になりません。

条件は次のように単純にする必要があります。0..255(is_waiting_for_data)

それを達成する方法は?

4

1 に答える 1

2

どのように機能is_checksum_correctするはずですか?あなたwhenが投稿した内容によると、チェックサムが読み取られる前に状態が発生します。私の提案は、内部のチェックサムをチェックして、message_receivedそこでエラーを処理することです。そうすれば、秒を取り除くことができwhen、問題はなくなります。

セマンティック条件は Ragel の比較的新しい機能のようです。非常に便利に見えますが、最適なコードが必要な場合は、まだ十分に成熟していない可能性があります。

于 2016-01-08T18:37:25.927 に答える