2011-12-30 35 views
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") 
     })) 

它为OkResponsePayloadErrorResponsePayload完全正常,但ResultResponsePayloadCodec不再具有访问权限字节用于前缀识别。

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

在这种情况下的问题是,我不会有关于包的总大小(nn),这有时在表达式中有用的信息。 此外,它看起来像其他结构的行为是这样的(第一个字节决定的类型),这将需要手写很多代码。

我希望有人能给我一个更清洁的解决方案。

回答

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

+0

这样我就不必存取权限fieldNotPrefix字节ResultsResponsePacketPayload,请仔细阅读第一伪代码。 – 2012-01-02 00:03:46

+0

我认为sakfa说你可以通过使ResultResponsePacketPayload和ResponsePacket的所有子类内部类访问fieldNotPrefix,然后如果你需要访问fieldNotPrefix属性,请从这些内部引用它'ResponsePacket.this.fieldNotPrefix'类。 – 2012-01-25 07:22:48

相关问题