異邦人になってみた~上海の人 

上海在住です。中国時代劇をよく見ています、中国旅行の事、weiboやQQの設定、一眼レフカメラの写真掲載、上海での日々の生活情報を書いています

 このブログについて(about)
 

 中国旅行記(体験談)


 スポンサーリンク

C言語でエンディアン(big-little)変換を行う

C言語で、リトルエンディアンをビックエンディアンに、ビックエンディアンをリトルエンディアンに変換するサンプル。
どちらの返還もビットの後ろと前をひっくり返すだけなので関数は1つで済みます。定義で分かりやすく分けています。


ヘッダー定義(H)

/*変数定義*/
#define USHORT uint16_t
#define UINT uint32_t
#define UINT64 uint64_t


/*関数定義*/
#define CONV_USHORT_BIG_2_LITTLE(value) ConvUShortBig2Little((USHORT)value)
#define CONV_USHORT_LITTLE_2_BIG(value) ConvUShortBig2Little((USHORT)value)


#define CONV_UINT_BIG_2_LITTLE(value) ConvUIntBig2Little((UINT)value)
#define CONV_UINT_LITTLE_2_BIG(value) ConvUIntBig2Little((UINT)value)


#define CONV_UINT64_BIG_2_LITTLE(value) ConvUInt64Big2Little((UINT64)value)
#define CONV_UINT64_LITTLE_2_BIG(value) ConvUInt64Big2Little((UINT64)value)

ソースファイル(C)

/* MACRO DEFINE BEGIN */
typedef union
{
USHORT i;
BYTE b[2];
} ShortBigEndian;


typedef union
{
UINT i;
BYTE b[4];
} IntBigEndian;


typedef union
{
UINT64 i;
BYTE b[8];
} Int64BigEndian;
/* MACRO DEFINE END */


/* ENUM BEGIN */
/* ENUM END */




SHORT ConvUShortBig2Little(USHORT value)
{
ShortBigEndian v;
v.i = value;


v.b[0] ^= v.b[1];
v.b[1] ^= v.b[0];
v.b[0] ^= v.b[1];


return v.i;
}
/*-----------------------------------------------------------*/


INT ConvUIntBig2Little(UINT value)
{
IntBigEndian v;
v.i = value;


v.b[0] ^= v.b[3];
v.b[3] ^= v.b[0];
v.b[0] ^= v.b[3];


v.b[1] ^= v.b[2];
v.b[2] ^= v.b[1];
v.b[1] ^= v.b[2];


return v.i;
}
/*-----------------------------------------------------------*/


UINT64 ConvUInt64Big2Little(UINT64 value)
{
Int64BigEndian v;
v.i = value;


v.b[0] ^= v.b[7];
v.b[7] ^= v.b[0];
v.b[0] ^= v.b[7];


v.b[1] ^= v.b[6];
v.b[6] ^= v.b[1];
v.b[1] ^= v.b[6];


v.b[2] ^= v.b[5];
v.b[5] ^= v.b[2];
v.b[2] ^= v.b[5];


v.b[3] ^= v.b[4];
v.b[4] ^= v.b[3];
v.b[3] ^= v.b[4];


return v.i;
}
/*-----------------------------------------------------------*/


VOID ConvDec2BCD(UINT src, PBYTE pDst, INT length)
{
BYTE byH;
BYTE byL;


memset(pDst, 0, length);
for (INT i = 0, j = 0; j < length; j++)
{
if (i++ % 2 == 0)
{
byL = src % 10;
src /= 10;
}


if (i++ % 2 == 1)
{
if (src > 0)
{
byH = src % 10;
src /= 10;
}
else
{
byH = 0;
src = 0;
}


pDst[length - j - 1] = byH << 4 | byL;
}


if (src == 0)
{
break;
}
}
}
/*-----------------------------------------------------------*/


UINT ConvBCD2Dec(PBYTE pSrc, INT length)
{
UINT ret = 0;


for (INT i = 0, j = 1; i < length; i++)
{
ret += j * (pSrc[length - 1 - i] & 0x0F);
j *= 10;
ret += j * ((pSrc[length - 1 - i] & 0xF0) >> 4);
j *= 10;
}


return ret;
}
/*-----------------------------------------------------------*/


VOID PrintRxTxHexData(CONST PBYTE pData, INT length, BOOL rxFlag)
{
if (rxFlag == TRUE)
{
printf("[R]: [ ");
}
else
{
printf("[S]: [ ");
}


for (INT i = 0; i < length; i++)
{
printf("0x%02x ", pData[i] & 0x00ff);
}


printf("]\r\n");
}
/*-----------------------------------------------------------*/


BOOL ConvStr2BCD(PBYTE pSrc, INT srcLen, PBYTE pDst, INT dstLen)
{
BOOL ret = FALSE;


if (srcLen <= dstLen * 2)
{
BYTE byH = 0;
BYTE byL = 0;
BYTE byTmp = 0;


memset(pDst, 0, dstLen);


for (INT i = 0, j = 0; i < srcLen; i++)
{
if (pSrc[srcLen - i - 1] >= '0' && pSrc[srcLen - i - 1] <= '9')
{
byTmp = pSrc[srcLen - i - 1] - '0';
}
else if (pSrc[srcLen - i - 1] >= 'A' && pSrc[srcLen - i - 1] <= 'F')
{
byTmp = pSrc[srcLen - i - 1] - 'A';
}
else if (pSrc[srcLen - i - 1] >= 'a' && pSrc[srcLen - i - 1] <= 'f')
{
byTmp = pSrc[srcLen - i - 1] - 'a';
}
else
{
break;
}


if (i % 2 == 0)
{
byL = byTmp;
}
else
{
byH = byTmp;
pDst[dstLen - j++ - 1] = byH << 4 | byL;
}


if (i == srcLen - 1)
{
if (i % 2 == 0)
{
pDst[dstLen - j++ - 1] = byL;
}


ret = TRUE;
}
}
}


return ret;
}
/*-----------------------------------------------------------*/