在做跨平臺(tái)的網(wǎng)絡(luò)數(shù)據(jù)傳輸和文件數(shù)據(jù)轉(zhuǎn)換和移植的時(shí)候,經(jīng)常會(huì)碰到CPU字節(jié)序不同導(dǎo)致的各種各樣的問題.
于是,在編寫平臺(tái)無關(guān),字符編碼無關(guān)的要求之外,又有一個(gè)新的對(duì)跨平臺(tái)編碼的要求,那就是字節(jié)序無關(guān).
其實(shí)要實(shí)現(xiàn)這個(gè)也不難, 只要能夠檢測(cè)和轉(zhuǎn)換字節(jié)序, 就完全可以實(shí)現(xiàn).
下面提供各一種方法來解決這兩個(gè)問題.
// 檢測(cè)平臺(tái)的Endian
typedef union uEndianTest{
struct
{
bool flittle_endian;
bool fill[3];
};
long value;
}EndianTest;
static const EndianTest __Endian_Test__ = { (long)1 };
const bool platform_little_endian = __Endian_Test__.flittle_endian;
這樣使用這個(gè) platform_little_endian 就可以檢測(cè)到當(dāng)前平臺(tái)是否是little_endian
// Endian 轉(zhuǎn)換(64位, 32位和16位的字節(jié)序轉(zhuǎn)換)
// 中間使用了異或交換的算法
// 使用方法舉例:
// long lValue = 0xff000000;
// ConvertEndian32( &lValue );
//
inline void ConvertEndian64( LPVOID lpMem )
{
BYTE * p = (BYTE*)lpMem;
p[0] = p[0] ^ p[7];
p[7] = p[0] ^ p[7];
p[0] = p[0] ^ p[7];
p[1] = p[1] ^ p[6];
p[6] = p[1] ^ p[6];
p[1] = p[1] ^ p[6];
p[2] = p[2] ^ p[5];
p[5] = p[2] ^ p[5];
p[2] = p[2] ^ p[5];
p[3] = p[3] ^ p[4];
p[4] = p[3] ^ p[4];
p[3] = p[3] ^ p[4];
}
inline void ConvertEndian32( LPVOID lpMem )
{
BYTE * p = (BYTE*)lpMem;
p[0] = p[0] ^ p[3];
p[3] = p[0] ^ p[3];
p[0] = p[0] ^ p[3];
p[1] = p[1] ^ p[2];
p[2] = p[1] ^ p[2];
p[1] = p[1] ^ p[2];
}
inline void ConvertEndian16( LPVOID lpMem )
{
BYTE * p = (BYTE*)lpMem;
p[0] = p[0] ^ p[1];
p[1] = p[0] ^ p[1];
p[0] = p[0] ^ p[1];
}