TuttleOFX  1
FileNumbers.hpp
Go to the documentation of this file.
00001 #ifndef _SEQUENCE_PARSER_FILE_NUMBERS_HPP_
00002 #define _SEQUENCE_PARSER_FILE_NUMBERS_HPP_
00003 
00004 #include <commonDefinitions.hpp>
00005 
00006 #include <boost/regex.hpp>
00007 #include <boost/unordered_map.hpp>
00008 #include <boost/lambda/lambda.hpp>
00009 #include <boost/foreach.hpp>
00010 #include <boost/lexical_cast.hpp>
00011 
00012 #include <set>
00013 
00014 namespace sequenceParser {
00015 namespace detail {
00016 
00017 /**
00018  * @brief Numbers inside a filename.
00019  * Each number can be a time inside a sequence.
00020  * Internal structures to detect sequence inside a directory
00021  */
00022 class FileNumbers
00023 {
00024 
00025 public:
00026         typedef FileNumbers This;
00027         typedef std::pair<Time, std::string> Pair;
00028         typedef std::vector<Pair> Vec;
00029 
00030 public:
00031 
00032         FileNumbers()
00033         {
00034                 // we preverse reserve and take memory,
00035                 // that realloc and takes time.
00036                 _numbers.reserve( 10 );
00037         }
00038 
00039 public:
00040 
00041         void push_back( const std::string& s )
00042         {
00043                 Time t;
00044                 try
00045                 {
00046                         t = boost::lexical_cast<Time > ( s );
00047                 }
00048                 catch( ... )
00049                 {
00050                         // can't retrieve the number,
00051                         // the number inside the string is probably
00052                         // ouf of range for Time type.
00053                         t = 0;
00054                 }
00055                 _numbers.push_back( Pair( t, s ) );
00056         }
00057 
00058         void clear()
00059         {
00060                 _numbers.clear();
00061         }
00062 
00063         const std::string& getString( const std::size_t& i ) const
00064         {
00065                 return _numbers[i].second;
00066         }
00067 
00068         
00069         static bool hasSign( const std::string& s ) { return ( ( s[0] == '-' ) || ( s[0] == '+' ) ); }
00070         
00071         static std::size_t extractPadding( const std::string& str )
00072         {
00073                 if( str.size() == 1 )
00074                         return 0;
00075                 const bool withSign = hasSign(str);
00076                 return str[withSign] == '0' ? str.size()-withSign : 0;
00077         }
00078         
00079         static std::size_t extractNbDigits( const std::string& s )
00080         {
00081                 return s.size() - hasSign( s );
00082         }
00083         
00084         std::size_t getNbDigits( const std::size_t& i ) const
00085         {
00086                 return extractNbDigits( _numbers[i].second );
00087         }
00088         
00089         std::size_t getPadding( const std::size_t& i ) const
00090         {
00091                 return extractPadding( _numbers[i].second );
00092         }
00093 
00094         Time getTime( const std::size_t& i ) const
00095         {
00096                 return _numbers[i].first;
00097         }
00098 
00099         std::size_t size() const
00100         {
00101                 return _numbers.size();
00102         }
00103 
00104         struct SortByNumber
00105         {
00106                 bool operator()( const FileNumbers& a, const FileNumbers& b ) const;
00107         };
00108         struct SortByPadding
00109         {
00110                 bool operator()( const FileNumbers& a, const FileNumbers& b ) const;
00111         };
00112         struct SortByDigit
00113         {
00114                 bool operator()( const FileNumbers& a, const FileNumbers& b ) const;
00115         };
00116         
00117         bool operator<( const This& v ) const
00118         {
00119                 // by default sort by number
00120                 return SortByNumber()( *this, v );
00121         }
00122 
00123         bool rangeEquals( const This& v, const size_t begin, const size_t end ) const
00124         {
00125                 for( std::size_t i = begin; i < end; ++i )
00126                 {
00127                         const Pair& me = this->_numbers[i];
00128                         const Pair& other = v._numbers[i];
00129 
00130                         //me.second.size() != other.second.size() ) // we don't check the padding...
00131                         if( me.first != other.first )
00132                                 return false;
00133                 }
00134                 return true;
00135         }
00136 
00137         friend std::ostream& operator<<( std::ostream& os, const This& p );
00138 
00139 private:
00140         Vec _numbers;
00141 };
00142 
00143 }
00144 }
00145 
00146 #endif