/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "test/testsupport/file_utils.h" #include #if defined(WEBRTC_POSIX) #include #endif #if defined(WEBRTC_WIN) #include #include #include #include #include #include #include "Shlwapi.h" #include "WinDef.h" #include "rtc_base/win32.h" #define GET_CURRENT_DIR _getcwd #else #include #define GET_CURRENT_DIR getcwd #endif #include // To check for directory existence. #ifndef S_ISDIR // Not defined in stat.h on Windows. #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) #endif #include #include #include #include #include #if defined(WEBRTC_IOS) #include "test/testsupport/ios_file_utils.h" #elif defined(WEBRTC_MAC) #include "test/testsupport/mac_file_utils.h" #endif #include "rtc_base/checks.h" #include "rtc_base/string_utils.h" #include "test/testsupport/file_utils_override.h" namespace webrtc { namespace test { #if defined(WEBRTC_WIN) const char* kPathDelimiter = "\\"; #else const char* kPathDelimiter = "/"; #endif std::string DirName(const std::string& path) { if (path.empty()) return ""; if (path == kPathDelimiter) return path; std::string result = path; if (result.back() == *kPathDelimiter) result.pop_back(); // Remove trailing separator. return result.substr(0, result.find_last_of(kPathDelimiter)); } bool FileExists(const std::string& file_name) { struct stat file_info = {0}; return stat(file_name.c_str(), &file_info) == 0; } bool DirExists(const std::string& directory_name) { struct stat directory_info = {0}; return stat(directory_name.c_str(), &directory_info) == 0 && S_ISDIR(directory_info.st_mode); } std::string OutputPath() { return webrtc::test::internal::OutputPath(); } std::string WorkingDir() { return webrtc::test::internal::WorkingDir(); } // Generate a temporary filename in a safe way. // Largely copied from talk/base/{unixfilesystem,win32filesystem}.cc. std::string TempFilename(const std::string& dir, const std::string& prefix) { #ifdef WIN32 wchar_t filename[MAX_PATH]; if (::GetTempFileNameW(rtc::ToUtf16(dir).c_str(), rtc::ToUtf16(prefix).c_str(), 0, filename) != 0) return rtc::ToUtf8(filename); assert(false); return ""; #else int len = dir.size() + prefix.size() + 2 + 6; std::unique_ptr tempname(new char[len]); snprintf(tempname.get(), len, "%s/%sXXXXXX", dir.c_str(), prefix.c_str()); int fd = ::mkstemp(tempname.get()); if (fd == -1) { assert(false); return ""; } else { ::close(fd); } std::string ret(tempname.get()); return ret; #endif } std::string GenerateTempFilename(const std::string& dir, const std::string& prefix) { std::string filename = TempFilename(dir, prefix); RemoveFile(filename); return filename; } absl::optional> ReadDirectory(std::string path) { if (path.length() == 0) return absl::optional>(); #if defined(WEBRTC_WIN) // Append separator character if needed. if (path.back() != '\\') path += '\\'; // Init. WIN32_FIND_DATAW data; HANDLE handle = ::FindFirstFileW(rtc::ToUtf16(path + '*').c_str(), &data); if (handle == INVALID_HANDLE_VALUE) return absl::optional>(); // Populate output. std::vector found_entries; do { const std::string name = rtc::ToUtf8(data.cFileName); if (name != "." && name != "..") found_entries.emplace_back(path + name); } while (::FindNextFileW(handle, &data) == TRUE); // Release resources. if (handle != INVALID_HANDLE_VALUE) ::FindClose(handle); #else // Append separator character if needed. if (path.back() != '/') path += '/'; // Init. DIR* dir = ::opendir(path.c_str()); if (dir == nullptr) return absl::optional>(); // Populate output. std::vector found_entries; while (dirent* dirent = readdir(dir)) { const std::string& name = dirent->d_name; if (name != "." && name != "..") found_entries.emplace_back(path + name); } // Release resources. closedir(dir); #endif return absl::optional>(std::move(found_entries)); } bool CreateDir(const std::string& directory_name) { struct stat path_info = {0}; // Check if the path exists already: if (stat(directory_name.c_str(), &path_info) == 0) { if (!S_ISDIR(path_info.st_mode)) { fprintf(stderr, "Path %s exists but is not a directory! Remove this " "file and re-run to create the directory.\n", directory_name.c_str()); return false; } } else { #ifdef WIN32 return _mkdir(directory_name.c_str()) == 0; #else return mkdir(directory_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0; #endif } return true; } bool RemoveDir(const std::string& directory_name) { #ifdef WIN32 return RemoveDirectoryA(directory_name.c_str()) != FALSE; #else return rmdir(directory_name.c_str()) == 0; #endif } bool RemoveFile(const std::string& file_name) { #ifdef WIN32 return DeleteFileA(file_name.c_str()) != FALSE; #else return unlink(file_name.c_str()) == 0; #endif } std::string ResourcePath(const std::string& name, const std::string& extension) { return webrtc::test::internal::ResourcePath(name, extension); } std::string JoinFilename(const std::string& dir, const std::string& name) { RTC_CHECK(!dir.empty()) << "Special cases not implemented."; return dir + kPathDelimiter + name; } size_t GetFileSize(const std::string& filename) { FILE* f = fopen(filename.c_str(), "rb"); size_t size = 0; if (f != NULL) { if (fseek(f, 0, SEEK_END) == 0) { size = ftell(f); } fclose(f); } return size; } } // namespace test } // namespace webrtc