deserialize function ( byte array to uint32 )

2019-07-03 08:19发布

Whats the best way to write a deserialize function to convert a byte array into a 32 bit unsigned integer?

    typedef unsigned long  uint32;

    uint32 deserialize_uint32(unsigned char *buffer)
    {
        uint32 value = 0;

        value |= buffer[0] << 24;
        value |= buffer[1] << 16;
        value |= buffer[2] << 8;
        value |= buffer[3];
        return value;

    }

    unsigned char* deserialize_uint32B(unsigned char *buffer, uint32* value)
    {
        *value = 0;

        *value |= buffer[0] << 24;
        *value |= buffer[1] << 16;
        *value |= buffer[2] << 8;
        *value |= buffer[3];
        return buffer + 4;
    }

thanks! or if there's even a better way please let me know.. thanks !

4条回答
\"骚年 ilove
2楼-- · 2019-07-03 08:45

One can make judicious use of casting to do this easily. Just cast the char buffer to the type you want.

uint32 deserialize_uint32(unsigned char *buf)
{
    uint32 *x = (uint32*)buf;
    return *x;
}

unsigned char * deserialize_uint32B(unsigned char *buffer, uint32* value)
{
    *(uint32*)buffer = *value;
    return buffer;
}
查看更多
Luminary・发光体
3楼-- · 2019-07-03 08:52

Your first method may result in better code, because in the second one the compiler must assume that the pointers data and value can alias (though this may be mitigated if the compiler is able to inline the function where it is used).

If you have a C99 compiler, you may want to take advantange of uint32_t, inline and for the second variant, restrict.

查看更多
倾城 Initia
4楼-- · 2019-07-03 08:53

I prefer your first variant over the second. Or you might exploit parallel processing by having four local variables that take the individual bytes shifted by the correct amount. Then, in the final line you return b0shifted | b1shifted | b2shifted | b3shifted.

Anyway, it all depends on your compiler. Your second variant contains more load/store operations, so the first variant has fewer abstract operations.

Concerning readability, understandability and clarity, your first variant is great. It also works on whatever weird platform you are using (endianess, alignment), provided that CHAR_BIT == 8.

查看更多
等我变得足够好
5楼-- · 2019-07-03 09:11

You can write:

#include <arpa/inet.h>

uint32_t deserialize_uint32(unsigned char *buffer) {
    uint32_t res = *((uint32_t *) buffer);
    return ntohl(res);
}

unsigned char *serialize_uint32(unsigned char *buffer, uint32_t *value) {
    *((uint32_t *) buffer) = htonl(*value);
    return buffer;
}

This implementation ensures that the byte ordering is the correct independently from the underlying architecture.

查看更多
登录 后发表回答