: O. Yuanying

Cocoa で Endian 変換

FLVやMP3をCocoaから読むにあたってバイトオーダーの違いに気をつけなくちゃいけなかったので、それについてメモ。

エンディアンを判別する

APIでエンディアンを得る

long NSHostByteOrder (
   void
);

実行時のバイトオーダーを返す。

返り値は以下の定数。

enum _NSByteOrder {
   NS_UnknownByteOrder = CFByteOrderUnknown,
   NS_LittleEndian = CFByteOrderLittleEndian,
   NS_BigEndian = CFByteOrderBigEndian
};

Rosettaで動作していればBigEndianを返すのかな?

マクロで判別

コンパイル時にバイトオーダーによって以下のどちらかの定数が定義される。

  • LITTLE_ENDIAN
  • BIG_ENDIAN

それぞれのバイトオーダー特有の処理を書きたい場合は、

#if __LITTLE_ENDIAN__ 
  // リトルエンディアンの場合の処理
#else
  // その他の場合の処理
#endif

こんな感じ。

データ型の変換

NSSwap* という関数がshort, int, long, long long, float, double 型についてそれぞれ用意されている。

例えばint型については、

unsigned int NSSwapInt (
   unsigned int inv
);

unsigned int NSSwapLittleIntToHost (
   unsigned int x
);

unsigned int NSSwapHostIntToLittle (
   unsigned int x
);

unsigned int NSSwapBigIntToHost (
   unsigned int x
);

unsigned int NSSwapHostIntToBig (
   unsigned int x
);

という感じで関数がそろっている。