file_util.cpp
Go to the documentation of this file.
00001 // *****************************************************************************
00002 //
00003 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //     * Redistributions of source code must retain the above copyright
00009 //       notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above copyright
00011 //       notice, this list of conditions and the following disclaimer in the
00012 //       documentation and/or other materials provided with the distribution.
00013 //     * Neither the name of Southwest Research Institute® (SwRI®) nor the
00014 //       names of its contributors may be used to endorse or promote products
00015 //       derived from this software without specific prior written permission.
00016 //
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //
00028 // *****************************************************************************
00029 
00030 #include <swri_system_util/file_util.h>
00031 
00032 #include <string>
00033 
00034 #include <boost/regex.hpp>
00035 
00036 namespace swri_system_util
00037 {
00038   boost::filesystem::path NaiveUncomplete(
00039     boost::filesystem::path const path,
00040     boost::filesystem::path const base)
00041   {
00042     // This implementation was derived from:
00043     //   https://svn.boost.org/trac/boost/ticket/1976#comment:2
00044 
00045     // Cache system-dependent dot, double-dot and slash strings
00046 
00047     #if BOOST_FILESYSTEM_VERSION == 3
00048     const boost::filesystem::path _dot = boost::filesystem::path(".").native();
00049     const boost::filesystem::path _dot_sep = boost::filesystem::path("./").native();
00050     const boost::filesystem::path _dots = boost::filesystem::path("..").native();
00051     const boost::filesystem::path _dots_sep = boost::filesystem::path("../").native();
00052     const boost::filesystem::path _sep = boost::filesystem::path("/").native();
00053     #else
00054     const boost::filesystem::path _dot = std::string(1, boost::filesystem::dot<boost::filesystem::path>::value);
00055     const boost::filesystem::path _sep = std::string(1, boost::filesystem::slash<boost::filesystem::path>::value);
00056     const boost::filesystem::path _dot_sep = _dot.string() + _sep.string();
00057     const boost::filesystem::path _dots = std::string(2, boost::filesystem::dot<boost::filesystem::path>::value);
00058     const boost::filesystem::path _dots_sep = _dots.string() + _sep.string();
00059     #endif  // BOOST_FILESYSTE_VERSION == 3
00060 
00061     if (path == base) return _dot_sep;
00062 
00063     boost::filesystem::path from_path;
00064     boost::filesystem::path from_base;
00065     boost::filesystem::path output;
00066 
00067     boost::filesystem::path::iterator path_it = path.begin();
00068     boost::filesystem::path::iterator base_it = base.begin();
00069 
00070     if ((path_it == path.end()) || (base_it == base.end()))
00071     {
00072       return "";
00073     }
00074 
00075     while (true)
00076     {
00077       if (*path_it != *base_it)
00078       {
00079         for (; base_it != base.end(); ++base_it)
00080         {
00081           if (*base_it == _dot)
00082             continue;
00083           else if (*base_it == _sep)
00084             continue;
00085           output /= _dots_sep;
00086         }
00087 
00088         boost::filesystem::path::iterator path_it_start = path_it;
00089         for (; path_it != path.end(); ++path_it)
00090         {
00091           if (path_it != path_it_start)
00092             output /= _sep;
00093 
00094           if (*path_it == _dot)
00095             continue;
00096 
00097           if (*path_it == _sep)
00098             continue;
00099 
00100           output /= *path_it;
00101         }
00102         break;
00103       }
00104 
00105       from_path /= boost::filesystem::path(*path_it);
00106       from_base /= boost::filesystem::path(*base_it);
00107 
00108       ++path_it, ++base_it;
00109     }
00110 
00111     return output;
00112   }
00113 
00114   std::vector<std::string> load_all_files(const std::string& path, std::string& directory)
00115   {
00116     std::vector< std::string > all_matching_files;
00117     // Extract the directory from the path
00118     std::string direct = path.substr(0, path.find_last_of("/\\"));
00119     // Extract the filename from the path
00120     std::string filename = path.substr(path.find_last_of("/\\")+1);
00121     boost::filesystem::path p(direct);
00122     if ( !exists( p ) )
00123     {
00124       printf("Path %s does not exists\n", p.string().c_str());
00125       return all_matching_files;
00126     }
00127     const boost::regex my_filter(filename.replace(filename.find("*"), std::string("*").length(), ".*\\") );
00128 
00129     boost::filesystem::directory_iterator end_itr; // Default construction yields past-the-end
00130     for( boost::filesystem::directory_iterator i( p ); i != end_itr; ++i )
00131     {
00132       // Skip if not a file
00133       // if( !boost::filesystem::is_regular_file( i->status() ) ) continue;
00134 
00135       //It it is a directory then search within
00136       if ( boost::filesystem::is_directory(i->status()) )
00137       {
00138         std::string path2 = i->path().string() + std::string("/") + path.substr(path.find_last_of("/\\")+1);
00139         std::string directory2;
00140         std::vector<std::string> matching_files = load_all_files( path2, directory2 );
00141         all_matching_files.insert(all_matching_files.end(), matching_files.begin(), matching_files.end());
00142       }
00143       else if (boost::filesystem::is_regular_file( i->status())) // Check if a file
00144       {
00145         boost::smatch what;
00146         // Skip if no match
00147         #if BOOST_FILESYSTEM_VERSION == 3
00148         if( !boost::regex_match( i->path().filename().string(), what, my_filter ) ) continue;
00149         #else
00150         if( !boost::regex_match( i->leaf(), what, my_filter ) ) continue;
00151         #endif  // BOOST_FILESYSTE_VERSION == 3
00152 
00153         // File matches, store it
00154         all_matching_files.push_back( i->path().string() );
00155       }
00156       std::sort(all_matching_files.begin(), all_matching_files.end());
00157     }
00158     directory = direct;
00159     return all_matching_files;
00160   }
00161 
00162   std::vector<std::string> Find(
00163       const std::string& path,
00164       const std::string& expression,
00165       int max_depth)
00166   {
00167     std::vector<std::string> files;
00168 
00169     boost::filesystem::path root(path);
00170     if(!boost::filesystem::exists(root) || !boost::filesystem::is_directory(root))
00171     {
00172       return files;
00173     }
00174 
00175     boost::regex filter(expression);
00176     boost::filesystem::recursive_directory_iterator it(root);
00177     boost::filesystem::recursive_directory_iterator end_it;
00178     while (it != end_it)
00179     {
00180       if (max_depth >= 0 && it.level() >= max_depth)
00181       {
00182         it.no_push();
00183       }
00184 
00185       boost::smatch what;
00186       std::string filename = it->path().filename().string();
00187       if (boost::regex_match(filename, what, filter))
00188       {
00189         files.push_back(it->path().string());
00190       }
00191 
00192       ++it;
00193     }
00194 
00195     return files;
00196   }
00197 }


swri_system_util
Author(s): Marc Alban
autogenerated on Thu Jun 6 2019 20:34:59