Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                           License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2008-2013, Willow Garage Inc., all rights reserved.
     15 // Third party copyrights are property of their respective owners.
     16 //
     17 // Redistribution and use in source and binary forms, with or without modification,
     18 // are permitted provided that the following conditions are met:
     19 //
     20 //   * Redistribution's of source code must retain the above copyright notice,
     21 //     this list of conditions and the following disclaimer.
     22 //
     23 //   * Redistribution's in binary form must reproduce the above copyright notice,
     24 //     this list of conditions and the following disclaimer in the documentation
     25 //     and / or other materials provided with the distribution.
     26 //
     27 //   * The name of the copyright holders may not be used to endorse or promote products
     28 //     derived from this software without specific prior written permission.
     29 //
     30 // This software is provided by the copyright holders and contributors "as is" and
     31 // any express or implied warranties, including, but not limited to, the implied
     32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     33 // In no event shall the Intel Corporation or contributors be liable for any direct,
     34 // indirect, incidental, special, exemplary, or consequential damages
     35 // (including, but not limited to, procurement of substitute goods or services;
     36 // loss of use, data, or profits; or business interruption) however caused
     37 // and on any theory of liability, whether in contract, strict liability,
     38 // or tort (including negligence or otherwise) arising in any way out of
     39 // the use of this software, even if advised of the possibility of such damage.
     40 //
     41 //M*/
     42 
     43 #include "precomp.hpp"
     44 
     45 #if defined WIN32 || defined _WIN32 || defined WINCE
     46 # include <windows.h>
     47 const char dir_separators[] = "/\\";
     48 const char native_separator = '\\';
     49 
     50 namespace
     51 {
     52     struct dirent
     53     {
     54         const char* d_name;
     55     };
     56 
     57     struct DIR
     58     {
     59 #ifdef WINRT
     60         WIN32_FIND_DATAW data;
     61 #else
     62         WIN32_FIND_DATA data;
     63 #endif
     64         HANDLE handle;
     65         dirent ent;
     66 #ifdef WINRT
     67         DIR() { }
     68         ~DIR()
     69         {
     70             if (ent.d_name)
     71                 delete[] ent.d_name;
     72         }
     73 #endif
     74     };
     75 
     76     DIR* opendir(const char* path)
     77     {
     78         DIR* dir = new DIR;
     79         dir->ent.d_name = 0;
     80 #ifdef WINRT
     81         cv::String full_path = cv::String(path) + "\\*";
     82         wchar_t wfull_path[MAX_PATH];
     83         size_t copied = mbstowcs(wfull_path, full_path.c_str(), MAX_PATH);
     84         CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
     85         dir->handle = ::FindFirstFileExW(wfull_path, FindExInfoStandard,
     86                         &dir->data, FindExSearchNameMatch, NULL, 0);
     87 #else
     88         dir->handle = ::FindFirstFileExA((cv::String(path) + "\\*").c_str(),
     89             FindExInfoStandard, &dir->data, FindExSearchNameMatch, NULL, 0);
     90 #endif
     91         if(dir->handle == INVALID_HANDLE_VALUE)
     92         {
     93             /*closedir will do all cleanup*/
     94             delete dir;
     95             return 0;
     96         }
     97         return dir;
     98     }
     99 
    100     dirent* readdir(DIR* dir)
    101     {
    102 #ifdef WINRT
    103         if (dir->ent.d_name != 0)
    104         {
    105             if (::FindNextFileW(dir->handle, &dir->data) != TRUE)
    106                 return 0;
    107         }
    108         size_t asize = wcstombs(NULL, dir->data.cFileName, 0);
    109         CV_Assert((asize != 0) && (asize != (size_t)-1));
    110         char* aname = new char[asize+1];
    111         aname[asize] = 0;
    112         wcstombs(aname, dir->data.cFileName, asize);
    113         dir->ent.d_name = aname;
    114 #else
    115         if (dir->ent.d_name != 0)
    116         {
    117             if (::FindNextFileA(dir->handle, &dir->data) != TRUE)
    118                 return 0;
    119         }
    120         dir->ent.d_name = dir->data.cFileName;
    121 #endif
    122         return &dir->ent;
    123     }
    124 
    125     void closedir(DIR* dir)
    126     {
    127         ::FindClose(dir->handle);
    128         delete dir;
    129     }
    130 
    131 
    132 }
    133 #else
    134 # include <dirent.h>
    135 # include <sys/stat.h>
    136 const char dir_separators[] = "/";
    137 const char native_separator = '/';
    138 #endif
    139 
    140 static bool isDir(const cv::String& path, DIR* dir)
    141 {
    142 #if defined WIN32 || defined _WIN32 || defined WINCE
    143     DWORD attributes;
    144     BOOL status = TRUE;
    145     if (dir)
    146         attributes = dir->data.dwFileAttributes;
    147     else
    148     {
    149         WIN32_FILE_ATTRIBUTE_DATA all_attrs;
    150 #ifdef WINRT
    151         wchar_t wpath[MAX_PATH];
    152         size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
    153         CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
    154         status = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs);
    155 #else
    156         status = ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs);
    157 #endif
    158         attributes = all_attrs.dwFileAttributes;
    159     }
    160 
    161     return status && ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
    162 #else
    163     (void)dir;
    164     struct stat stat_buf;
    165     if (0 != stat( path.c_str(), &stat_buf))
    166         return false;
    167     int is_dir = S_ISDIR( stat_buf.st_mode);
    168     return is_dir != 0;
    169 #endif
    170 }
    171 
    172 static bool wildcmp(const char *string, const char *wild)
    173 {
    174     // Based on wildcmp written by Jack Handy - <A href="mailto:jakkhandy (at) hotmail.com">jakkhandy (at) hotmail.com</A>
    175     const char *cp = 0, *mp = 0;
    176 
    177     while ((*string) && (*wild != '*'))
    178     {
    179         if ((*wild != *string) && (*wild != '?'))
    180         {
    181             return false;
    182         }
    183 
    184         wild++;
    185         string++;
    186     }
    187 
    188     while (*string)
    189     {
    190         if (*wild == '*')
    191         {
    192             if (!*++wild)
    193             {
    194                 return true;
    195             }
    196 
    197             mp = wild;
    198             cp = string + 1;
    199         }
    200         else if ((*wild == *string) || (*wild == '?'))
    201         {
    202             wild++;
    203             string++;
    204         }
    205         else
    206         {
    207             wild = mp;
    208             string = cp++;
    209         }
    210     }
    211 
    212     while (*wild == '*')
    213     {
    214         wild++;
    215     }
    216 
    217     return *wild == 0;
    218 }
    219 
    220 static void glob_rec(const cv::String& directory, const cv::String& wildchart, std::vector<cv::String>& result, bool recursive)
    221 {
    222     DIR *dir;
    223     struct dirent *ent;
    224 
    225     if ((dir = opendir (directory.c_str())) != 0)
    226     {
    227         /* find all the files and directories within directory */
    228         try
    229         {
    230             while ((ent = readdir (dir)) != 0)
    231             {
    232                 const char* name = ent->d_name;
    233                 if((name[0] == 0) || (name[0] == '.' && name[1] == 0) || (name[0] == '.' && name[1] == '.' && name[2] == 0))
    234                     continue;
    235 
    236                 cv::String path = directory + native_separator + name;
    237 
    238                 if (isDir(path, dir))
    239                 {
    240                     if (recursive)
    241                         glob_rec(path, wildchart, result, recursive);
    242                 }
    243                 else
    244                 {
    245                     if (wildchart.empty() || wildcmp(name, wildchart.c_str()))
    246                         result.push_back(path);
    247                 }
    248             }
    249         }
    250         catch (...)
    251         {
    252             closedir(dir);
    253             throw;
    254         }
    255         closedir(dir);
    256     }
    257     else CV_Error(CV_StsObjectNotFound, cv::format("could not open directory: %s", directory.c_str()));
    258 }
    259 
    260 void cv::glob(String pattern, std::vector<String>& result, bool recursive)
    261 {
    262     result.clear();
    263     String path, wildchart;
    264 
    265     if (isDir(pattern, 0))
    266     {
    267         if(strchr(dir_separators, pattern[pattern.size() - 1]) != 0)
    268         {
    269             path = pattern.substr(0, pattern.size() - 1);
    270         }
    271         else
    272         {
    273             path = pattern;
    274         }
    275     }
    276     else
    277     {
    278         size_t pos = pattern.find_last_of(dir_separators);
    279         if (pos == String::npos)
    280         {
    281             wildchart = pattern;
    282             path = ".";
    283         }
    284         else
    285         {
    286             path = pattern.substr(0, pos);
    287             wildchart = pattern.substr(pos + 1);
    288         }
    289     }
    290 
    291     glob_rec(path, wildchart, result, recursive);
    292     std::sort(result.begin(), result.end());
    293 }
    294