TuttleOFX
1
|
00001 #include "detector.hpp" 00002 #include "Sequence.hpp" 00003 #include "Folder.hpp" 00004 #include "File.hpp" 00005 00006 #include "detail/analyze.hpp" 00007 #include "detail/FileNumbers.hpp" 00008 #include "detail/FileStrings.hpp" 00009 #include "commonDefinitions.hpp" 00010 00011 #include <boost/regex.hpp> 00012 #include <boost/unordered_map.hpp> 00013 #include <boost/lambda/lambda.hpp> 00014 #include <boost/foreach.hpp> 00015 #include <boost/lexical_cast.hpp> 00016 00017 #include <set> 00018 00019 00020 namespace sequenceParser { 00021 00022 using detail::FileNumbers; 00023 using detail::FileStrings; 00024 namespace bfs = boost::filesystem; 00025 00026 // NOTE How we can replace this with a wrapper? 00027 // Like boost::function, boost::bind,... 00028 00029 struct SeqIdHash : std::unary_function<FileStrings, std::size_t> 00030 { 00031 std::size_t operator()(const FileStrings & p ) const 00032 { 00033 return p.getHash(); 00034 } 00035 }; 00036 00037 00038 boost::regex convertFilterToRegex( std::string filter, const EMaskOptions desc ) 00039 { 00040 boost::cmatch match; 00041 boost::regex expression( "(.*[%])([0-9]{2})([d].*)" ); // match to pattern like : %04d 00042 if( boost::regex_match( filter.c_str(), match, expression ) ) 00043 { 00044 std::string matched = match[1].second; 00045 matched.erase( 2 , matched.size()-2); // keep only numbers 00046 const int patternWidth = boost::lexical_cast<int>( matched ); 00047 std::string replacing( patternWidth, '#' ); 00048 filter = boost::regex_replace( filter, boost::regex( "\\%\\d{1,2}d" ), replacing ); 00049 } 00050 00051 // for detect sequence based on a single file 00052 if( ( desc & eMaskOptionsSequenceBasedOnFilename ) ) 00053 filter = boost::regex_replace( filter, boost::regex( "\\d" ), "[0-9]" ); 00054 00055 filter = boost::regex_replace( filter, boost::regex( "\\*" ), "(.*)" ); 00056 filter = boost::regex_replace( filter, boost::regex( "\\?" ), "(.)" ); 00057 if( desc & eMaskOptionsNegativeIndexes ) 00058 { 00059 filter = boost::regex_replace( filter, boost::regex( "\\@" ), "[\\-\\+]?[0-9]+" ); // one @ correspond to one or more digits 00060 filter = boost::regex_replace( filter, boost::regex( "\\#" ), "[\\-\\+]?[0-9]" ); // each # in pattern correspond to a digit 00061 } 00062 else 00063 { 00064 filter = boost::regex_replace( filter, boost::regex( "\\@" ), "[0-9]+" ); // one @ correspond to one or more digits 00065 filter = boost::regex_replace( filter, boost::regex( "\\#" ), "[0-9]" ); // each # in pattern correspond to a digit 00066 } 00067 return boost::regex( filter ); 00068 } 00069 00070 std::vector<boost::regex> convertFilterToRegex( const std::vector<std::string>& filters, const EMaskOptions desc ) 00071 { 00072 std::vector<boost::regex> res; 00073 BOOST_FOREACH( const std::string& filter, filters ) 00074 { 00075 res.push_back( convertFilterToRegex( filter, desc ) ); 00076 } 00077 return res; 00078 } 00079 00080 /** 00081 * Detect if the filename is filtered by one of the filter 00082 * 00083 * @param[in] filename filename need to be check if it filtered 00084 * @param[in] filters vector of filters 00085 * @param[in] desc enable research options (Cf. EMaskOptions in commonDefinitions.hpp ) 00086 * 00087 * @return return true if the filename is filtered by filter(s) 00088 */ 00089 bool filenameIsNotFilter( const std::string& filename, const std::vector<boost::regex>& filters ) 00090 { 00091 if( filters.size() == 0 ) 00092 return true; 00093 00094 BOOST_FOREACH( const boost::regex& filter, filters ) 00095 { 00096 if( boost::regex_match( filename, filter ) ) 00097 { 00098 return true; 00099 } 00100 } 00101 return false; 00102 } 00103 00104 bool isNotFilter( const bfs::path& inputPath, const std::vector<boost::regex>& filters, const std::string& filename, const EMaskOptions desc ) 00105 { 00106 if( !( inputPath.filename().string()[0] == '.' ) || ( desc & eMaskOptionsDotFile ) ) // if we ask to show hidden files and if it is hidden 00107 { 00108 if( filenameIsNotFilter( inputPath.filename().string(), filters ) ) // filtering of entries with filters strings 00109 { 00110 if( filename.size() ) 00111 { 00112 if( filename == inputPath.string() ) 00113 { 00114 return true; 00115 } 00116 else 00117 { 00118 return false; 00119 } 00120 } 00121 else 00122 { 00123 return true; 00124 } 00125 } 00126 } 00127 return false; 00128 } 00129 00130 00131 boost::ptr_vector<File> fileInDirectory( const std::string& directory, const EMaskOptions desc ) 00132 { 00133 std::vector<std::string> filters; 00134 return fileInDirectory( directory, filters, desc ); 00135 } 00136 00137 boost::ptr_vector<File> fileInDirectory( const std::string& dir, std::vector<std::string>& filters, const EMaskOptions desc ) 00138 { 00139 boost::ptr_vector<File> outputFiles; 00140 std::string tmpDir( dir ); 00141 std::string filename; 00142 00143 if( !detectDirectoryInResearch( tmpDir, filters, filename ) ) 00144 { 00145 return outputFiles; 00146 } 00147 00148 const std::vector<boost::regex> reFilters = convertFilterToRegex( filters, desc ); 00149 00150 // variables for sequence detection 00151 typedef boost::unordered_map<FileStrings, std::vector<FileNumbers>, SeqIdHash> SeqIdMap; 00152 bfs::path directory( tmpDir ); 00153 SeqIdMap sequences; 00154 00155 // temporary variables, should be inside the loop but here for optimization. 00156 FileStrings tmpStringParts; // an object uniquely identify a sequence 00157 FileNumbers tmpNumberParts; // the vector of numbers inside one filename 00158 00159 // for all files in the directory 00160 bfs::directory_iterator itEnd; 00161 for( bfs::directory_iterator iter( directory ); iter != itEnd; ++iter ) 00162 { 00163 // clear previous infos 00164 tmpStringParts.clear(); 00165 tmpNumberParts.clear(); // (clear but don't realloc the vector inside) 00166 00167 if( isNotFilter( iter->path(), reFilters, filename, desc ) ) 00168 { 00169 // it's a file or a file of a sequence 00170 if( filenameIsNotFilter( iter->path().filename().string(), reFilters ) && 00171 ( ( filename.size() && filename == iter->path().filename().string() ) || !filename.size() ) ) // filtering of entries with filters strings 00172 { 00173 // if at least one number detected 00174 if( decomposeFilename( iter->path().filename().string(), tmpStringParts, tmpNumberParts, desc ) ) 00175 { 00176 // need to construct sequence to detect file with a pattern but with only one image 00177 const SeqIdMap::iterator it( sequences.find( tmpStringParts ) ); 00178 if( it != sequences.end() ) // is already in map 00179 { 00180 // append the vector of numbers 00181 sequences.at( tmpStringParts ).push_back( tmpNumberParts ); 00182 } 00183 else 00184 { 00185 // create an entry in the map 00186 std::vector<FileNumbers> li; 00187 li.push_back( tmpNumberParts ); 00188 sequences.insert( SeqIdMap::value_type( tmpStringParts, li ) ); 00189 } 00190 } 00191 else 00192 { 00193 if( ! bfs::is_directory( directory / iter->path().filename().string() ) ) 00194 { 00195 outputFiles.push_back( new File( directory, iter->path().filename().string(), desc ) ); 00196 } 00197 } 00198 } 00199 } 00200 } 00201 // add sequences in the output vector 00202 BOOST_FOREACH( SeqIdMap::value_type & p, sequences ) 00203 { 00204 if( p.second.size() == 1 ) 00205 { 00206 std::string filename = p.first[0]; 00207 filename += p.second[0].getString(0); 00208 filename += p.first[1]; 00209 //std::cout << "FILENAME = " << filename << std::endl; 00210 outputFiles.push_back( new File( directory, filename, desc ) ); 00211 } 00212 } 00213 00214 return outputFiles; 00215 } 00216 00217 boost::ptr_vector<Sequence> sequenceInDirectory( const std::string& directory, const EMaskOptions desc ) 00218 { 00219 std::vector<std::string> filters; 00220 return sequenceInDirectory( directory, filters, desc ); 00221 } 00222 00223 boost::ptr_vector<Sequence> sequenceInDirectory( const std::string& dir, std::vector<std::string>& filters, const EMaskOptions desc ) 00224 { 00225 boost::ptr_vector<Sequence> outputSequences; 00226 std::string tmpDir( dir ); 00227 std::string filename; 00228 00229 if( !detectDirectoryInResearch( tmpDir, filters, filename ) ) 00230 { 00231 return outputSequences; 00232 } 00233 00234 const std::vector<boost::regex> reFilters = convertFilterToRegex( filters, desc ); 00235 00236 // variables for sequence detection 00237 typedef boost::unordered_map<FileStrings, std::vector<FileNumbers>, SeqIdHash> SeqIdMap; 00238 bfs::path directory( tmpDir ); 00239 SeqIdMap sequences; 00240 FileStrings tmpStringParts; // an object uniquely identify a sequence 00241 FileNumbers tmpNumberParts; // the vector of numbers inside one filename 00242 00243 // for all files in the directory 00244 bfs::directory_iterator itEnd; 00245 for( bfs::directory_iterator iter( directory ); iter != itEnd; ++iter ) 00246 { 00247 // clear previous infos 00248 tmpStringParts.clear(); 00249 tmpNumberParts.clear(); // (clear but don't realloc the vector inside) 00250 00251 if( isNotFilter( iter->path(), reFilters, filename, desc ) ) 00252 { 00253 // it's a file or a file of a sequence 00254 if( filenameIsNotFilter( iter->path().filename().string(), reFilters ) ) // filtering of entries with filters strings 00255 { 00256 // if at least one number detected 00257 if( decomposeFilename( iter->path().filename().string(), tmpStringParts, tmpNumberParts, desc ) ) 00258 { 00259 const SeqIdMap::iterator it( sequences.find( tmpStringParts ) ); 00260 if( it != sequences.end() ) // is already in map 00261 { 00262 // append the vector of numbers 00263 sequences.at( tmpStringParts ).push_back( tmpNumberParts ); 00264 } 00265 else 00266 { 00267 // create an entry in the map 00268 std::vector<FileNumbers> li; 00269 li.push_back( tmpNumberParts ); 00270 sequences.insert( SeqIdMap::value_type( tmpStringParts, li ) ); 00271 } 00272 } 00273 } 00274 } 00275 } 00276 // add sequences in the output vector 00277 00278 BOOST_FOREACH( SeqIdMap::value_type & p, sequences ) 00279 { 00280 const std::vector<Sequence> ss = buildSequences( directory, p.first, p.second, desc ); 00281 00282 BOOST_FOREACH( const std::vector<Sequence>::value_type & s, ss ) 00283 { 00284 // don't detect sequence of directories 00285 if( !bfs::is_directory( s.getAbsoluteFirstFilename() ) ) 00286 { 00287 if( !( s.getNbFiles() == 1 ) ) // if it's a sequence of 1 file, it isn't a sequence but only a file 00288 { 00289 outputSequences.push_back( new Sequence( directory, s, desc ) ); 00290 } 00291 } 00292 } 00293 } 00294 00295 return outputSequences; 00296 } 00297 00298 boost::ptr_vector<Sequence> sequenceFromFilenameList( const std::vector<boost::filesystem::path>& filenames, const EMaskOptions desc ) 00299 { 00300 std::vector<std::string> filters; // @todo as argument ! 00301 boost::ptr_vector<Sequence> outputSequences; 00302 00303 const std::vector<boost::regex> reFilters = convertFilterToRegex( filters, desc ); 00304 00305 // variables for sequence detection 00306 typedef boost::unordered_map<FileStrings, std::vector<FileNumbers>, SeqIdHash> SeqIdMap; 00307 SeqIdMap sequences; 00308 FileStrings tmpStringParts; // an object uniquely identify a sequence 00309 FileNumbers tmpNumberParts; // the vector of numbers inside one filename 00310 00311 // for all files in the directory 00312 00313 BOOST_FOREACH( const boost::filesystem::path& iter, filenames ) 00314 { 00315 // clear previous infos 00316 tmpStringParts.clear(); 00317 tmpNumberParts.clear(); // (clear but don't realloc the vector inside) 00318 00319 if( !( iter.filename().string()[0] == '.' ) || ( desc & eMaskOptionsDotFile ) ) // if we ask to show hidden files and if it is hidden 00320 { 00321 // it's a file or a file of a sequence 00322 if( filenameIsNotFilter( iter.filename().string(), reFilters ) ) // filtering of entries with filters strings 00323 { 00324 // if at least one number detected 00325 if( decomposeFilename( iter.filename().string(), tmpStringParts, tmpNumberParts, desc ) ) 00326 { 00327 const SeqIdMap::iterator it( sequences.find( tmpStringParts ) ); 00328 if( it != sequences.end() ) // is already in map 00329 { 00330 // append the vector of numbers 00331 sequences.at( tmpStringParts ).push_back( tmpNumberParts ); 00332 } 00333 else 00334 { 00335 // create an entry in the map 00336 std::vector<FileNumbers> li; 00337 li.push_back( tmpNumberParts ); 00338 sequences.insert( SeqIdMap::value_type( tmpStringParts, li ) ); 00339 } 00340 } 00341 } 00342 } 00343 } 00344 00345 boost::filesystem::path directory; ///< @todo filter by directories, etc. 00346 00347 // add sequences in the output vector 00348 BOOST_FOREACH( SeqIdMap::value_type & p, sequences ) 00349 { 00350 //std::cout << "FileStrings: " << p.first << std::endl; 00351 const std::vector<Sequence> ss = buildSequences( directory, p.first, p.second, desc ); 00352 00353 BOOST_FOREACH( const std::vector<Sequence>::value_type & s, ss ) 00354 { 00355 // don't detect sequence of directories 00356 if( !bfs::is_directory( s.getAbsoluteFirstFilename() ) ) 00357 { 00358 if( !( s.getNbFiles() == 1 ) ) // if it's a sequence of 1 file, it isn't a sequence but only a file 00359 { 00360 outputSequences.push_back( new Sequence( directory, s, desc ) ); 00361 } 00362 } 00363 } 00364 } 00365 00366 return outputSequences; 00367 } 00368 00369 boost::ptr_vector<FileObject> fileAndSequenceInDirectory( const std::string& directory, const EMaskOptions desc ) 00370 { 00371 std::vector<std::string> filters; 00372 return fileAndSequenceInDirectory( directory, filters, desc ); 00373 } 00374 00375 boost::ptr_vector<FileObject> fileAndSequenceInDirectory( const std::string& dir, std::vector<std::string>& filters, const EMaskOptions desc ) 00376 { 00377 boost::ptr_vector<FileObject> output; 00378 boost::ptr_vector<FileObject> outputFiles; 00379 boost::ptr_vector<FileObject> outputSequences; 00380 std::string tmpDir( dir ); 00381 std::string filename; 00382 00383 if( ! detectDirectoryInResearch( tmpDir, filters, filename ) ) 00384 { 00385 return output; 00386 } 00387 00388 const std::vector<boost::regex> reFilters = convertFilterToRegex( filters, desc ); 00389 00390 // variables for sequence detection 00391 typedef boost::unordered_map<FileStrings, std::vector<FileNumbers>, SeqIdHash> SeqIdMap; 00392 bfs::path directory( tmpDir ); 00393 SeqIdMap sequences; 00394 FileStrings tmpStringParts; // an object uniquely identify a sequence 00395 FileNumbers tmpNumberParts; // the vector of numbers inside one filename 00396 00397 // for all files in the directory 00398 bfs::directory_iterator itEnd; 00399 for( bfs::directory_iterator iter( directory ); iter != itEnd; ++iter ) 00400 { 00401 // clear previous infos 00402 tmpStringParts.clear(); 00403 tmpNumberParts.clear(); // (clear but don't realloc the vector inside) 00404 00405 if( isNotFilter( iter->path(), reFilters, filename, desc ) ) 00406 { 00407 // it's a file or a file of a sequence 00408 if( filenameIsNotFilter( iter->path().filename().string(), reFilters ) ) // filtering of entries with filters strings 00409 { 00410 // if at least one number detected 00411 if( decomposeFilename( iter->path().filename().string(), tmpStringParts, tmpNumberParts, desc ) ) 00412 { 00413 const SeqIdMap::iterator it( sequences.find( tmpStringParts ) ); 00414 if( it != sequences.end() ) // is already in map 00415 { 00416 // append the vector of numbers 00417 sequences.at( tmpStringParts ).push_back( tmpNumberParts ); 00418 } 00419 else 00420 { 00421 // create an entry in the map 00422 std::vector<FileNumbers> li; 00423 li.push_back( tmpNumberParts ); 00424 sequences.insert( SeqIdMap::value_type( tmpStringParts, li ) ); 00425 } 00426 } 00427 else 00428 { 00429 outputFiles.push_back( new File( directory, iter->path().filename().string(), desc ) ); 00430 } 00431 } 00432 } 00433 } 00434 // add sequences in the output vector 00435 00436 BOOST_FOREACH( SeqIdMap::value_type & p, sequences ) 00437 { 00438 if( p.second.size() == 1 ) 00439 { 00440 std::string filename = p.first[0]; 00441 filename += p.second[0].getString(0); 00442 filename += p.first[1]; 00443 //std::cout << "FILENAME = " << filename << std::endl; 00444 outputFiles.push_back( new File( directory, filename, desc ) ); 00445 } 00446 else 00447 { 00448 const std::vector<Sequence> ss = buildSequences( directory, p.first, p.second, desc ); 00449 00450 BOOST_FOREACH( const std::vector<Sequence>::value_type & s, ss ) 00451 { 00452 // don't detect sequence of directories 00453 if( !bfs::is_directory( s.getAbsoluteFirstFilename() ) ) 00454 { 00455 if( s.getNbFiles() == 1 ) // if it's a sequence of 1 file, it isn't a sequence but only a file 00456 { 00457 outputFiles.push_back( new File( directory, s.getFirstFilename(), desc ) ); 00458 } 00459 else 00460 { 00461 outputSequences.push_back( new Sequence( directory, s, desc ) ); 00462 } 00463 } 00464 } 00465 } 00466 } 00467 00468 output.transfer( output.begin(), outputFiles ); 00469 output.transfer( output.begin(), outputSequences ); 00470 return output; 00471 } 00472 00473 boost::ptr_vector<Folder> folderInDirectory( const std::string& directory, const EMaskOptions desc ) 00474 { 00475 std::vector<std::string> filters; 00476 return folderInDirectory( directory, filters, desc ); 00477 } 00478 00479 boost::ptr_vector<Folder> folderInDirectory( const std::string& dir, std::vector<std::string>& filters, const EMaskOptions desc ) 00480 { 00481 boost::ptr_vector<Folder> outputFolders; 00482 bfs::path directory; 00483 std::string filename; // never fill in this case 00484 00485 if( bfs::exists( dir ) ) 00486 { 00487 if( bfs::is_directory( dir ) ) 00488 { 00489 directory = bfs::path( dir ); 00490 } 00491 else 00492 { 00493 return outputFolders; 00494 } 00495 } 00496 else 00497 { 00498 return outputFolders; 00499 } 00500 00501 const std::vector<boost::regex> reFilters = convertFilterToRegex( filters, desc ); 00502 00503 // for all files in the directory 00504 bfs::directory_iterator itEnd; 00505 for( bfs::directory_iterator iter( directory ); iter != itEnd; ++iter ) 00506 { 00507 if( isNotFilter( iter->path(), reFilters, filename, desc ) ) 00508 { 00509 // detect if is a folder 00510 if( bfs::is_directory( iter->status() ) ) 00511 { 00512 outputFolders.push_back( new Folder( directory, iter->path().filename().string(), desc ) ); 00513 } 00514 } 00515 } 00516 return outputFolders; 00517 } 00518 00519 boost::ptr_vector<FileObject> fileObjectInDirectory( const std::string& directory, const EMaskType mask, const EMaskOptions desc ) 00520 { 00521 std::vector<std::string> filters; 00522 return fileObjectInDirectory( directory, filters, mask, desc ); 00523 } 00524 00525 boost::ptr_vector<FileObject> fileObjectInDirectory( const std::string& dir, std::vector<std::string>& filters, const EMaskType mask, const EMaskOptions desc ) 00526 { 00527 boost::ptr_vector<FileObject> output; 00528 boost::ptr_vector<FileObject> outputFolders; 00529 boost::ptr_vector<FileObject> outputFiles; 00530 boost::ptr_vector<FileObject> outputSequences; 00531 std::string tmpDir( dir ); 00532 std::string filename; 00533 00534 if( !detectDirectoryInResearch( tmpDir, filters, filename ) ) 00535 { 00536 return outputFiles; 00537 } 00538 00539 const std::vector<boost::regex> reFilters = convertFilterToRegex( filters, desc ); 00540 00541 // variables for sequence detection 00542 typedef boost::unordered_map<FileStrings, std::vector<FileNumbers>, SeqIdHash> SeqIdMap; 00543 bfs::path directory( tmpDir ); 00544 SeqIdMap sequences; 00545 FileStrings tmpStringParts; // an object uniquely identify a sequence 00546 FileNumbers tmpNumberParts; // the vector of numbers inside one filename 00547 00548 // for all files in the directory 00549 bfs::directory_iterator itEnd; 00550 for( bfs::directory_iterator iter( directory ); iter != itEnd; ++iter ) 00551 { 00552 // clear previous infos 00553 tmpStringParts.clear(); 00554 tmpNumberParts.clear(); // (clear but don't realloc the vector inside) 00555 00556 if( isNotFilter( iter->path(), reFilters, filename, desc ) ) 00557 { 00558 // @todo: no check that needs to ask the status of the file here (like asking if it's a folder). 00559 // detect if is a folder 00560 if( bfs::is_directory( iter->status() ) ) 00561 { 00562 outputFolders.push_back( new Folder( directory, iter->path().filename().string(), desc ) ); 00563 } 00564 else // it's a file or a file of a sequence 00565 { 00566 // if at least one number detected 00567 if( decomposeFilename( iter->path().filename().string(), tmpStringParts, tmpNumberParts, desc ) ) 00568 { 00569 const SeqIdMap::iterator it( sequences.find( tmpStringParts ) ); 00570 if( it != sequences.end() ) // is already in map 00571 { 00572 // append the vector of numbers 00573 sequences.at( tmpStringParts ).push_back( tmpNumberParts ); 00574 } 00575 else 00576 { 00577 // create an entry in the map 00578 std::vector<FileNumbers> li; 00579 li.push_back( tmpNumberParts ); 00580 sequences.insert( SeqIdMap::value_type( tmpStringParts, li ) ); 00581 } 00582 } 00583 else 00584 { 00585 outputFiles.push_back( new File( directory, iter->path().filename().string(), desc ) ); 00586 } 00587 } 00588 } 00589 } 00590 // add sequences in the output vector 00591 00592 BOOST_FOREACH( SeqIdMap::value_type & p, sequences ) 00593 { 00594 if( p.second.size() == 1 ) 00595 { 00596 std::string filename = p.first.getId().at( 0 ); 00597 for( size_t i = 0; i < p.second[ 0 ].size(); i++ ) 00598 { 00599 filename += p.second[ 0 ].getString( i ); 00600 filename += p.first.getId().at( i+1 ); 00601 } 00602 //std::cout << "FILENAME = " << filename << std::endl; 00603 outputFiles.push_back( new File( directory, filename, desc ) ); 00604 } 00605 else 00606 { 00607 const std::vector<Sequence> ss = buildSequences( directory, p.first, p.second, desc ); 00608 00609 BOOST_FOREACH( const std::vector<Sequence>::value_type & s, ss ) 00610 { 00611 // don't detect sequence of directories 00612 if( !bfs::is_directory( s.getAbsoluteFirstFilename() ) ) 00613 { 00614 if( s.getNbFiles() == 1 ) // if it's a sequence of 1 file, it isn't a sequence but only a file 00615 { 00616 outputFiles.push_back( new File( directory, s.getFirstFilename(), desc ) ); 00617 } 00618 else 00619 { 00620 outputSequences.push_back( new Sequence( directory, s, desc ) ); 00621 } 00622 } 00623 // else 00624 // { 00625 // @todo loop to declare direcotries ! 00626 // } 00627 } 00628 } 00629 } 00630 00631 if( mask & eMaskTypeDirectory ) 00632 { 00633 output.transfer( output.end(), outputFolders ); 00634 } 00635 // add files in the output vector 00636 if( mask & eMaskTypeFile ) 00637 { 00638 output.transfer( output.end(), outputFiles ); 00639 } 00640 // add sequences in the output vector 00641 if( mask & eMaskTypeSequence ) 00642 { 00643 output.transfer( output.end(), outputSequences ); 00644 } 00645 return output; 00646 } 00647 00648 }