Open joshewilliams opened 5 years ago
Unfortunately, right now there's no good answer to this class of problems in KS.
"Counter", by definition, is imperative, i.e. it relies on a certain way to process (in this case, sequentially parse) the stream.
KS strives to be declarative, i.e. not rely on a particular implementation, but rather describe the essence of the data itself and relationships between data elements. Granted, current implementations that ksc generates is more or less sequential and eager, but it does not mean that other possible implementations would not be so straightforward. For example, we can't rely on the process being parsing (i.e. reading), as opposed to serialization (i.e. writing), and we can't rely on it being sequential and eager (i.e. not lazy).
Probably the best way to solve this class of problems in KS would be to introduce some collection operations that one can invoke in expression language. Given that you state that:
The Stay or Move field is repeated based on the number of times that the face_orientation in new_face_position_info is 0x01.
... we could do it like that:
- id: stay_or_move
type: u1
repeat: expr
repeat-expr: 'new_face_position_info.count { |x| x.face_orientation == 0x01 }'
where collection.count()
being a method which takes one lambda expression / anonymous function (that accepts one collection element and is expected to return boolean), runs it for every element of the collection (passing that element inside) and then counts the number of times it returned true.
Unfortunately, this is not implemented now :(
Thanks for the quick response! Looks like I might be out of luck with this particular format for now, or I can just ignore the rest of that data stream for the moment. Fortunately, that isn't the only file format I need to work with, so I'll just move on to the others for now.
Well, if all else fails, you can always implement that particular type imperatively in your language of choice, i.e. see opaque types.
Any update?
Thanks to @generalmimon on gitter.im & https://github.com/kaitai-io/kaitai_struct_formats/pull/265#discussion_r377966739 , here is a wip ksy file for git packfile index (.git/objects/pack/*idx) that counts : https://github.com/kaitai-io/kaitai_struct_formats/issues/323
here is a ksy file for git packfile index
Could you create a PR into KSF?
Will once packfile is done
I was wondering if there was a good way to create a counter. I'm not sure of a good way to describe this, so I'll just go with the example I'm trying to work on. I'm attempting to create a file format parser for the U3D File Format.
Specifically, I'm attempting to handle the Stay or Move field described in 9.6.1.3.4.7 (page 72) which is in the resolution_update type. The Stay or Move field is repeated based on the number of times that the face_orientation in new_face_position_info is 0x01.
Following is my template in its current state, omitting all but the relevant parts:
I can't think of a good way to do this. If there isn't one, can some sort of counter to Kaitai Struct?