diff options
Diffstat (limited to 'third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc')
-rw-r--r-- | third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc b/third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc new file mode 100644 index 0000000000..2aff75a4d9 --- /dev/null +++ b/third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc @@ -0,0 +1,363 @@ +/* + * 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/fileutils.h" + +#include <assert.h> + +#ifdef WIN32 +#include <direct.h> +#include <tchar.h> +#include <windows.h> +#include <algorithm> + +#include "Shlwapi.h" +#include "WinDef.h" + +#include "rtc_base/win32.h" +#define GET_CURRENT_DIR _getcwd +#else +#include <dirent.h> +#include <unistd.h> + +#define GET_CURRENT_DIR getcwd +#endif + +#include <sys/stat.h> // 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <memory> +#include <utility> + +#include "rtc_base/checks.h" +#include "typedefs.h" // NOLINT(build/include) // For architecture defines + +namespace webrtc { +namespace test { + +#if defined(WEBRTC_IOS) +// Defined in iosfileutils.mm. No header file to discourage use elsewhere. +std::string IOSOutputPath(); +std::string IOSRootPath(); +std::string IOSResourcePath(std::string name, std::string extension); +#endif + +namespace { + +#ifdef WIN32 +const char* kPathDelimiter = "\\"; +#else +const char* kPathDelimiter = "/"; +#endif + +#ifdef WEBRTC_ANDROID +const char* kRootDirName = "/sdcard/chromium_tests_root/"; +#else +#if !defined(WEBRTC_IOS) +const char* kOutputDirName = "out"; +#endif +const char* kFallbackPath = "./"; +#endif // !defined(WEBRTC_ANDROID) + +#if !defined(WEBRTC_IOS) +const char* kResourcesDirName = "resources"; +#endif + +char relative_dir_path[FILENAME_MAX]; +bool relative_dir_path_set = false; + +} // namespace + +const char* kCannotFindProjectRootDir = "ERROR_CANNOT_FIND_PROJECT_ROOT_DIR"; + +void SetExecutablePath(const std::string& path) { + std::string working_dir = WorkingDir(); + std::string temp_path = path; + + // Handle absolute paths; convert them to relative paths to the working dir. + if (path.find(working_dir) != std::string::npos) { + temp_path = path.substr(working_dir.length() + 1); + } + // On Windows, when tests are run under memory tools like DrMemory and TSan, + // slashes occur in the path as directory separators. Make sure we replace + // such cases with backslashes in order for the paths to be correct. +#ifdef WIN32 + std::replace(temp_path.begin(), temp_path.end(), '/', '\\'); +#endif + + // Trim away the executable name; only store the relative dir path. + temp_path = temp_path.substr(0, temp_path.find_last_of(kPathDelimiter)); + strncpy(relative_dir_path, temp_path.c_str(), FILENAME_MAX); + relative_dir_path_set = true; +} + +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); +} + +#ifdef WEBRTC_ANDROID + +std::string ProjectRootPath() { + return kRootDirName; +} + +std::string OutputPath() { + return kRootDirName; +} + +std::string WorkingDir() { + return kRootDirName; +} + +#else // WEBRTC_ANDROID + +std::string ProjectRootPath() { +#if defined(WEBRTC_IOS) + return IOSRootPath(); +#else + std::string path = WorkingDir(); + if (path == kFallbackPath) { + return kCannotFindProjectRootDir; + } + if (relative_dir_path_set) { + path = path + kPathDelimiter + relative_dir_path; + } + path = path + kPathDelimiter + ".." + kPathDelimiter + ".."; + char canonical_path[FILENAME_MAX]; +#ifdef WIN32 + BOOL succeeded = PathCanonicalizeA(canonical_path, path.c_str()); +#else + bool succeeded = realpath(path.c_str(), canonical_path) != NULL; +#endif + if (succeeded) { + path = std::string(canonical_path) + kPathDelimiter; + return path; + } else { + fprintf(stderr, "Cannot find project root directory!\n"); + return kCannotFindProjectRootDir; + } +#endif +} + +std::string OutputPath() { +#if defined(WEBRTC_IOS) + return IOSOutputPath(); +#else + std::string path = ProjectRootPath(); + if (path == kCannotFindProjectRootDir) { + return kFallbackPath; + } + path += kOutputDirName; + if (!CreateDir(path)) { + return kFallbackPath; + } + return path + kPathDelimiter; +#endif +} + +std::string WorkingDir() { + char path_buffer[FILENAME_MAX]; + if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) { + fprintf(stderr, "Cannot get current directory!\n"); + return kFallbackPath; + } else { + return std::string(path_buffer); + } +} + +#endif // !WEBRTC_ANDROID + +// 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 (::GetTempFileName(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<char[]> 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 +} + +rtc::Optional<std::vector<std::string>> ReadDirectory(std::string path) { + if (path.length() == 0) + return rtc::Optional<std::vector<std::string>>(); + +#if defined(WEBRTC_WIN) + // Append separator character if needed. + if (path.back() != '\\') + path += '\\'; + + // Init. + WIN32_FIND_DATA data; + HANDLE handle = ::FindFirstFile(rtc::ToUtf16(path + '*').c_str(), &data); + if (handle == INVALID_HANDLE_VALUE) + return rtc::Optional<std::vector<std::string>>(); + + // Populate output. + std::vector<std::string> found_entries; + do { + const std::string name = rtc::ToUtf8(data.cFileName); + if (name != "." && name != "..") + found_entries.emplace_back(path + name); + } while (::FindNextFile(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 rtc::Optional<std::vector<std::string>>(); + + // Populate output. + std::vector<std::string> 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 rtc::Optional<std::vector<std::string>>(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) { +#if defined(WEBRTC_IOS) + return IOSResourcePath(name, extension); +#else + std::string platform = "win"; +#ifdef WEBRTC_LINUX + platform = "linux"; +#endif // WEBRTC_LINUX +#ifdef WEBRTC_MAC + platform = "mac"; +#endif // WEBRTC_MAC +#ifdef WEBRTC_ANDROID + platform = "android"; +#endif // WEBRTC_ANDROID + +#ifdef WEBRTC_ARCH_64_BITS + std::string architecture = "64"; +#else + std::string architecture = "32"; +#endif // WEBRTC_ARCH_64_BITS + + std::string resources_path = ProjectRootPath() + kResourcesDirName + + kPathDelimiter; + std::string resource_file = resources_path + name + "_" + platform + "_" + + architecture + "." + extension; + if (FileExists(resource_file)) { + return resource_file; + } + // Try without architecture. + resource_file = resources_path + name + "_" + platform + "." + extension; + if (FileExists(resource_file)) { + return resource_file; + } + // Try without platform. + resource_file = resources_path + name + "_" + architecture + "." + extension; + if (FileExists(resource_file)) { + return resource_file; + } + + // Fall back on name without architecture or platform. + return resources_path + name + "." + extension; +#endif // defined (WEBRTC_IOS) +} + +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 |