File.h
Go to the documentation of this file.
00001 // -*- C++ -*-
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     // path has at least one or more path characters
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('\\'); } // delim = '\'
00246         else                          { path.push_back('/');  } // delim = '/'
00247       }
00248     path.push_back('*'); // now path is "/dir/dir/../*"
00249 
00250     // fd will be held by DIR structure
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                     // the last '*' matches every thing
00406                     if (globc[1] == '\0') { break; }
00407                     // consecutive * or + are skiped, but fname keeps pointer
00408                     if (globc[1] == '*' || globc[1] == '+') { --i; continue; }
00409 
00410                     // advance pointer and find normal characters
00411                     ++globc;
00412                     size_t pos(fname.find(*globc, i));
00413                     if (pos == std::string::npos) { match = false; break; }
00414                     // matched, and advance i to pos
00415                     i = pos;
00416                   }
00417                 else if (*globc == '+')
00418                   {
00419                     // the last '+' matches last one or more characters
00420                     if (globc[1] == '\0' && !(i + 1 < fname.size())) { break; }
00421                     // consecutive * or + are skiped, but fname keeps pointer
00422                     if (globc[1] == '*' || globc[1] == '+') { --i; continue; }
00423 
00424                     // advance pointer and find normal characters
00425                     ++globc;
00426                     size_t pos(fname.find(*globc, i + 1));
00427                     if (pos == std::string::npos) { match = false; break; }
00428                     // matched, and advance i to pos
00429                     i = pos;
00430                   }
00431                 else
00432                   {
00433                     if (fname[i] != *globc) { match = false; }
00434                   }
00435                 
00436                 // in the last fname character, if glob is not end,
00437                 // or *, fname is not matched.
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


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Aug 27 2015 14:16:37