Search code examples
c++enumsc-strings

Converting enum type to a specific, predefined array of hex values in C++


What would be the most optimal and shortest way to write a function returning an array of 8-bit hex values, which are assigned based on an enumerated parameter.

I need to hard code commands, which will be sent over bluetooth and still have an easy access to them in code. So I have an enum with all possible commands listed in a human-readable way.

enum eventType {
    MODIFY_A,
    MODIFY_B,
    MODIFY_C,
    MODIFY_D
}

The communication protocol I try to adapt uses custom packets with predefined hex values. So for example, sending 0x00, 0x01, 0x02, 0x03 could change led colour of a receiving device.

The library used for ble communication accepts arrays of said hexes, or other words, just a plain C string.

It would be easiest to simply define an array in a switch() after declaring it, just like this:

uint8_t* getCommandOf(eventType event) {
    uint8_t command[4];
     
    switch(event) {
        case eventType::MODIFY_A:
            command = {0x01, 0x00, 0x00, 0x00}; break; 
        case eventType::MODIFY_B:
            command = {0x02, 0x00, 0x00, 0x00}; break; 
        case eventType::MODIFY_C:
            command = {0x03, 0x00, 0x00, 0x00}; break; 
        case eventType::MODIFY_D:
            command = {0x04, 0x00, 0x00, 0x00}; break; 
    }

    return command;
}

Then I could simply call: sendOverBLE(getCommandOf(eventType::MODIFY_A));

Unfortunately, we can't do that in C++. I'm open to suggestions. How would you solve it? I though of a few solutions, butI don't like any of them.

Maybe define them in a 2d array? Or a custom container class?


Solution

  • I would suggest using and returning a std::array. That would change your function to

    std::array<uint8_t, 4> getCommandOf(eventType event) {
        switch(event) {
            case eventType::MODIFY_A:
                return {0x01, 0x00, 0x00, 0x00};
            case eventType::MODIFY_B:
                return {0x02, 0x00, 0x00, 0x00};
            case eventType::MODIFY_C:
                return {0x03, 0x00, 0x00, 0x00};
            case eventType::MODIFY_D:
                return {0x04, 0x00, 0x00, 0x00}; 
        }
        // for bad input
        return {}; // for all zeros
        // or use an exception
        throw std::invalid_argument("some error message here");
    }
    

    If you need to pass this array to a function that takes a uint8_t*, then you can use array's data member to get such a pointer like

    my_uint8_t_ptr_func(getCommandOf(eventType::MODIFY_A).data());