エンディアン変換プログラム

ネットワークプログラムを組む際に,Big Endian (Network Byte Order) <--> Little Endian (x86) のエンディアン変換プログラムを書いてみた.(ほとんど参考サイトの写経ともいう.)

/** @file endian_utility.hpp
 *  @brief Header file for utility fanctions to change endian.
 */
#ifndef ENDIAN_UTILITY_HPP__INCLUDED
#define ENDIAN_UTILITY_HPP__INCLUDED

#include <boost/cstdint.hpp> //< for boost::uint8_t etc.

namespace endian {

  // check endian for the host CPU
  inline bool isLittleEndian()
  {
    boost::uint16_t test_data = 0x0001; //< 2 bytes data
    // test data are stored as ...
    // "00 01" if BigEndian
    // "01 00" if LittleEndian
    // So, check the first byte:
    return (0x01 == (*(reinterpret_cast<boost::uint8_t*>(&test_data))));
  }

  inline bool isBigEndian()
  {
    return !isLittleEndian();
  }

  inline boost::uint16_t reverseEndian(boost::uint16_t value)
  {
    value = static_cast<boost::uint16_t> ((value & 0x00FF) << 8 | (value & 0xFF00) >> 8);
    return value;
  }

  inline boost::uint32_t reverseEndian(boost::uint32_t value)
  {
    value = static_cast<boost::uint32_t> ((value & 0x00FF00FF) << 8 | (value & 0xFF00FF00) >> 8);
    value = static_cast<boost::uint32_t> ((value & 0x0000FFFF) << 16 | (value & 0xFFFF0000) >> 16);
    return value;
  }

  inline boost::uint64_t reverseEndian(boost::uint64_t value)
  {
    value = static_cast<boost::uint64_t> ((value & 0x00FF00FF00FF00FF) << 8 | (value & 0xFF00FF00FF00FF00) >> 8);
    value = static_cast<boost::uint64_t> ((value & 0x0000FFFF0000FFFF) << 16 | (value & 0xFFFF0000FFFF0000) >> 16);
    value = static_cast<boost::uint64_t> ((value & 0x00000000FFFFFFFF) << 32 | (value & 0xFFFFFFFF00000000) >> 32);
    return value;
  }

} //< namespace Endian

#endif //< ENDIAN_UTILITY_HPP__INCLUDED

参考にしたサイト

追記(2011-05-27)

templateを利用したエンディアン変換プログラムを見つけた:

これらの場合,

  • Cons: 型に依らない
  • Pros: 1 byte ごとの処理になるため,データサイズに線形の処理時間がかかる

と思われる.