TuttleOFX
1
|
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