lunixbochs / struc

Better binary packing for Go
MIT License
564 stars 42 forks source link

struc definition - struct arrays #89

Closed ayh20 closed 3 years ago

ayh20 commented 3 years ago

I've been using your great library for a while and have come across a scenario that feels like it should work but doesn't. I currently have this scenario in a struct and it work nicely:

type InputData {
NumZones     uint8  `struc:"uint8,little"`
ZoneData     []Zone `struc:"Zone,sizefrom=NumZones"`
}

Where Zone is:

type Zone struct {
    ZoneStart float32 `struc:"float32,little"`
    ZoneFlag  int8    `struc:"int8,little"` 
}

But i now need to be able to do this with a fixed number of zones where i don't have a field to use as a sizefrom

type InputData {
ZoneData     []Zone `struc:"[25]Zone"`
}

Logically the above sounds like the solution and some of your examples show the use of [] in the struc definition.

running the above example throws "struc: field Zone is a slice with no length or sizeof field." So the error seems to imply that I should be able to pass a fixed length. Looking at the code i can't see anywhere that the length it used.

Should it work this way ? can you specify a fixed size for my array ?

lunixbochs commented 3 years ago

I think this doesn't work because []Zone in the struct tag doesn't make any sense to the parser. At that level, struc doesn't know about the Zone type - the string type names it can parse from the tag are a fixed list.

https://github.com/lunixbochs/struc/blob/master/struc_test.go#L26

The ways to work around this are probably:

  1. A custom field type encapsulating multiple zones: https://github.com/lunixbochs/struc/blob/master/custom.go (see also the float16 example and the custom unit tests).
  2. An array type instead of a slice type ([4]Zone at the Go level instead of in the struct tag).
  3. Specify the type in the tag in bytes? e.g. [200]byte
ayh20 commented 3 years ago

Ryan, Thanks so much for the response. You are absolutely correct and I've got myself all mixed up (I blame coding in 4 different languages at the same time).

The solution (as it's fixed length) is simply:

type InputData {
ZoneData     [25]Zone `struc:"[25]Zone"`
}
lunixbochs commented 3 years ago

I don't think you need the struc tag on that