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
00068 T data_;
00069
00070
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
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
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
00172
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 }
00182
00183 #ifndef BALL_NO_INLINE_FUNCTIONS
00184 #include <BALL/SYSTEM/binaryFileAdaptor.iC>
00185 #endif
00186
00187 #endif //BALL_SYSTEM_BINARYFILEADAPTOR_H