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
DIR__anondd4895ca0111::DIR67         DIR() { }
~DIR__anondd4895ca0111::DIR68         ~DIR()
69         {
70             if (ent.d_name)
71                 delete[] ent.d_name;
72         }
73 #endif
74     };
75 
opendir(const char * path)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 
readdir(DIR * dir)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 
closedir(DIR * dir)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 
isDir(const cv::String & path,DIR * dir)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 
wildcmp(const char * string,const char * wild)172 static bool wildcmp(const char *string, const char *wild)
173 {
174     // Based on wildcmp written by Jack Handy - <A href="mailto:jakkhandy@hotmail.com">jakkhandy@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 
glob_rec(const cv::String & directory,const cv::String & wildchart,std::vector<cv::String> & result,bool recursive)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 
glob(String pattern,std::vector<String> & result,bool recursive)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