異邦人になってみた~~上海生活写真ブログ

中国上海市在住です。もう10年を超えました。休日は星空(天の川)撮影やポートレート撮影等、連休時はカメラを持って中国各地を旅行してます。最近は内モンゴル自治区によく行っています。

 このブログについて(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;
}
/*-----------------------------------------------------------*/