How to parse different packet types depending on first byte

465 Views Asked by At

I'm trying to parse mysql result packets using preon. Packet looks like this:

nn xx yy yy yy zz zz zz

I parse it like this

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;

}

I tried using @BoundObject annotation like this:

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

It works perfectly fine for OkResponsePayload and ErrorResponsePayload, but ResultResponsePayload Codec doesn't have acces anymore to first byte used for prefix identification.

My first idea was to write custom Codec<ResponsePacket>, and inside decode i could read first byte and depending on it's value i could instantiate new codecs to parse rest of the buffer.

The problem in such case is that i wont have information on the total size of the packet(nn) which is sometimes usefull in expressions. Also it looks like there are other structures whiche behave like this(first byte decides of the type), wo this would require a lot of code writen by hand.

I hope someone could show me a cleaner solution.

1

There are 1 best solutions below

2
On

Then don't use prefix, you have entire resolver context in condition available.

@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")
    }))

This way you will be able to reference fieldNotPrefix in limbo expressions as outer.fieldNotPrefix