BALL  1.4.1
binaryFileAdaptor.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines