posix_dir_files.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // $Id$
  3. //
  4. #include<__vic/posix/dir_files.h>
  5. #include<__vic/posix/file_stat.h>
  6. #include<fnmatch.h>
  7. namespace __vic { namespace posix {
  8. //----------------------------------------------------------------------------
  9. dir_files::dir_files()
  10. {
  11. }
  12. //----------------------------------------------------------------------------
  13. dir_files::dir_files(const char *path, const char *patt)
  14. : de(path), dir(path)
  15. {
  16. if(patt) pattern = patt;
  17. }
  18. //----------------------------------------------------------------------------
  19. dir_files::~dir_files()
  20. {
  21. }
  22. //----------------------------------------------------------------------------
  23. #if __cpp_rvalue_references
  24. //----------------------------------------------------------------------------
  25. dir_files::dir_files(dir_files &&o) noexcept
  26. :
  27. de(std::move(o.de)),
  28. dir(std::move(o.dir)),
  29. pattern(std::move(o.pattern))
  30. {
  31. }
  32. //----------------------------------------------------------------------------
  33. dir_files &dir_files::operator=(dir_files &&o) noexcept
  34. {
  35. if(&o != this)
  36. {
  37. de = std::move(o.de);
  38. dir = std::move(o.dir);
  39. pattern = std::move(o.pattern);
  40. }
  41. return *this;
  42. }
  43. //----------------------------------------------------------------------------
  44. #endif
  45. //----------------------------------------------------------------------------
  46. bool dir_files::reopen(const char *path, const char *patt)
  47. {
  48. if(!de.reopen(path)) return false;
  49. dir = path;
  50. if(patt) pattern = patt; else pattern.clear();
  51. return true;
  52. }
  53. //----------------------------------------------------------------------------
  54. const char *dir_files::next()
  55. {
  56. while(const char *entry = de.next())
  57. {
  58. if(pattern.empty() || ::fnmatch(pattern.c_str(), entry, 0) == 0)
  59. {
  60. // is it a regular file?
  61. #ifdef _DIRENT_HAVE_D_TYPE
  62. switch(de.type())
  63. {
  64. case DT_REG: return entry;
  65. case DT_UNKNOWN: break; // can't detect - use stat()
  66. default: continue;
  67. }
  68. #endif
  69. tmp.clear() << dir << '/' << entry;
  70. file_stat s;
  71. if(s.get_if_exists(tmp) && s.is_regular()) return entry;
  72. // ignore disappeared entries
  73. }
  74. }
  75. return 0;
  76. }
  77. //----------------------------------------------------------------------------
  78. }} // namespace