>>947の疑似コードだけど、既にメッセージ全体が受信バッファに読み込まれていること、
あるいは、メッセージが未完成の場合にはget操作内でプロセス(or スレッド)がブロックされる、
言い換えると同期I/Oを前提にしている、という前提がある。
だから、そもそもの質問
>>931(未完成時の再開方法)に対するレスとしては不適切だった。
質問の意図に沿って「非同期I/Oを前提(だよね?)」とした場合、最も外側のTLV構造の処理は、
ステートマシン(状態管理処理)と一体になる。疑似コードだと、こんな感じ。
(続く)
(
>>950の続き)
RecvAcceptorState state = STATE_WAIT_TYPE; // 初期状態はType待ち
void recv_acceptor() // recvイベント発生に呼ばれるコールバック関数
{
while (buf.size() > 0) {
byte = buf.pop(1)
switch (state) {
case STATE_WAIT_TYPE: // Type待ち状態
tlv.type = byte; // Type値が決定
state = STATE_WAIT_LEGTH; // 次の状態(Length待ち)へ遷移
break;
case STATE_WAIT_LENGTH: // Length待ち状態
tlv.length = byte; // Length値が決定(Lengthフィールドが1byte固定である事を仮定)
value_counter = tlv.length; // 受信カウンタをLength値で初期化
state = STATE_PROCESS_VALUE; // 次の状態(Value処理中)へ遷移
break;
case STATE_PROCESS_VALUE: // Value処理中状態
:
if (メッセージ組立て完了) {
: // 受信メッセージ処理のアクションを起動する
: // もし階層的なTLV構造であれば、
>>947のメッセージ解析処理を呼ぶ
state = STATE_WAIT_TYPE; // 初期状態へ遷移(必要であれば他の再初期化処理も)
}
:
break;
}
}
}
(更に続く)
(
>>951の続き、これで終わり)
>>931の場合、Lengthとして4byte固定を想定しているみたいだから、
上記の疑似コードに対して、Length待ち状態をSTATE_WAIT_LENGTH1..._LENGTH4に分割するか、
あるいはLength受信カウンタを追加する、といった改造を加える必要があるから、注意してね。
他にも、pop値は1byte固定になってるけど、Value処理中状態ではNbyteに高速化すべきだろうし。