Go to the documentation of this file.00001 #ifndef __UTILMM_SYSTEM_ENDIAN_HH
00002 #define __UTILMM_SYSTEM_ENDIAN_HH
00003
00004 #include <utilmm/config/config.h>
00005 #include <boost/integer.hpp>
00006
00007 namespace utilmm
00008 {
00013 namespace endian
00014 {
00015 namespace details {
00016 template<int size> struct type_from_size
00017 { typedef typename boost::uint_t<size>::least least; };
00018 template<> struct type_from_size<64>
00019 { typedef uint64_t least; };
00020
00021 template<int size, typename D>
00022 void swap_helper(const D data, D& buffer);
00023
00024 template<> inline void swap_helper<1, uint8_t>(const uint8_t data, uint8_t& buffer)
00025 { buffer = data; }
00026 template<> inline void swap_helper<2, uint16_t>(const uint16_t data, uint16_t& buffer)
00027 { buffer = ((data >> 8) & 0xFF) | ((data << 8) & 0xFF00); }
00028 template<> inline void swap_helper<4, uint32_t>(const uint32_t data, uint32_t& buffer)
00029 { buffer = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) | ((data & 0xFF) << 24) | ((data & 0xFF00) << 8); }
00030 template<> inline void swap_helper<8, uint64_t>(const uint64_t data, uint64_t& buffer)
00031 {
00032 const uint32_t
00033 src_low (data & 0xFFFFFFFF)
00034 , src_high(data >> 32);
00035
00036 uint32_t dst_low, dst_high;
00037 swap_helper<4, uint32_t>( src_high, dst_low );
00038 swap_helper<4, uint32_t>( src_low, dst_high );
00039
00040 buffer = static_cast<uint64_t>(dst_high) << 32 | dst_low;
00041 }
00042 }
00043
00044
00045 template<typename S>
00046 inline void swap(const S data, S& buffer)
00047 {
00048 typedef typename details::type_from_size<sizeof(S) * 8>::least T;
00049 details::swap_helper<sizeof(S), T> (reinterpret_cast<const T&>(data), reinterpret_cast<T&>(buffer));
00050 }
00051
00052
00053 template<typename S>
00054 inline S swap(const S data)
00055 { S ret;
00056 swap(data, ret);
00057 return ret;
00058 }
00059
00060 #ifdef WORDS_BIGENDIAN
00061
00063 template<typename S>
00064 inline void to_big(const S source, S& dest) { dest = source; }
00067 template<typename S>
00068 inline S to_big(const S source) { return source; }
00071 template<typename S>
00072 inline void to_little(const S source, S& dest) { swap<S>(source, dest); }
00075 template<typename S>
00076 inline S to_little(const S source) { return swap<S>(source); }
00077 #else
00078 template<typename S>
00079 inline void to_big(const S source, S& dest) { swap<S>(source, dest); }
00080 template<typename S>
00081 inline S to_big(const S source) { return swap<S>(source); }
00082 template<typename S>
00083 inline void to_little(const S source, S& dest) { dest = source; }
00084 template<typename S>
00085 inline S to_little(const S source) { return source; }
00086 #endif
00087
00090 template<typename S>
00091 inline void from_network(const S source, S& dest) { to_network(source, dest); }
00094 template<typename S>
00095 inline S from_network(const S source) { return to_network(source); }
00098 template<typename S>
00099 inline void from_little(const S source, S& dest) { to_little(source, dest); }
00102 template<typename S>
00103 inline S from_little(const S source) { return to_little(source); }
00106 template<typename S>
00107 inline void from_big(const S source, S& dest) { to_big(source, dest); }
00110 template<typename S>
00111 inline S from_big(const S source) { return to_big(source); }
00112
00113 template<typename S>
00114 inline void to_network(const S source, S& dest) { return to_big(source, dest); }
00115 template<typename S>
00116 inline S to_network(const S source) { return to_big(source); }
00117 }
00118 }
00119
00120 #endif
00121