Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to point to a separate data spot in a sequence Kaitai? #1036

Closed
portconnect opened this issue Jun 12, 2023 · 2 comments
Closed

How to point to a separate data spot in a sequence Kaitai? #1036

portconnect opened this issue Jun 12, 2023 · 2 comments
Labels

Comments

@portconnect
Copy link

portconnect commented Jun 12, 2023

I want to build a feature in the .ksy file to reference data from a later data set to satisfy an earlier condition. In the example I included below, it will produce a value of null for the x and y fields. The reason is that the condition value is null since the z field comes after the x and y fields. Is there a method that would allow me to bypass this issue?

seq:
 - id: x
   type: b2
   if: z == false
 - id: y1
   type: b1
   if:  z == true
 - id: y1
   type: b1
   if:  z == true
 - id: z
   type: b1
   enum: z_kind
enum:
  z_kind:
  0: false
  1: true
@generalmimon
Copy link
Member

generalmimon commented Jun 18, 2023

@portconnect:

The reason is that the condition value is null since the z field comes after the x and y fields.

Yes. Probably in the future the compiler will be able to catch this erroneous situation and provide an error (#469), but we're not there yet.

Is there a method that would allow me to bypass this issue?

That's what instances are for. In the example you provided, it's a bit complicated by the fact that the z field that you want to use in the condition is a bit-sized integer type (https://doc.kaitai.io/user_guide.html#_bit_sized_integers), which is effectively not supported in instances yet (the problem is that there is no support for bit seeking, so the parsing of the bit type when the instance is invoked would permanently change the bit position of the stream and the seq parsing would be affected by that - #564 is related).

But you can for example read the whole byte and extract the bit you want:

seq:
 - id: x
   type: b2
   if: z == z_kind::false
 - id: y1
   type: b1
   if: z == z_kind::true
 - id: y2
   type: b1
   if: z == z_kind::true
 - id: z_old
   type: b1
instances:
  byte0:
    pos: 0
    type: u1
  z:
    value: (byte0 & 0b0010_0000) >> 5
    enum: z_kind
enum:
  z_kind:
    0: false
    1: true

Alternatively, you can always read the 2 bits the same way, and then use value instances to analyze it further (and note that in your case there's actually no need for the z_kind enum, because the 1-bit type: b1 type in Kaitai Struct is automatically translated to a boolean, see User Guide: "Booleans (...) also can be derived by using type: b1. This method parses a single bit from a stream and represents it as a boolean value: 0 becomes false, 1 becomes true."):

seq:
 - id: x_or_y
   type: b2
 - id: z
   type: b1
instances:
  x:
    value: x_or_y
    if: not z
  y1:
    value: x_or_y & 0b10
    if: z
  y2:
    value: x_or_y & 0b01
    if: z

@generalmimon
Copy link
Member

No response after my answer - I consider this resolved, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants