1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/fileutils.h"
12 
13 #include "rtc_base/arraysize.h"
14 #include "rtc_base/checks.h"
15 #include "rtc_base/pathutils.h"
16 #include "rtc_base/stringutils.h"
17 
18 #if defined(WEBRTC_WIN)
19 #include "rtc_base/win32filesystem.h"
20 #else
21 #include "rtc_base/unixfilesystem.h"
22 #endif
23 
24 #if !defined(WEBRTC_WIN)
25 #define MAX_PATH 260
26 #endif
27 
28 namespace rtc {
29 
30 //////////////////////////
31 // Directory Iterator   //
32 //////////////////////////
33 
34 // A DirectoryIterator is created with a given directory. It originally points
35 // to the first file in the directory, and can be advanecd with Next(). This
36 // allows you to get information about each file.
37 
38   // Constructor
DirectoryIterator()39 DirectoryIterator::DirectoryIterator()
40 #ifdef WEBRTC_WIN
41     : handle_(INVALID_HANDLE_VALUE) {
42 #else
43     : dir_(nullptr),
44       dirent_(nullptr){
45 #endif
46 }
47 
48   // Destructor
49 DirectoryIterator::~DirectoryIterator() {
50 #if defined(WEBRTC_WIN)
51   if (handle_ != INVALID_HANDLE_VALUE)
52     ::FindClose(handle_);
53 #else
54   if (dir_)
55     closedir(dir_);
56 #endif
57 }
58 
59   // Starts traversing a directory.
60   // dir is the directory to traverse
61   // returns true if the directory exists and is valid
62 bool DirectoryIterator::Iterate(const Pathname &dir) {
63   directory_ = dir.pathname();
64 #if defined(WEBRTC_WIN)
65   if (handle_ != INVALID_HANDLE_VALUE)
66     ::FindClose(handle_);
67   std::string d = dir.pathname() + '*';
68   handle_ = ::FindFirstFile(ToUtf16(d).c_str(), &data_);
69   if (handle_ == INVALID_HANDLE_VALUE)
70     return false;
71 #else
72   if (dir_ != nullptr)
73     closedir(dir_);
74   dir_ = ::opendir(directory_.c_str());
75   if (dir_ == nullptr)
76     return false;
77   dirent_ = readdir(dir_);
78   if (dirent_ == nullptr)
79     return false;
80 
81   if (::stat(std::string(directory_ + Name()).c_str(), &stat_) != 0)
82     return false;
83 #endif
84   return true;
85 }
86 
87   // Advances to the next file
88   // returns true if there were more files in the directory.
89 bool DirectoryIterator::Next() {
90 #if defined(WEBRTC_WIN)
91   return ::FindNextFile(handle_, &data_) == TRUE;
92 #else
93   dirent_ = ::readdir(dir_);
94   if (dirent_ == nullptr)
95     return false;
96 
97   return ::stat(std::string(directory_ + Name()).c_str(), &stat_) == 0;
98 #endif
99 }
100 
101   // returns true if the file currently pointed to is a directory
102 bool DirectoryIterator::IsDirectory() const {
103 #if defined(WEBRTC_WIN)
104   return (data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FALSE;
105 #else
106   return S_ISDIR(stat_.st_mode);
107 #endif
108 }
109 
110   // returns the name of the file currently pointed to
111 std::string DirectoryIterator::Name() const {
112 #if defined(WEBRTC_WIN)
113   return ToUtf8(data_.cFileName);
114 #else
115   RTC_DCHECK(dirent_);
116   return dirent_->d_name;
117 #endif
118 }
119 
120 FilesystemInterface* Filesystem::default_filesystem_ = nullptr;
121 
122 FilesystemInterface *Filesystem::EnsureDefaultFilesystem() {
123   if (!default_filesystem_) {
124 #if defined(WEBRTC_WIN)
125     default_filesystem_ = new Win32Filesystem();
126 #else
127     default_filesystem_ = new UnixFilesystem();
128 #endif
129   }
130   return default_filesystem_;
131 }
132 
133 }  // namespace rtc
134