954,504 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Binary Data To Long

// foo vector of unsigned chars
// contains 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xEC 0x82
std::vector< unsigned char > foo;
long some_long = (long)&foo[6];

// i want the unsigned chars 0x00, 0x1F, 0xEC 0x82 to
// make up the long decimal value of 2092162


Now the above would work if my system was big-endian however how do i get this to work for little-endian?

Also is the above way preferred? or should I be using something like below:

std::copy(&foo[6], &foo[6] + sizeof(long), reinterpret_cast<unsigned char*>(&some_long));
jnewing
Newbie Poster
7 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

>>long some_long = (long)&foo[6];

I think that's called undefined behavior, typecasting an address into a long integer. The two may or may not be the same size, depending on the compiler you are using.

The way I would do it is like this: long some_long = *(long *)&foo[6];

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

Is reversing the vector an option?
I guess this should work:

reverse(foo.begin(), foo.end());
long some_long = *(long *)&foo[0];
Insensus
Junior Poster
112 posts since Mar 2011
Reputation Points: 70
Solved Threads: 46
 

Won't help. If you are converting from big to little endien (or vice versa) you will just simply have to rewrite the order of the bytes. typecasting will not affect that.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

just in case anyone was interested here is how I solved this.

// function to swap endianness
long int swap_long(long int i)
{
    unsigned char bit1, bit2, bit3, bit4;

    bit1 = i & 255;
    bit2 = ( i >> 8 ) & 255;
    bit3 = ( i >> 16 ) & 255;
    bit4 = ( i >> 24 ) & 255;

    return ((int)bit1 << 24) + ((int)bit2 << 16) + ((int)bit3 << 8) + bit4;
}

// function to read data from a vector at a given offset
long int _int32(const std::vector< unsigned char >& data, long offset, bool swap_endian)
{
    long int i = *(long int*)&data[offset];
    
    if (swap_endian)
        return swap_long(i);
    else
        return i;
}

int main()
{
    // assuming foo contains the following series of unsigned chars
    // 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xEC 0x82
    // i want the unsigned chars 0x00, 0x1F, 0xEC 0x82 to
    // make up the long decimal value of 2092162

    unsigned char bar[] = { 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xEC, 0x82 };
    std::vector< unsigned char >foo(bar, bar + sizeof(bar) / sizeof(unsigned char));

    long int myint = _int32(foo, 6, true);

    std::cout << "myint as dec: " << myint << std::endl;
    std::cout << "myint as hex: 0x" << std::hex << std::setw(8) << std::setfill('0') << myint << std::endl;

    return 0;
}
jnewing
Newbie Poster
7 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

And just because I have it finished now anyway, here is what I just made. :P

template <typename T>
T switchEndian(unsigned char * from)
{
	T tmp = 0;
	for(unsigned idx = 0; idx < sizeof(T); idx++) {
		tmp += (from+(sizeof(T)-idx-1))[0] << idx*8;
	}
	return tmp;
}
long result = switchEndian<long>(&foo[6]);


It might be bad code though so I'm not very skilled.

Insensus
Junior Poster
112 posts since Mar 2011
Reputation Points: 70
Solved Threads: 46
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: