ISIS Core Library 0.7.2 (api 3.0.0)
|
00001 // 00002 // fileptr.hpp 00003 // isis 00004 // 00005 // Created by Enrico Reimer on 08.08.11. 00006 // Copyright 2011 __MyCompanyName__. All rights reserved. 00007 // 00008 00009 #ifndef FILEPTR_HPP 00010 #define FILEPTR_HPP 00011 00012 #define BOOST_FILESYSTEM_VERSION 2 //@todo remove as soon as we switch to boost 1.42 00013 #include <boost/filesystem.hpp> 00014 #include <boost/detail/endian.hpp> 00015 #include "valuearray.hpp" 00016 #include "endianess.hpp" 00017 00018 #ifdef WIN32 00019 #include <windows.h> 00020 #define FILE_HANDLE HANDLE 00021 #else 00022 #define FILE_HANDLE int 00023 #endif 00024 00025 namespace isis 00026 { 00027 namespace data 00028 { 00038 class FilePtr: public ValueArray<uint8_t> 00039 { 00040 struct Closer { 00041 FILE_HANDLE file, mmaph; 00042 size_t len; 00043 boost::filesystem::path filename; 00044 bool write; 00045 void operator()( void *p ); 00046 }; 00047 typedef data::ValueArrayReference( *generator_type )( data::FilePtr &, size_t, size_t, bool ); 00048 struct GeneratorMap: public std::map<unsigned short, generator_type> { 00049 GeneratorMap(); 00050 template<class T> static data::ValueArrayReference generator( data::FilePtr &mfile, size_t offset, size_t len, bool swap_endianess ) { 00051 return mfile.at<T>( offset, len, swap_endianess ); 00052 } 00053 struct proc { 00054 std::map<unsigned short, generator_type> *m_map; 00055 proc( std::map<unsigned short, generator_type> *map ): m_map( map ) {} 00056 template<class T> void operator()( const T & ) { 00057 m_map->insert( std::make_pair( ValueArray<T>::staticID, &generator<T> ) ); 00058 } 00059 }; 00060 }; 00061 00062 bool map( FILE_HANDLE file, size_t len, bool write, const boost::filesystem::path &filename ); 00063 00064 size_t checkSize( bool write, FILE_HANDLE file, const boost::filesystem::path &filename, size_t size = 0 ); 00065 bool m_good, writing; 00066 public: 00068 FilePtr(); 00089 FilePtr( const boost::filesystem::path &filename, size_t len = 0, bool write = false ); 00090 00103 template<typename T> ValueArray<T> at( size_t offset, size_t len = 0, bool swap_endianess = false ) { 00104 boost::shared_ptr<T> ptr = boost::static_pointer_cast<T>( getRawAddress( offset ) ); 00105 00106 if( len == 0 ) { 00107 len = ( getLength() - offset ) / sizeof( T ); 00108 LOG_IF( ( getLength() - offset ) % sizeof( T ), Runtime, warning ) 00109 << "The remaining filesize " << getLength() - offset << " does not fit the bytesize of the requested type " 00110 << util::Value<T>::staticName(); 00111 } 00112 00113 LOG_IF( len * sizeof( T ) > ( getLength() - offset ), Debug, error ) 00114 << "The requested length will be " << len - ( getLength() - offset ) << " bytes behind the end of the file."; 00115 LOG_IF( writing && swap_endianess, Debug, warning ) 00116 << "Ignoring requested to swap byte order for writing (the systems byte order is " << BOOST_BYTE_ORDER << " and that will be used)"; 00117 00118 if( writing || !swap_endianess ) { // if not endianess swapping was requested or T is not float (or if we are writing) 00119 return data::ValueArray<T>( ptr, len ); // return a cheap copy 00120 } else { // flip bytes into a new ValueArray 00121 LOG( Debug, info ) << "Byte swapping " << ValueArray<T>::staticName() << " for endianess"; 00122 ValueArray<T> ret( len ); 00123 data::endianSwapArray( ptr.get(), ptr.get() + std::min( len, getLength() / sizeof( T ) ), ret.begin() ); 00124 return ret; 00125 } 00126 00127 } 00128 00145 data::ValueArrayReference atByID( unsigned short ID, size_t offset, size_t len = 0, bool swap_endianess = false ); 00146 00147 bool good(); 00148 void release(); 00149 }; 00150 00151 } 00152 } 00153 00154 #endif