LAMA
|
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_