diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc index 48b66a440..3ba46e4aa 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc @@ -118,7 +118,7 @@ class BaseLineFileUpdate : public BaseLineFileInterface { virtual bool VerifyOrWrite() { if (!verifier_->VerifyOrWrite()) { std::string dir_path = webrtc::test::OutputPath() + kResourceSubDir; - if (!webrtc::test::CreateDirectory(dir_path)) { + if (!webrtc::test::CreateDir(dir_path)) { printf("WARNING: Cannot create output dir: %s\n", dir_path.c_str()); return false; } diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index 747557fdf..045647755 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -156,7 +156,10 @@ class VideoProcessorIntegrationTest: public testing::Test { // Setup the TestConfig struct for processing of a clip in CIF resolution. config_.input_filename = webrtc::test::ResourcePath("foreman_cif", "yuv"); - config_.output_filename = tmpnam(NULL); + + // Generate an output filename in a safe way. + config_.output_filename = webrtc::test::TempFilename( + webrtc::test::OutputPath(), "videoprocessor_integrationtest"); config_.frame_length_in_bytes = CalcBufferSize(kI420, kCIFWidth, kCIFHeight); config_.verbose = false; diff --git a/webrtc/system_wrappers/interface/utf_util_win.h b/webrtc/system_wrappers/interface/utf_util_win.h new file mode 100644 index 000000000..f88f0799f --- /dev/null +++ b/webrtc/system_wrappers/interface/utf_util_win.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 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. + */ + +// Conversion functions for UTF-8 and UTF-16 strings on Windows. +// Duplicated from talk/base/win32.h. +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_UTF_UTIL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_UTF_UTIL_H_ + +#ifdef WIN32 +#include +#include + +#include "webrtc/system_wrappers/interface/scoped_ptr.h" + +namespace webrtc { + +inline std::wstring ToUtf16(const char* utf8, size_t len) { + int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast(len), + NULL, 0); + scoped_ptr ws(new wchar_t[len16]); + ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast(len), ws.get(), + len16); + return std::wstring(ws.get(), len16); +} + +inline std::wstring ToUtf16(const std::string& str) { + return ToUtf16(str.data(), str.length()); +} + +inline std::string ToUtf8(const wchar_t* wide, size_t len) { + int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast(len), + NULL, 0, NULL, NULL); + scoped_ptr ns(new char[len8]); + ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast(len), ns.get(), len8, + NULL, NULL); + return std::string(ns.get(), len8); +} + +inline std::string ToUtf8(const wchar_t* wide) { + return ToUtf8(wide, wcslen(wide)); +} + +inline std::string ToUtf8(const std::wstring& wstr) { + return ToUtf8(wstr.data(), wstr.length()); +} + +} // namespace webrtc + +#endif // WIN32 +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_UTF_UTIL_H_ diff --git a/webrtc/system_wrappers/source/system_wrappers.gyp b/webrtc/system_wrappers/source/system_wrappers.gyp index 109a72aac..cc79f0bcc 100644 --- a/webrtc/system_wrappers/source/system_wrappers.gyp +++ b/webrtc/system_wrappers/source/system_wrappers.gyp @@ -52,6 +52,7 @@ '../interface/tick_util.h', '../interface/trace.h', '../interface/trace_event.h', + '../interface/utf_util_win.h', 'aligned_malloc.cc', 'atomic32_mac.cc', 'atomic32_posix.cc', diff --git a/webrtc/test/testsupport/fileutils.cc b/webrtc/test/testsupport/fileutils.cc index c89f9bd1a..9d04ab023 100644 --- a/webrtc/test/testsupport/fileutils.cc +++ b/webrtc/test/testsupport/fileutils.cc @@ -11,11 +11,18 @@ #include "webrtc/test/testsupport/fileutils.h" #ifdef WIN32 +#include #include +#include +#include #include + +#include "webrtc/system_wrappers/interface/utf_util_win.h" #define GET_CURRENT_DIR _getcwd #else #include + +#include "webrtc/system_wrappers/interface/scoped_ptr.h" #define GET_CURRENT_DIR getcwd #endif @@ -25,6 +32,7 @@ #endif #include +#include #include #include "webrtc/typedefs.h" // For architecture defines @@ -92,7 +100,7 @@ std::string OutputPathImpl() { return kFallbackPath; } path += kOutputDirName; - if (!CreateDirectory(path)) { + if (!CreateDir(path)) { return kFallbackPath; } return path + kPathDelimiter; @@ -154,7 +162,35 @@ std::string WorkingDir() { #endif // !WEBRTC_ANDROID -bool CreateDirectory(std::string directory_name) { +// 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(ToUtf16(dir).c_str(), + ToUtf16(prefix).c_str(), 0, filename) != 0) + return ToUtf8(filename); + assert(false); + return ""; +#else + int len = dir.size() + prefix.size() + 2 + 6; + scoped_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 +} + +bool CreateDir(std::string directory_name) { struct stat path_info = {0}; // Check if the path exists already: if (stat(directory_name.c_str(), &path_info) == 0) { diff --git a/webrtc/test/testsupport/fileutils.h b/webrtc/test/testsupport/fileutils.h index d51bbde21..78789fa87 100644 --- a/webrtc/test/testsupport/fileutils.h +++ b/webrtc/test/testsupport/fileutils.h @@ -103,6 +103,10 @@ std::string ProjectRootPath(); // found, the current working directory ("./") is returned as a fallback. std::string OutputPath(); +// Generates an empty file with a unique name in the specified directory and +// returns the file name and path. +std::string TempFilename(const std::string &dir, const std::string &prefix); + // Returns a path to a resource file for the currently executing platform. // Adapts to what filenames are currently present in the // [project-root]/resources/ dir. @@ -132,7 +136,10 @@ std::string WorkingDir(); // Creates a directory if it not already exists. // Returns true if successful. Will print an error message to stderr and return // false if a file with the same name already exists. -bool CreateDirectory(std::string directory_name); +bool CreateDir(std::string directory_name); + +// Checks if a file exists. +bool FileExists(std::string& file_name); // File size of the supplied file in bytes. Will return 0 if the file is // empty or if the file does not exist/is readable. diff --git a/webrtc/test/testsupport/fileutils_unittest.cc b/webrtc/test/testsupport/fileutils_unittest.cc index c38e4533b..4cd451372 100644 --- a/webrtc/test/testsupport/fileutils_unittest.cc +++ b/webrtc/test/testsupport/fileutils_unittest.cc @@ -46,7 +46,7 @@ class FileUtilsTest : public testing::Test { original_working_dir_ = webrtc::test::WorkingDir(); std::string resources_path = original_working_dir_ + kPathDelimiter + kResourcesDir + kPathDelimiter; - webrtc::test::CreateDirectory(resources_path); + webrtc::test::CreateDir(resources_path); files_.push_back(resources_path + kTestName + "." + kExtension); files_.push_back(resources_path + kTestName + "_32." + kExtension); @@ -117,12 +117,19 @@ TEST_F(FileUtilsTest, DISABLED_ON_ANDROID(OutputPathFromRootWorkingDir)) { ASSERT_EQ("./", webrtc::test::OutputPath()); } +TEST_F(FileUtilsTest, DISABLED_ON_ANDROID(TempFilename)) { + std::string temp_filename = webrtc::test::TempFilename( + webrtc::test::OutputPath(), "TempFilenameTest"); + ASSERT_TRUE(webrtc::test::FileExists(temp_filename)); + remove(temp_filename.c_str()); +} + // Only tests that the code executes -TEST_F(FileUtilsTest, CreateDirectory) { +TEST_F(FileUtilsTest, CreateDir) { std::string directory = "fileutils-unittest-empty-dir"; // Make sure it's removed if a previous test has failed: remove(directory.c_str()); - ASSERT_TRUE(webrtc::test::CreateDirectory(directory)); + ASSERT_TRUE(webrtc::test::CreateDir(directory)); remove(directory.c_str()); }