BALL
1.4.1
|
00001 #ifndef BALL_SYSTEM_BINARYFILEADAPTOR_H 00002 #define BALL_SYSTEM_BINARYFILEADAPTOR_H 00003 00004 #include <iostream> 00005 #include <algorithm> 00006 00007 #ifndef BALL_COMMON_LOGSTREAM_H 00008 # include <BALL/COMMON/logStream.h> 00009 #endif 00010 00011 namespace BALL 00012 { 00025 template <typename T> 00026 class BinaryFileAdaptor 00027 { 00028 00029 public: 00030 00032 00033 00035 BinaryFileAdaptor(); 00036 00038 BinaryFileAdaptor(const T& data, bool swap_endian = false); 00039 00041 00042 00043 00045 void setSwapEndian(bool swap_endian); 00046 00048 bool getSwapEndian() const; 00049 00053 void setData(const T& data); 00054 00057 const T& getData() const; 00058 00061 T& getData(); 00062 00064 00065 protected: 00066 00067 //_ The member data. 00068 T data_; 00069 00070 //_ A flag indicating whether we should swap all reads and writes 00071 bool swap_endian_; 00072 }; 00073 00074 template <typename T> 00075 BinaryFileAdaptor<T>::BinaryFileAdaptor() 00076 : data_(), 00077 swap_endian_(false) 00078 { 00079 } 00080 00081 template <typename T> 00082 BinaryFileAdaptor<T>::BinaryFileAdaptor(const T& data, bool swap_endian) 00083 : data_(data), 00084 swap_endian_(swap_endian) 00085 { 00086 } 00087 00088 template <typename T> 00089 void BinaryFileAdaptor<T>::setSwapEndian(bool swap_endian) 00090 { 00091 swap_endian_ = swap_endian; 00092 } 00093 00094 template <typename T> 00095 bool BinaryFileAdaptor<T>::getSwapEndian() const 00096 { 00097 return swap_endian_; 00098 } 00099 00100 template <typename T> 00101 void BinaryFileAdaptor<T>::setData(const T& data) 00102 { 00103 data_ = data; 00104 } 00105 00106 template <typename T> 00107 const T& BinaryFileAdaptor<T>::getData() const 00108 { 00109 return data_; 00110 } 00111 00112 template <typename T> 00113 T& BinaryFileAdaptor<T>::getData() 00114 { 00115 return data_; 00116 } 00117 00119 template <typename T> 00120 std::ostream& operator << (std::ostream& os, const BinaryFileAdaptor<T>& data) 00121 { 00122 // do we need to swap endianness? 00123 if (!data.getSwapEndian()) 00124 { 00125 os.write(reinterpret_cast<const char*>(&data.getData()), sizeof(T)); 00126 } 00127 else 00128 { 00129 T swapped_data = data.getData(); 00130 swapBytes(swapped_data); 00131 os.write(reinterpret_cast<const char*>(&swapped_data), sizeof(T)); 00132 } 00133 return os; 00134 } 00135 00137 template <typename T> 00138 std::istream& operator >> (std::istream& is, BinaryFileAdaptor<T>& data) 00139 { 00140 // do we need to swap endianness? 00141 if (!data.getSwapEndian()) 00142 { 00143 is.read(reinterpret_cast<char*>(&data.getData()), sizeof(T)); 00144 } 00145 else 00146 { 00147 T swapped_data; 00148 is.read(reinterpret_cast<char*>(&swapped_data), sizeof(T)); 00149 swapBytes(swapped_data); 00150 data.setData(swapped_data); 00151 } 00152 return is; 00153 } 00154 00158 template <typename T> 00159 void swapBytes(T& t) 00160 { 00161 if (sizeof(T) % 2 != 0) 00162 { 00163 Log.error() << "Cannot swap types of uneven size." << std::endl; 00164 return; 00165 } 00166 00167 char* tmp = reinterpret_cast<char*>(&t); 00168 std::reverse(tmp, tmp + sizeof(T)); 00169 } 00170 00171 //In the following some specialisations of swapBytes are provided for efficiency reasons 00172 //These should also cover BALL types like Size, Position and Index 00173 template<> BALL_EXPORT void swapBytes(unsigned short&); 00174 template<> BALL_EXPORT void swapBytes(short&); 00175 template<> BALL_EXPORT void swapBytes(unsigned int&); 00176 template<> BALL_EXPORT void swapBytes(int&); 00177 template<> BALL_EXPORT void swapBytes(unsigned long&); 00178 template<> BALL_EXPORT void swapBytes(long&); 00179 template<> BALL_EXPORT void swapBytes(float&); 00180 template<> BALL_EXPORT void swapBytes(double&); 00181 } //namespace BALL 00182 00183 #ifndef BALL_NO_INLINE_FUNCTIONS 00184 #include <BALL/SYSTEM/binaryFileAdaptor.iC> 00185 #endif 00186 00187 #endif //BALL_SYSTEM_BINARYFILEADAPTOR_H