LAMA
/home/brandes/workspace/LAMA/src/lama/io/XDRFileStream.hpp
Go to the documentation of this file.
00001 
00034 #ifndef XDRFILESTREAM_HPP_
00035 #define XDRFILESTREAM_HPP_
00036 
00037 // for dll_import
00038 #include <lama/config.hpp>
00039 #include <lama/exception/Exception.hpp>
00040 
00041 // others
00042 #include <fstream>
00043 #include <cstdlib>
00044 #include <typeinfo>
00045 #include <sstream>
00046 
00047 namespace lama
00048 {
00049 
00054 class LAMA_DLL_IMPORTEXPORT XDRFileStream
00055 {
00056 public:
00066     XDRFileStream(const std::string& filename,
00067                   const std::ios_base::openmode openmode);
00068 
00073     virtual ~XDRFileStream();
00074 
00082     template <typename T>
00083     void read(T * const input, const std::streamsize n);
00084 
00091     template <typename T>
00092     void read(T * const input);
00093 
00094 
00102     template <typename T>
00103     void write(T * const input, const std::streamsize n);
00104 
00111     template <typename T>
00112     void write(T * const input);
00113 
00114 
00120     bool is_open();
00121 
00125     void close();
00126 
00127 private:
00128 
00129     std::string m_filename;
00130     std::fstream m_filestream;
00131 
00132     std::ios_base::openmode m_openmode;
00133 
00134     void openFilePointer(const std::string filename,
00135                          const std::ios_base::openmode openmode);
00136     template <typename T>
00137     void xdrRead(T* const data);
00138     template <typename T>
00139     void xdrWrite(const T* const data);
00140 
00141     template <typename T>
00142     int getSize(const T);
00143 
00144     bool isLittleEndian();
00145 
00146 }; //class XDRFileStream
00147 
00148 template <typename T>
00149 void XDRFileStream::write(T * const input, const std::streamsize n)
00150 {
00151     if(m_openmode&std::ios::in)
00152     {
00153         LAMA_THROWEXCEPTION("XDRFileStream: Stream is not in Output mode");
00154     }
00155     for (std::streamsize i = 0; i<n; i++)
00156     {
00157         xdrWrite(&input[i]);
00158     }
00159 }
00160 
00161 template <typename T>
00162 void XDRFileStream::write(T * const input)
00163 {
00164     write(input,1);
00165 }
00166 
00167 template <typename T>
00168 void XDRFileStream::read(T * const input, const std::streamsize n)
00169 {
00170     if(m_openmode&std::ios::out)
00171     {
00172         LAMA_THROWEXCEPTION( "XDRFileStream: Stream is not in Input mode" );
00173     }
00174     for (std::streamsize i = 0; i<n; i++)
00175     {
00176         xdrRead(&input[i]);
00177     }
00178 }
00179 
00180 template <typename T>
00181 void XDRFileStream::read(T * const input)
00182 {
00183     read(input,1);
00184 }
00185 
00186 template <typename T>
00187 void XDRFileStream::xdrRead(T* const data){
00188     if(!is_open())
00189     {
00190         LAMA_THROWEXCEPTION( "Error trying to read from closed XDRFileStream" );
00191     }
00192     const int length = getSize(*data);
00193     *data = 0;
00194     char* dataptr = reinterpret_cast<char*>(data);
00195     if(isLittleEndian())
00196     {
00197         for(int pos = length-1; pos >= 0; pos--)
00198         {
00199             m_filestream.read(dataptr+pos,1);
00200         }
00201     }else{
00202         m_filestream.read(dataptr,length);
00203     }
00204     //correct the signed bit
00205     if (typeid(T) == typeid(long))
00206     {
00207         int i = 0|static_cast<long>(*data);
00208         *data =0;
00209         *data = static_cast<T>( i );
00210     }
00211 }
00212 template <typename T>
00213 void XDRFileStream::xdrWrite(const T* const data){
00214     if( !is_open() )
00215     {
00216         LAMA_THROWEXCEPTION( "Error trying to read from closed XDRFileStream" );
00217     }
00218     const int length = getSize(*data);
00219     //correct the signed bit
00220     T tempData = *data;
00221     if ( typeid(T) == typeid(unsigned long) )
00222     {
00223         //Check if unsigned long is over the limit of XDR
00224         if(((static_cast<long>(*data)))>((static_cast<long>(1)<<(length*8))-1))
00225         {
00226             LAMA_THROWEXCEPTION( "unsigned long is to big for XDR (Limit 4 Byte)" );
00227         }
00228     }
00229     if ( typeid(T) == typeid(long) )
00230     {
00231         if(std::abs(static_cast<long>(*data))>=(1<<30)-1)
00232         {
00233             LAMA_THROWEXCEPTION( "long is to big for XDR (Limit 4 Byte)" );
00234         }
00235         int temp = static_cast<long>(*data);
00236         tempData= static_cast<T>( 0|temp );
00237     }
00238     char* dataptr = reinterpret_cast<char*>(&tempData);
00239     if(isLittleEndian())
00240     {
00241         for(int pos = length-1; pos >= 0; pos--)
00242         {
00243             m_filestream.write(dataptr+pos,1);
00244         }
00245     }
00246     else
00247     {
00248         m_filestream.write(dataptr,length);
00249     }
00250 }
00251 
00252 template <typename T>
00253 int XDRFileStream::getSize(const T)
00254 {
00255     int size = 0;
00256 
00257     if(typeid(T) == typeid(double))
00258     {
00259         size = 8;
00260     }
00261     else if (typeid(T) == typeid(float))
00262     {
00263         size = 4;
00264     }
00265     else if (typeid(T) == typeid(int))
00266     {
00267         size = 4;
00268     }
00269     else if (typeid(T) == typeid(long))
00270     {
00271         size = 4;
00272     }
00273     else if (typeid(T) == typeid(unsigned long))
00274     {
00275         size = 4;
00276     }
00277     else if (typeid(T) == typeid(unsigned int))
00278     {
00279         size = 4;
00280     }
00281     else
00282     {
00283         LAMA_THROWEXCEPTION( (std::string("XDRFileStream: Type not permitted: ") + typeid(T).name()).c_str() );
00284     }
00285     return size;
00286 }
00287 
00288 
00289 } //namespace lama
00290 
00291 #endif // XDRFILESTREAM_HPP_