$search
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 /* Returns in \c buffer the value of \c data with endianness swapped */ 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 /* Returns the value of \c data with endianness swapped */ 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