NordicSemiconductor / zcbor

Low footprint C/C++ CBOR library and Python tool providing code generation from CDDL descriptions.
Apache License 2.0
114 stars 34 forks source link

Two union byte strings generate in a goofy way #382

Closed jnz86 closed 5 months ago

jnz86 commented 8 months ago

Given the choice of two byte string options. A zero length, or a 16 byte length...

map = {
    check   : ("c" => bstr .size 16 / bstr .size 0),
}

Ideally this would have allowed me to generate something like check.len which I could simply check for zero or 16 to know if I could use the pointer at all and then up to 16B length.

Instead, I have issues with the generated:

struct map {
    union {
        struct zcbor_string bstr128;
        struct zcbor_string bstr;
    };
    enum {
        map_check_bstr128_c,
        map_check_bstr_c,
    } check_choice;
};

1. Is that both of these generate into zcbor_string types. Seems odd. I get it, if it was a byte string an a uint32_t. That would make sense. This however is a union of two of the same type and that type is a fat pointer of a byte string.

2. Not sure if that 128 is bits. But either way, it's very strange. One is bstr and the other bstr128... Even if it was bits, I would expect one to be bstr0

3. I can still use this the way I'd like. Because both variables are length + pointer, I can access either and have the same data. I can still check `bstrxxx.len. It works either way, which makes me suspect it isn't a desired scenario.

I suspect there more options here. I don't want to use an optional, the "c" needs to be there. But a nil value does create a more accurate "check choice then use" scenario.