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它对and工作得很好ErrorResponsePayload,但ResultResponsePayload Codec不再访问用于前缀标识的第一个字节。

我的第一个想法是编写 custom Codec<ResponsePacket>,在 decode 里面我可以读取第一个字节,根据它的值我可以实例化新的编解码器来解析缓冲区的其余部分。

在这种情况下的问题是我不会有关于包(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 回答