summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc')
-rw-r--r--third_party/libwebrtc/webrtc/test/testsupport/fileutils.cc363
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