ISIS Core Library 0.7.2 (api 3.0.0)

/scr/tee1/isis/lib/Core/DataStorage/fileptr.hpp

Go to the documentation of this file.
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