Go to the documentation of this file.00001
00019 #ifndef COIL_FILE_H
00020 #define COIL_FILE_H
00021
00022 #include <windows.h>
00023 #include <coil/config_coil.h>
00024 #include <coil/stringutil.h>
00025
00026 namespace coil
00027 {
00028 const unsigned int MaxPathLength(1024);
00029
00056 inline std::string dirname(char* path)
00057 {
00058 char return_dirname[MaxPathLength + 1];
00059
00060 size_t len = strlen(path);
00061 if (len > (sizeof(return_dirname) / sizeof(char)))
00062 {
00063 len = sizeof(return_dirname) / sizeof(char);
00064 }
00065 std::strncpy(return_dirname, path, len);
00066 return_dirname[len] = '\0';
00067
00068 const char delimiter('/');
00069 char *p = std::strrchr(return_dirname, delimiter);
00070
00071 std::string dir_name;
00072 if (p)
00073 {
00074 if(p != return_dirname)
00075 {
00076 if(*(p+1) == '\0')
00077 {
00078 *p = '\0';
00079 dir_name = dirname(return_dirname);
00080 }
00081 else
00082 {
00083 *p = '\0';
00084 dir_name = return_dirname;
00085 }
00086 }
00087 else
00088 {
00089 *(p+1) = '\0';
00090 dir_name = return_dirname;
00091 }
00092 }
00093 else
00094 {
00095 dir_name = ".";
00096 }
00097 return dir_name;
00098 }
00099
00123 inline std::string basename(const char* path)
00124 {
00125 char p[MaxPathLength + 1];
00126
00127 size_t len = strlen(path);
00128 if (len > (sizeof(p) / sizeof(char)))
00129 {
00130 len = sizeof(p) / sizeof(char);
00131 }
00132 std::strncpy(p, path, len);
00133 p[len] = '\0';
00134
00135 const char delimiter('/');
00136 char *pdelimiter = std::strrchr(p, delimiter);
00137
00138 std::string base_name(p);
00139 if (pdelimiter)
00140 {
00141 if(pdelimiter != p)
00142 {
00143 if(*(pdelimiter+1) == '\0')
00144 {
00145 *pdelimiter = '\0';
00146 base_name = basename(p);
00147 }
00148 else
00149 {
00150 pdelimiter++;
00151 base_name = pdelimiter;
00152 }
00153 }
00154 else
00155 {
00156 if(*(pdelimiter+1) != '\0')
00157 {
00158 pdelimiter++;
00159 base_name = pdelimiter;
00160 }
00161 else
00162 {
00163 base_name = pdelimiter;
00164 }
00165
00166 }
00167 }
00168 return base_name;
00169 }
00170
00171
00172
00173 typedef unsigned int ino_t;
00174
00186 struct dirent
00187 {
00188 ino_t d_ino;
00189 char d_name[_MAX_PATH];
00190 };
00191
00203 typedef struct
00204 {
00205 HANDLE h;
00206 WIN32_FIND_DATAA *fd;
00207 BOOL has_next;
00208 struct dirent entry;
00209 } DIR;
00210
00211
00235 DIR* opendir(const char *name)
00236 {
00237 if (name == 0) { return 0; }
00238 std::string path(name);
00239 if (path.empty()) { return 0; }
00240
00241
00242 if (*(path.end() - 1) != '\\' && *(path.end() - 1) != '/')
00243 {
00244 std::string::size_type pos(path.find("/"));
00245 if (pos == std::string::npos) { path.push_back('\\'); }
00246 else { path.push_back('/'); }
00247 }
00248 path.push_back('*');
00249
00250
00251 HANDLE dhandle;
00252 WIN32_FIND_DATAA* fd;
00253 try
00254 {
00255 fd = new WIN32_FIND_DATAA();
00256 dhandle = FindFirstFileA(path.c_str(), fd);
00257 if (dhandle == INVALID_HANDLE_VALUE) { delete fd; return 0; }
00258
00259 }
00260 catch (...)
00261 {
00262 FindClose(dhandle);
00263 return 0;
00264 }
00265
00266 DIR* dir;
00267 try
00268 {
00269 dir = new DIR();
00270 dir->h = dhandle;
00271 dir->fd = fd;
00272 dir->has_next = TRUE;
00273 }
00274 catch (...)
00275 {
00276 delete fd;
00277 return 0;
00278 }
00279 return dir;
00280 }
00281
00282
00306 dirent* readdir(DIR *dir)
00307 {
00308 if (dir == 0) { return 0; }
00309 if (dir->fd == 0) { return 0;}
00310 if (!dir->has_next) { return 0; }
00311
00312 strcpy_s(dir->entry.d_name, _MAX_PATH, dir->fd->cFileName);
00313 dir->has_next = FindNextFileA(dir->h, dir->fd);
00314
00315 return &dir->entry;
00316 }
00317
00341 int closedir(DIR *dir)
00342 {
00343 if (dir == 0) { return -1; }
00344 if (dir->h != 0 && dir->h != INVALID_HANDLE_VALUE)
00345 {
00346 FindClose(dir->h);
00347 }
00348 if (dir->fd != 0) { delete dir->fd; }
00349 delete dir;
00350
00351 return 0;
00352 }
00353
00354
00355
00381 inline coil::vstring filelist(const char* path, const char* glob_str = "")
00382 {
00383 struct dirent* ent;
00384 coil::vstring flist;
00385 bool has_glob(false);
00386 std::string pattern;
00387
00388 if (path == 0) { return flist; }
00389 if (glob_str[0] != '\0') { has_glob = true; }
00390
00391 DIR* dir_ptr(coil::opendir(path));
00392 if (dir_ptr == 0) { return flist; }
00393
00394 while ((ent = coil::readdir(dir_ptr)) != 0)
00395 {
00396 bool match(true);
00397 if (has_glob)
00398 {
00399 const char* globc(glob_str);
00400 std::string fname(ent->d_name);
00401 for (size_t i(0); i < fname.size() && globc != '\0'; ++i, ++globc)
00402 {
00403 if (*globc == '*')
00404 {
00405
00406 if (globc[1] == '\0') { break; }
00407
00408 if (globc[1] == '*' || globc[1] == '+') { --i; continue; }
00409
00410
00411 ++globc;
00412 size_t pos(fname.find(*globc, i));
00413 if (pos == std::string::npos) { match = false; break; }
00414
00415 i = pos;
00416 }
00417 else if (*globc == '+')
00418 {
00419
00420 if (globc[1] == '\0' && !(i + 1 < fname.size())) { break; }
00421
00422 if (globc[1] == '*' || globc[1] == '+') { --i; continue; }
00423
00424
00425 ++globc;
00426 size_t pos(fname.find(*globc, i + 1));
00427 if (pos == std::string::npos) { match = false; break; }
00428
00429 i = pos;
00430 }
00431 else
00432 {
00433 if (fname[i] != *globc) { match = false; }
00434 }
00435
00436
00437
00438 if (i + 1 == fname.size() &&
00439 globc[1] != '\0' && globc[1] != '*') { match = false; }
00440 }
00441 }
00442 if (match) { flist.push_back(ent->d_name); }
00443 }
00444 coil::closedir(dir_ptr);
00445
00446 return flist;
00447 }
00448
00449
00450 };
00451
00452 #endif // COIL_FILE_H