バイト配列を渡す関数があります。これらのバイトには、xml メッセージの一部、全体、または全体と一部が含まれる場合があります。ステート マシンを使用してメッセージを解析することに成功しましたが、今日まで、2 番目のソースがデータを送信している場合、メッセージの前半と 2 番目のソースからの別のメッセージの開始直後を取得できることに気付きました。 . 順番が間違っていたメッセージを破棄することで、それを修正できるようにしたいと思います。私はそれを保管し、完成するまで保持しておくべきではないと思います。
これが私のステートマシンです:
for (int i = 0; i < bytes.length; i++)
{
byte data = bytes[i];
//based on the read state, perform an action. This is attempting to
//determine if we are reading the beginning of a message, or the end of the message.
if (bufferIndex == BmsConstants.MAX_DRAWING_LENGTH)
{
resetState();
}
switch (readState)
{
case SYNC:
//we've read: <
if (data == '<')
{
readState = DrawingDeviceParserState.START_LT;
buff[bufferIndex++] = (char) data;
} else
{
resetState();
}
break;
case START_LT:
//we've read: <?
if (data == '?')
{
readState = DrawingDeviceParserState.START_QM;
buff[bufferIndex++] = (char) data;
} else
{
resetState();
}
break;
case START_QM:
//we've read: <?x
if (data == 'x')
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
} else
{
resetState();
}
break;
case START_X:
//we've read: <, now just read until we get to the </event>
if (data == '<')
{
readState = DrawingDeviceParserState.END_LT;
buff[bufferIndex++] = (char) data;
}
else
{
buff[bufferIndex++] = (char) data;
}
break;
case END_LT:
//we've read: </
if (data == '/')
{
readState = DrawingDeviceParserState.END_SLASH;
buff[bufferIndex++] = (char) data;
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
case END_SLASH:
//we've read: </e
if (data == 'e')
{
readState = DrawingDeviceParserState.END_E;
buff[bufferIndex++] = (char) data;
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
case END_E:
//we've read: </ev
if (data == 'v')
{
readState = DrawingDeviceParserState.END_V;
buff[bufferIndex++] = (char) data;
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
case END_V:
//we've read: </eve
if (data == 'e')
{
readState = DrawingDeviceParserState.END_E1;
buff[bufferIndex++] = (char) data;
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
case END_E1:
//we've read: </even
if (data == 'n')
{
readState = DrawingDeviceParserState.END_N;
buff[bufferIndex++] = (char) data;
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
case END_N:
//we've read: </event
if (data == 't')
{
readState = DrawingDeviceParserState.END_T;
buff[bufferIndex++] = (char) data;
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
case END_T:
//we've read: </event>
//End of the message, now we can parse it.
if (data == '>')
{
//readState = DrawingDeviceParserState.END_GT;
buff[bufferIndex++] = (char) data;
parseXml(new String(buff, 0, bufferIndex));
resetState();
}
else
{
readState = DrawingDeviceParserState.START_X;
buff[bufferIndex++] = (char) data;
}
break;
}
}
弱点は、このステート マシンが START_X のケース内にあることです。タグが見つかるまで読み続けます。2 つのメッセージが順不同で詰め込まれている場合、タグは 2 番目のメッセージの最後になります。誰かができることを望んでいるのは、ステートマシンは私がやろうとしていることではないことを私にアドバイスするか、このフリンジケースをより適切に処理するためにコード/ロジックを変更することです.