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

string content as parameter #968

Closed
schiebel opened this issue Jun 7, 2022 · 2 comments
Closed

string content as parameter #968

schiebel opened this issue Jun 7, 2022 · 2 comments
Labels

Comments

@schiebel
Copy link

schiebel commented Jun 7, 2022

Hello, this could be user error... I am trying to follow the documentation, but I cannot get parameters to work for string content. I have a lot of data blocks like:

      - id: name_len
        type: u4
      - id: name
        contents: ["TableRecord"]

so I would like to be able to use parameters like:

label:
    params:
      - id: value
         type: str
    seq:
      - id: name_len
         type: u4
      - id: name
         contents: value

I tried label( ["TableRecord"] ), label( "TableRecord" ) and label( [0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64] ), I put the square brackets in the parameterized struct, I tried removing the type from value but nothing seems to work.

Is it possible to parameterize string content? Thanks in advance for any help...

@generalmimon
Copy link
Member

@schiebel The contents key does not support expressions. The string value is always treated literally, so if you write

      - id: magic
        contents: value

it literally expects the following bytes:

Offset(h) 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

00000000  76 61 6c 75 65                                   value

Since the .ksy language is based on YAML, quoting has no effect (it will be processed by the YAML parser and KSC only receives the 5-character string "value" again):

      - id: magic
        contents: 'value'

If you want to use expressions, you have to use the valid key (sorry, this feature still doesn't have any proper documentation even though it was introduced in 0.9, the issue ref is the best I can give you) - see description in #435 (comment).

As suggested in https://doc.kaitai.io/user_guide.html#param-types, you can declare:

  1. a byte array parameter:

    label:
      params:
        - id: value
          type: bytes
      seq:
        - id: name_len
          type: u4
        - id: name
          size: value.length
          valid:
            eq: value

    Note: valid/eq also has a shorthand notation:

            - id: name
              size: value.length
    -         valid:
    -           eq: value
    +         valid: value

    Note that with this approach, you must really pass a byte array in it. For the ASCII bytes "Rec", that would be

      seq:
        - id: foo
          type: label([0x52, 0x65, 0x63])

    You cannot pass a string literal - that won't work because strings and byte arrays are incompatible. This is wrong (the parameter expects a byte array):

    -  seq:
    -    - id: foo
    -      type: label("Rec")

    The reason why you can give either a byte array or a UTF-8 string literal to contents (or some mix of bytes and strings, which will be concatenated) is that contents is a very special key that encodes the strings in UTF-8 to bytes (for convenience). This behavior has nothing to do with the expression language.

  2. a string parameter - you have to specify an encoding when parsing. The following relies on a single-byte encoding such as ASCII (for a multi-byte encoding, it won't work in general):

    label:
      params:
        - id: value
          type: str
      seq:
        - id: name_len
          type: u4
        - id: name
          size: value.length # `str.length` gives the number of *characters*, not bytes as we would need here; but in ASCII they're equal
          type: str
          encoding: ASCII
          valid:
            eq: value

    Now you can pass a string:

      seq:
        - id: foo
          type: label("Rec")

@schiebel
Copy link
Author

schiebel commented Jun 8, 2022

Thanks very much for explaining the issues @generalmimon

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