TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/diskCache/DiskCacheTranslator.cpp
Go to the documentation of this file.
00001 #include "DiskCacheTranslator.hpp"
00002 
00003 #include <boost/filesystem/operations.hpp>
00004 #include <boost/format.hpp>
00005 #include <boost/lexical_cast.hpp>
00006 #include <boost/foreach.hpp>
00007 
00008 #include <iostream>
00009 #include <iomanip>
00010 
00011 namespace tuttle {
00012 namespace host {
00013 
00014 boost::filesystem::path DiskCacheTranslator::keyToAbsolutePath( const KeyType key ) const
00015 {
00016     return relativePathToAbsolutePath( keyToRelativePath( key ) );
00017 }
00018 
00019 boost::filesystem::path DiskCacheTranslator::keyToRelativePath( const KeyType key ) const
00020 {
00021     const std::string keyStr = ( boost::format("%1%") % boost::io::group(std::setfill('0'), std::setw(s_digits), key) ).str();
00022     BOOST_ASSERT( keyStr.size() == s_digits );
00023 
00024     boost::filesystem::path relativePath;
00025 
00026     // fixed size split
00027     for( std::size_t i = 0; i < keyStr.size(); i += s_nbCharSplit )
00028     {
00029         relativePath /= keyStr.substr( i, s_nbCharSplit );
00030     }
00031 
00032     return relativePath;
00033 }
00034 
00035 DiskCacheTranslator::KeyType DiskCacheTranslator::relativePathToKey( const boost::filesystem::path& filepath ) const
00036 {
00037     std::string keyStr;
00038     BOOST_FOREACH( const boost::filesystem::path& p, filepath )
00039     {
00040         keyStr += p.string();
00041     }
00042     return boost::lexical_cast<KeyType>( keyStr );
00043 }
00044 
00045 boost::filesystem::path DiskCacheTranslator::absolutePathToRelativePath( const boost::filesystem::path& absoluteKeypath ) const
00046 {
00047     boost::filesystem::path diffPath;
00048 
00049     boost::filesystem::path tmpPath = absoluteKeypath;
00050     while( tmpPath != _rootDir )
00051     {
00052         diffPath = tmpPath.stem() / diffPath;
00053         tmpPath = tmpPath.parent_path();
00054     }
00055 
00056     return diffPath;
00057 }
00058 
00059 DiskCacheTranslator::KeyType DiskCacheTranslator::absolutePathToKey( const boost::filesystem::path& filepath ) const
00060 {
00061     return relativePathToKey( absolutePathToRelativePath( filepath ) );
00062 }
00063 
00064 bool DiskCacheTranslator::contains( const KeyType key ) const
00065 {
00066     boost::system::error_code error;
00067     return boost::filesystem::exists( keyToAbsolutePath( key ), error );
00068 }
00069 
00070 bool DiskCacheTranslator::contains( const KeyType key, std::time_t& lastWriteTime ) const
00071 {
00072     boost::filesystem::path fullKeyPath = keyToAbsolutePath( key );
00073     boost::system::error_code error;
00074     if( ! boost::filesystem::exists( fullKeyPath, error ) )
00075         return false;
00076 
00077     lastWriteTime = boost::filesystem::last_write_time(fullKeyPath);
00078     return true;
00079 }
00080 
00081 bool DiskCacheTranslator::contains( const boost::filesystem::path& keypath ) const
00082 {
00083     boost::system::error_code error;
00084     if( keypath.is_absolute() )
00085         return boost::filesystem::exists( keypath, error );
00086     return boost::filesystem::exists( relativePathToAbsolutePath( keypath ), error );
00087 }
00088 
00089 bool DiskCacheTranslator::contains( const boost::filesystem::path& keyPath, std::time_t& lastWriteTime ) const
00090 {
00091     boost::filesystem::path fullKeyPath = keyPath.is_absolute() ? keyPath : relativePathToAbsolutePath( keyPath );
00092 
00093     boost::system::error_code error;
00094     if( ! boost::filesystem::exists( fullKeyPath, error ) )
00095         return false;
00096 
00097     lastWriteTime = boost::filesystem::last_write_time(keyPath);
00098     return true;
00099 }
00100     
00101 boost::filesystem::path DiskCacheTranslator::get( const KeyType key ) const
00102 {
00103     const boost::filesystem::path p = keyToAbsolutePath( key );
00104     if( ! contains(p) )
00105         BOOST_THROW_EXCEPTION( std::logic_error("Key not found in DiskCacheTranslator.") );
00106     return p;
00107 }
00108 
00109 boost::filesystem::path DiskCacheTranslator::create( const KeyType key )
00110 {
00111     if( _rootDir.empty() )
00112         BOOST_THROW_EXCEPTION( std::logic_error("DiskCacheTranslator base directory is not set!") );
00113 
00114     const boost::filesystem::path p = keyToAbsolutePath( key );
00115     boost::filesystem::create_directories( p.parent_path() );
00116     return p;
00117 }
00118 
00119 }
00120 }
00121