3

preon を使用して mysql の結果パケットを解析しようとしています。パケットは次のようになります。

nn xx yy yy yy zz zz zz

私はこのようにそれを解析します

class ResponsePacket {
  @BoundNumber(size="1")
  byte sizeOfThePacket;
  /* 
  if(xx==00)
    packet = OkResponsePayload(yy yy zz zz zz)
  elseif(xx==ff)
    packet = ErrorResponsePayload(yy yy zz zz zz)
  else
    packet = ResultResponsePayload(xx yy yy zz zz zz)
  */

  PacketPayload packet;

}

私は@BoundObjectこのような注釈を使用してみました:

    @BoundObject( selectFrom = @Choices(prefixSize = 8, 
        defaultType=ResultsResponsePacketPayload.class, 
        alternatives={
            @Choice(type=OkResponsePacketPayload.class, condition="prefix==0"),
            @Choice(type=ErrorResponsePacketPayload.class, condition="prefix==255")
        }))

OkResponsePayloadおよびに対しては完全に正常に動作しますErrorResponsePayloadResultResponsePayload Codec、プレフィックスの識別に使用される最初のバイトにアクセスできなくなりました。

私の最初のアイデアは custom を書くことでしたCodec<ResponsePacket>。デコード内で最初のバイトを読み取ることができ、その値に応じて新しいコーデックをインスタンス化して残りのバッファを解析することができました。

このような場合の問題は、式で役立つ場合がある packet( nn) の合計サイズに関する情報が得られないことです。また、このように動作する他の構造があるようです (最初のバイトがタイプを決定します)。これには、手作業で多くのコードを記述する必要があります。

誰かが私にもっときれいな解決策を教えてくれることを願っています。

4

1 に答える 1

2

次に、プレフィックスを使用しないでください。リゾルバーコンテキスト全体が利用可能な状態にあります。

@BoundNumber(size = "8")
public int fieldNotPrefix;

@BoundObject( selectFrom = @Choices(
    defaultType=ResultsResponsePacketPayload.class, 
    alternatives={
        @Choice(type=OkResponsePacketPayload.class, condition="fieldNotPrefix==0"),
        @Choice(type=ErrorResponsePacketPayload.class, condition="fieldNotPrefix==255")
    }))

このようにして、リンボ式で fieldNotPrefix を outer.fieldNotPrefix として参照できるようになります。

于 2012-01-01T20:42:21.480 に答える