HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Writing data of a certain integer type to a buffer

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
writingtypecertaindataintegerbuffer

Problem

I have function which writes data of a specified type to a buffer. Here is the part of this which writes Uint8, Uint16, Uint32 and Uint64, in big and little endian. As you can see that the same code is repeated several times, so I want to make this code more elegant.

```
...
case BW_DATA_TYPE_UINT8:
{
Uint8_T val = (static_cast(Uint8_T, src));
Uint8ToLittleEndianAr( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] );
bw->curPos += length;
break;
}

case BW_DATA_TYPE_UINT16_LE:
{
Uint16_T val = (static_cast(Uint16_T, src));
Uint16ToLittleEndianAr( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] + 1 );
bw->curPos += length;
break;
}

case BW_DATA_TYPE_UINT32_LE:
{
Uint32_T val = (static_cast(Uint32_T, src));
Uint32ToLittleEndianAr( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] + 3 );
bw->curPos += length;
break;
}

case BW_DATA_TYPE_UINT64_LE:
{
Uint64_T val = (static_cast(Uint64_T, src));
Uint64ToLittleEndianAr( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] + 7 );
bw->curPos += length;
break;
}

case BW_DATA_TYPE_UINT16_BE:
{
Uint16_T val = (static_cast(Uint16_T, src));
Uint16ToBigEndianAr( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] + 1 );
bw->curPos += length;
break;
}

case BW_DATA_TYPE_UINT32_BE:
{
Uint32_T val = (static_cast(Uint32_T, src));
Uint32ToBigEndian

Solution

#define CONVERT(T, F, v) T val = *(static_cast(T*, src)); \
    F( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] + v ); \
    bw->curPos += length;

    [...]

    case BW_DATA_TYPE_UINT8:
    {
        CONVERT(Uint8_T, Uint8ToLittleEndianAr, 0)
        break;
    }

    case BW_DATA_TYPE_UINT16_LE:
    {
        CONVERT(Uint16_T, Uint16ToLittleEndianAr, 1)
        break;
    }

    case BW_DATA_TYPE_UINT32_LE:
    {
        CONVERT(Uint32_T, Uint32ToLittleEndianAr, 3)
        break;
    }

    case BW_DATA_TYPE_UINT64_LE:
    {
        CONVERT(Uint64_T, Uint64ToLittleEndianAr, 7)
        break;
    }

    case BW_DATA_TYPE_UINT16_BE:
    {
        CONVERT(Uint16_T, Uint16ToBigEndianAr, 1)
        break;
    }


(untested!)

You can go beyond that and even generate the whole case, but this version is a compromise to keep readability.

[EDIT] I missed the bottom of your code, but I suppose you can complete yourself... :-)

Code Snippets

#define CONVERT(T, F, v) T val = *(static_cast(T*, src)); \
    F( IN val, OUT_FROM &bw->buffer[bw->curPos], OUT_TO &bw->buffer[bw->curPos] + v ); \
    bw->curPos += length;

    [...]

    case BW_DATA_TYPE_UINT8:
    {
        CONVERT(Uint8_T, Uint8ToLittleEndianAr, 0)
        break;
    }

    case BW_DATA_TYPE_UINT16_LE:
    {
        CONVERT(Uint16_T, Uint16ToLittleEndianAr, 1)
        break;
    }

    case BW_DATA_TYPE_UINT32_LE:
    {
        CONVERT(Uint32_T, Uint32ToLittleEndianAr, 3)
        break;
    }

    case BW_DATA_TYPE_UINT64_LE:
    {
        CONVERT(Uint64_T, Uint64ToLittleEndianAr, 7)
        break;
    }

    case BW_DATA_TYPE_UINT16_BE:
    {
        CONVERT(Uint16_T, Uint16ToBigEndianAr, 1)
        break;
    }

Context

StackExchange Code Review Q#4941, answer score: 4

Revisions (0)

No revisions yet.