エンディアン変換プログラム
ネットワークプログラムを組む際に,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を利用したエンディアン変換プログラムを見つけた:
- http://www.kijineko.co.jp/tech/cpptempls/endian/reverse_endian.html
- http://blog.petermares.com/2010/10/26/snippet-endian-swap-template/
これらの場合,
- Cons: 型に依らない
- Pros: 1 byte ごとの処理になるため,データサイズに線形の処理時間がかかる
と思われる.