Accessing index of an uint8 array inside record

What is the correct way of accessing the index of an array of uint8 inside a record?

In protocol.pac, I have:

type Record_A = record {
record_b : Record_B;
} &byteorder=littleendian;

type Record_B = record {
data: uint8[4];
} &byteorder=littleendian;

In analyzer.pac, I tried using ${Record_A.record_b.data[0]}, but the log becomes empty. However, if I change data from uint8[4] to uint32 and used ${Record_A.record_b.data}, then the log gets generated correctly. I also tried: test->Assign(i, new Val((*Record_A.record_b.data)[0], TYPE_COUNT)); but no luck. I’m probably missing something silly here, but can’t seem to figure it out. Welcome all pointers!

Thanks,

How about this:

${Record_A.record_b.data}[0]

I didn't explicitly try it out, but just assuming that the syntax is
only sophisticated enough to recognize fields, not arrays, so
${Record_A.record_b.data} transforms from uint8[] (binpac) to a uint8*
(c++) and then you index into that.

- Jon

Hey Jon,

I tried that, but the log is empty for some reason, with only the headers being populated. Dpd.log wasn’t generated, so I couldn’t figure out error. I ended up using bytestring &length=4, and this allows me to access using ${Record_A.record_b.data[0]}. Bizarre as these two are equivalent, right?

Thanks,

Logically, "bytestring &length=4" and uint8[4] are equivalent but seem
to be implemented differently.

A bytestring field ends up being a "datastring<uint8>"
object/reference from binpac_bytestring.h

A uint8[4] ends up being a pointer to a "std::vector<uint8>".

So that last bit about it being a pointer is likely important, means
you were probably missing a pointer dereference e.g. you could try
${Record_A.record_b.data}->at(0) for accessing a uint8[] at index 0.

All this info should be available for you to find in the generated
*_pac.cc files and checking those is the best way to confirm what you
need to be doing.

- Jon

Ah, ok. Thanks for this tip!