Jump to content
  • Advertisement
Sign in to follow this  
silverphyre673

I need someone to check if my program works on big-endian (Mac)

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I've been working on a hiscore system. It saves the hiscores to a binary file using a format and process I made myself. It tries to take into account both big and little endian systems. It works fine on my PC, which is little endian. I was hoping to get someone with a big-endian system (like a Mac) to test it out and make sure it works. If possible, please download it and test it out. You should just be able to put all the files together in a project using your favorite IDE or into a makefile for make, and compile them. They don't have any windows-only code. Thanks a lot, I appreciate it!

Share this post


Link to post
Share on other sites
Advertisement
I have a windows machine, but I still have a couple suggestions. I don't think that code would work quite the way you think it would.


// always specify the sign of a char in these cases...some systems have
// different defaults
char * ReverseByteOrder( const char * bytes )
{
// whats this for?
char swap;
// what if bytes isn't null terminated? Or what if its terminated too early?
unsigned int length = std::strlen(bytes);

// this points at one byte?
char * ret = new char[1];
// going out of bounds here
std::strcpy(ret, bytes);

for ( unsigned int i = 0, j = length-1; i < length; ++i, --j )
{

ret = bytes[j];
}
return ret;
}



Here's some changes I think would help you, this still isn't the optimal solution, but its the first thing that popped into my head

#include <iostream>
#include <bitset>
#include <exception>
#include <climits>
using std::bitset;
using std::cout;
using std::endl;
using std::cerr;

void * ReverseByteOrder(const void *pValue, const std::size_t numBytes)
{
if( 0 == pValue ) throw(std::exception(__FUNCTION__));

std::size_t i, j = numBytes-1;
const unsigned char *pData = reinterpret_cast<const unsigned char*>(pValue);
unsigned char *pRetVal = new unsigned char[numBytes];

for(i=0; i < numBytes; ++i, --j )
pRetVal = pData[j];

return(pRetVal);
}


int main()
{
unsigned int before = 1, *pAfter = NULL;
std::bitset<sizeof(int) * CHAR_BIT> b;

try{
b = before;
cout << "Before swap\t" << b << endl;


pAfter = (unsigned int*)ReverseByteOrder( &before, sizeof(before));

b = *pAfter;

cout << "After swap\t" << b << endl;


}
catch(std::exception &e)
{
cerr << e.what() << endl;
}
catch(...)
{
cerr << "An unknown exception has occurred" << endl;
}

delete [] pAfter;

return(0);
}








[EDIT]
Odd, well if it works it works I guess.. =) I could have sworn you should have been going out of bounds in a couple of spots there...
[/EDIT]

[Edited by - moeron on June 10, 2005 10:13:26 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hello,

I didn't look at your code, sorry. Here is the output on a 32-bit big endian machine (G4 PPC):

Mary has 1904 points.
Ben has 18 points.
John has 18 points.
Bip has 9 points.
Jeremy has 8 points.
Bob has 8 points.


Hope this helps.

Share this post


Link to post
Share on other sites
Sweet! Guess it works. Anyone else give it a try? I would have rated you up anonymous, but you are anonymous :) ++rate for moeron, though. I appreciate it.

Share this post


Link to post
Share on other sites
I couldn't get hiscoresystem.cpp to compile, got the following warnings and errors from g++:

hiscoresystem.cpp: In member function `bool HiscoreSystem::Load()':
hiscoresystem.cpp:153: warning: comparison between signed and unsigned integer
expressions
hiscoresystem.cpp:173: error: type specifier omitted for parameter `score'
hiscoresystem.cpp:174: error: no matching function for call to `
std::vector<Hiscore, std::allocator<Hiscore> >::push_back(Hiscore
(&)(std::basic_string<char, std::char_traits<char>, std::allocator<char> >))
'
/usr/include/c++/3.3.2/bits/stl_vector.h:596: error: candidates are: void
std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Hiscore, _Alloc
= std::allocator<Hiscore>]


Maybe i'm forgetting something, i'll come back and look at it when I get the chance.

Share this post


Link to post
Share on other sites
I've made some code changes - found one of the errors you mentioned. If you could re-download it, that would be great, because the line numbers have changed :) The original link should work fin.

I really appreciate you taking the time to do this, though. Thanks again!

Share this post


Link to post
Share on other sites
Your code relies on having a null terminated byte string (unsigned int length = std::strlen(bytes);)



Try this, it's more type safe than your solution - you should declare this in an anonymous namesapce and have wrappers for it only for types that it makes sense to endian-swap:


template<class T>
T& ReverseByteOrder(T& value)
{
unsigned char* ptr = reinterpret_cast<unsigned char*>(&value);

size_t index = 0;
for(;index<(sizeof(T)/2);++index)
{
std::swap(ptr[index],ptr[size - index -1]);
}

return value;
}

template<class T>
T ReverseByteOrder_copy(const T& value)
{
T value_copy = value;
ReverseByteOrder(value_copy);
return value_copy;
}


I don't have access to the actual code I use right now, so I had to write this from memory, but hopefully you get the idea.





Share this post


Link to post
Share on other sites
Guest Anonymous Poster
the endian won't and doesn't matter

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
the endian won't and doesn't matter


Why not? I posted something on this a while ago and everyone told me it would. Anyways, I tried this:

entries_to_write = ReverseByteOrder_copy<int>(entries_to_write);

and similar on all the lines where I needed to reverse the byte order (changing <int> to <char*> when neccessary), but it gave me a bunch of linker errors, like this for example:

[Linker error] undefined reference to `int ReverseByteOrder<int>(int const&)'

I can't think of how I'm supposed to change the statement so it will work. Can you give me an example? Thanks.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!