Adopt absl::string_view in testsupport/file_utils*

Bug: webrtc:13579
Change-Id: I5b710cfd218c44be01a7a42c2b281739081881e6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256280
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Ali Tofigh <alito@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36332}
This commit is contained in:
Ali Tofigh 2022-03-24 19:34:34 +01:00 committed by WebRTC LUCI CQ
parent e39daf4146
commit 1d6de1499c
9 changed files with 136 additions and 103 deletions

View file

@ -55,7 +55,7 @@ class MAYBE_FileRotatingStreamTest : public ::testing::Test {
// Append per-test output path in order to run within gtest parallel.
dir_path_.append(dir_name.begin(), dir_name.end());
if (ensure_trailing_delimiter) {
dir_path_.append(webrtc::test::kPathDelimiter);
dir_path_.append(std::string(webrtc::test::kPathDelimiter));
}
ASSERT_TRUE(webrtc::test::CreateDir(dir_path_));
stream_.reset(new FileRotatingStream(dir_path_, file_prefix, max_file_size,
@ -192,7 +192,8 @@ TEST_F(MAYBE_FileRotatingStreamTest, WriteWithoutDelimiterAndRead) {
// Reopen for read.
std::string expected_contents("bbccd");
VerifyStreamRead(expected_contents.c_str(), expected_contents.size(),
dir_path_ + webrtc::test::kPathDelimiter, kFilePrefix);
dir_path_ + std::string(webrtc::test::kPathDelimiter),
kFilePrefix);
}
// Tests that a write operation followed by a read (without trailing delimiter)
@ -262,7 +263,7 @@ class MAYBE_CallSessionFileRotatingStreamTest : public ::testing::Test {
// Append per-test output path in order to run within gtest parallel.
dir_path_.append(dir_name.begin(), dir_name.end());
dir_path_.append(webrtc::test::kPathDelimiter);
dir_path_.append(std::string(webrtc::test::kPathDelimiter));
ASSERT_TRUE(webrtc::test::CreateDir(dir_path_));
stream_.reset(
new CallSessionFileRotatingStream(dir_path_, max_total_log_size));

View file

@ -629,6 +629,7 @@ if (is_ios) {
"../rtc_base:rtc_base_approved",
"../sdk:helpers_objc",
]
absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings" ]
}
}
@ -659,7 +660,10 @@ rtc_library("fileutils") {
"../rtc_base:checks",
"../rtc_base:stringutils",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
absl_deps = [
"//third_party/abseil-cpp/absl/strings:strings",
"//third_party/abseil-cpp/absl/types:optional",
]
if (is_ios) {
deps += [ ":fileutils_ios_objc" ]
}
@ -676,6 +680,7 @@ rtc_library("fileutils") {
rtc_source_set("fileutils_override_api") {
testonly = true
sources = [ "testsupport/file_utils_override.h" ]
absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings" ]
}
rtc_library("fileutils_override_impl") {
@ -688,7 +693,10 @@ rtc_library("fileutils_override_impl") {
"../rtc_base:macromagic",
"../rtc_base:stringutils",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
absl_deps = [
"//third_party/abseil-cpp/absl/strings:strings",
"//third_party/abseil-cpp/absl/types:optional",
]
if (is_ios) {
deps += [ ":fileutils_ios_objc" ]
}
@ -739,7 +747,10 @@ rtc_library("fileutils_unittests") {
":test_support",
"../rtc_base:checks",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
absl_deps = [
"//third_party/abseil-cpp/absl/strings:strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("direct_transport") {

View file

@ -53,30 +53,36 @@
#include "test/testsupport/mac_file_utils.h"
#endif
#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/strings/string_builder.h"
#include "test/testsupport/file_utils_override.h"
namespace webrtc {
namespace test {
#if defined(WEBRTC_WIN)
const char* kPathDelimiter = "\\";
const absl::string_view kPathDelimiter = "\\";
#else
const char* kPathDelimiter = "/";
const absl::string_view kPathDelimiter = "/";
#endif
std::string DirName(const std::string& path) {
std::string DirName(absl::string_view path) {
if (path.empty())
return "";
if (path == kPathDelimiter)
return path;
return std::string(path);
std::string result = path;
if (result.back() == *kPathDelimiter)
result.pop_back(); // Remove trailing separator.
if (path.back() == kPathDelimiter[0])
path.remove_suffix(1); // Remove trailing separator.
return result.substr(0, result.find_last_of(kPathDelimiter));
return std::string(path.substr(0, path.find_last_of(kPathDelimiter)));
}
bool FileExists(absl::string_view file_name) {
struct stat file_info = {0};
return stat(std::string(file_name).c_str(), &file_info) == 0;
}
bool FileExists(const std::string& file_name) {
@ -84,9 +90,9 @@ bool FileExists(const std::string& file_name) {
return stat(file_name.c_str(), &file_info) == 0;
}
bool DirExists(const std::string& directory_name) {
bool DirExists(absl::string_view directory_name) {
struct stat directory_info = {0};
return stat(directory_name.c_str(), &directory_info) == 0 &&
return stat(std::string(directory_name).c_str(), &directory_info) == 0 &&
S_ISDIR(directory_info.st_mode);
}
@ -100,7 +106,7 @@ std::string 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) {
std::string TempFilename(absl::string_view dir, absl::string_view prefix) {
#ifdef WIN32
wchar_t filename[MAX_PATH];
if (::GetTempFileNameW(rtc::ToUtf16(dir).c_str(),
@ -109,41 +115,42 @@ std::string TempFilename(const std::string& dir, const std::string& prefix) {
RTC_DCHECK_NOTREACHED();
return "";
#else
int len = dir.size() + prefix.size() + 2 + 6;
std::unique_ptr<char[]> tempname(new char[len]);
rtc::StringBuilder os;
os << dir << "/" << prefix << "XXXXXX";
std::string tempname = os.Release();
snprintf(tempname.get(), len, "%s/%sXXXXXX", dir.c_str(), prefix.c_str());
int fd = ::mkstemp(tempname.get());
int fd = ::mkstemp(tempname.data());
if (fd == -1) {
RTC_DCHECK_NOTREACHED();
return "";
} else {
::close(fd);
}
std::string ret(tempname.get());
return ret;
return tempname;
#endif
}
std::string GenerateTempFilename(const std::string& dir,
const std::string& prefix) {
std::string GenerateTempFilename(absl::string_view dir,
absl::string_view prefix) {
std::string filename = TempFilename(dir, prefix);
RemoveFile(filename);
return filename;
}
absl::optional<std::vector<std::string>> ReadDirectory(std::string path) {
absl::optional<std::vector<std::string>> ReadDirectory(absl::string_view path) {
if (path.length() == 0)
return absl::optional<std::vector<std::string>>();
std::string path_str = std::string(path);
#if defined(WEBRTC_WIN)
// Append separator character if needed.
if (path.back() != '\\')
path += '\\';
if (path_str.back() != '\\')
path_str += '\\';
// Init.
WIN32_FIND_DATAW data;
HANDLE handle = ::FindFirstFileW(rtc::ToUtf16(path + '*').c_str(), &data);
HANDLE handle = ::FindFirstFileW(rtc::ToUtf16(path_str + '*').c_str(), &data);
if (handle == INVALID_HANDLE_VALUE)
return absl::optional<std::vector<std::string>>();
@ -152,7 +159,7 @@ absl::optional<std::vector<std::string>> ReadDirectory(std::string path) {
do {
const std::string name = rtc::ToUtf8(data.cFileName);
if (name != "." && name != "..")
found_entries.emplace_back(path + name);
found_entries.emplace_back(path_str + name);
} while (::FindNextFileW(handle, &data) == TRUE);
// Release resources.
@ -160,11 +167,11 @@ absl::optional<std::vector<std::string>> ReadDirectory(std::string path) {
::FindClose(handle);
#else
// Append separator character if needed.
if (path.back() != '/')
path += '/';
if (path_str.back() != '/')
path_str += '/';
// Init.
DIR* dir = ::opendir(path.c_str());
DIR* dir = ::opendir(path_str.c_str());
if (dir == nullptr)
return absl::optional<std::vector<std::string>>();
@ -173,7 +180,7 @@ absl::optional<std::vector<std::string>> ReadDirectory(std::string path) {
while (dirent* dirent = readdir(dir)) {
const std::string& name = dirent->d_name;
if (name != "." && name != "..")
found_entries.emplace_back(path + name);
found_entries.emplace_back(path_str + name);
}
// Release resources.
@ -183,55 +190,57 @@ absl::optional<std::vector<std::string>> ReadDirectory(std::string path) {
return absl::optional<std::vector<std::string>>(std::move(found_entries));
}
bool CreateDir(const std::string& directory_name) {
bool CreateDir(absl::string_view directory_name) {
std::string directory_name_str = 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 (stat(directory_name_str.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());
directory_name_str.c_str());
return false;
}
} else {
#ifdef WIN32
return _mkdir(directory_name.c_str()) == 0;
return _mkdir(directory_name_str.c_str()) == 0;
#else
return mkdir(directory_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0;
return mkdir(directory_name_str.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0;
#endif
}
return true;
}
bool RemoveDir(const std::string& directory_name) {
bool RemoveDir(absl::string_view directory_name) {
#ifdef WIN32
return RemoveDirectoryA(directory_name.c_str()) != FALSE;
return RemoveDirectoryA(std::string(directory_name).c_str()) != FALSE;
#else
return rmdir(directory_name.c_str()) == 0;
return rmdir(std::string(directory_name).c_str()) == 0;
#endif
}
bool RemoveFile(const std::string& file_name) {
bool RemoveFile(absl::string_view file_name) {
#ifdef WIN32
return DeleteFileA(file_name.c_str()) != FALSE;
return DeleteFileA(std::string(file_name).c_str()) != FALSE;
#else
return unlink(file_name.c_str()) == 0;
return unlink(std::string(file_name).c_str()) == 0;
#endif
}
std::string ResourcePath(const std::string& name,
const std::string& extension) {
std::string ResourcePath(absl::string_view name, absl::string_view extension) {
return webrtc::test::internal::ResourcePath(name, extension);
}
std::string JoinFilename(const std::string& dir, const std::string& name) {
std::string JoinFilename(absl::string_view dir, absl::string_view name) {
RTC_CHECK(!dir.empty()) << "Special cases not implemented.";
return dir + kPathDelimiter + name;
rtc::StringBuilder os;
os << dir << kPathDelimiter << name;
return os.Release();
}
size_t GetFileSize(const std::string& filename) {
FILE* f = fopen(filename.c_str(), "rb");
size_t GetFileSize(absl::string_view filename) {
FILE* f = fopen(std::string(filename).c_str(), "rb");
size_t size = 0;
if (f != NULL) {
if (fseek(f, 0, SEEK_END) == 0) {

View file

@ -16,17 +16,15 @@
#include <string>
#include <vector>
#include "absl/base/attributes.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
namespace webrtc {
namespace test {
// This is the "directory" returned if the ProjectPath() function fails
// to find the project root.
extern const char* kCannotFindProjectRootDir;
// Slash or backslash, depending on platform. NUL-terminated string.
extern const char* kPathDelimiter;
// Slash or backslash, depending on platform.
ABSL_CONST_INIT extern const absl::string_view kPathDelimiter;
// Returns the absolute path to the output directory where log files and other
// test artifacts should be put. The output directory is generally a directory
@ -47,12 +45,12 @@ std::string OutputPath();
// Generates an empty file with a unique name in the specified directory and
// returns the file name and path.
// TODO(titovartem) rename to TempFile and next method to TempFilename
std::string TempFilename(const std::string& dir, const std::string& prefix);
std::string TempFilename(absl::string_view dir, absl::string_view prefix);
// Generates a unique file name that can be used for file creation. Doesn't
// create any files.
std::string GenerateTempFilename(const std::string& dir,
const std::string& prefix);
std::string GenerateTempFilename(absl::string_view dir,
absl::string_view prefix);
// Returns a path to a resource file in [project-root]/resources/ dir.
// Returns an absolute path
@ -63,10 +61,10 @@ std::string GenerateTempFilename(const std::string& dir,
// If a directory path is prepended to the filename, a subdirectory
// hierarchy reflecting that path is assumed to be present.
// extension - File extension, without the dot, i.e. "bmp" or "yuv".
std::string ResourcePath(const std::string& name, const std::string& extension);
std::string ResourcePath(absl::string_view name, absl::string_view extension);
// Joins directory name and file name, separated by the path delimiter.
std::string JoinFilename(const std::string& dir, const std::string& name);
std::string JoinFilename(absl::string_view dir, absl::string_view name);
// Gets the current working directory for the executing program.
// Returns "./" if for some reason it is not possible to find the working
@ -77,31 +75,34 @@ std::string WorkingDir();
// of strings with one element for each found file or directory. Each element is
// a path created by prepending `dir` to the file/directory name. "." and ".."
// are never added in the returned vector.
absl::optional<std::vector<std::string>> ReadDirectory(std::string path);
absl::optional<std::vector<std::string>> ReadDirectory(absl::string_view path);
// 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 CreateDir(const std::string& directory_name);
bool CreateDir(absl::string_view directory_name);
// Removes a directory, which must already be empty.
bool RemoveDir(const std::string& directory_name);
bool RemoveDir(absl::string_view directory_name);
// Removes a file.
bool RemoveFile(const std::string& file_name);
bool RemoveFile(absl::string_view file_name);
// Checks if a file exists.
// TOOD(alito): Merge these once absl::string_view adoption is complete for this
// file.
bool FileExists(absl::string_view file_name);
bool FileExists(const std::string& file_name);
// Checks if a directory exists.
bool DirExists(const std::string& directory_name);
bool DirExists(absl::string_view directory_name);
// Strips the rightmost path segment from a path.
std::string DirName(const std::string& path);
std::string DirName(absl::string_view path);
// 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.
size_t GetFileSize(const std::string& filename);
size_t GetFileSize(absl::string_view filename);
} // namespace test
} // namespace webrtc

View file

@ -41,34 +41,37 @@
#include "test/testsupport/mac_file_utils.h"
#endif
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/strings/string_builder.h"
namespace webrtc {
namespace test {
std::string DirName(const std::string& path);
bool CreateDir(const std::string& directory_name);
std::string DirName(absl::string_view path);
bool CreateDir(absl::string_view directory_name);
namespace internal {
namespace {
#if defined(WEBRTC_WIN)
const char* kPathDelimiter = "\\";
const absl::string_view kPathDelimiter = "\\";
#elif !defined(WEBRTC_IOS)
const char* kPathDelimiter = "/";
const absl::string_view kPathDelimiter = "/";
#endif
#if defined(WEBRTC_ANDROID)
// This is a special case in Chrome infrastructure. See
// base/test/test_support_android.cc.
const char* kAndroidChromiumTestsRoot = "/sdcard/chromium_tests_root/";
const absl::string_view kAndroidChromiumTestsRoot =
"/sdcard/chromium_tests_root/";
#endif
#if !defined(WEBRTC_IOS)
const char* kResourcesDirName = "resources";
const absl::string_view kResourcesDirName = "resources";
#endif
} // namespace
@ -77,7 +80,7 @@ const char* kResourcesDirName = "resources";
// The returned path always ends with a path separator.
absl::optional<std::string> ProjectRootPath() {
#if defined(WEBRTC_ANDROID)
return kAndroidChromiumTestsRoot;
return std::string(kAndroidChromiumTestsRoot);
#elif defined WEBRTC_IOS
return IOSRootPath();
#elif defined(WEBRTC_MAC)
@ -86,7 +89,7 @@ absl::optional<std::string> ProjectRootPath() {
std::string exe_dir = DirName(path);
// On Mac, tests execute in out/Whatever, so src is two levels up except if
// the test is bundled (which our tests are not), in which case it's 5 levels.
return DirName(DirName(exe_dir)) + kPathDelimiter;
return DirName(DirName(exe_dir)) + std::string(kPathDelimiter);
#elif defined(WEBRTC_POSIX)
char buf[PATH_MAX];
ssize_t count = ::readlink("/proc/self/exe", buf, arraysize(buf));
@ -95,8 +98,8 @@ absl::optional<std::string> ProjectRootPath() {
return absl::nullopt;
}
// On POSIX, tests execute in out/Whatever, so src is two levels up.
std::string exe_dir = DirName(std::string(buf, count));
return DirName(DirName(exe_dir)) + kPathDelimiter;
std::string exe_dir = DirName(absl::string_view(buf, count));
return DirName(DirName(exe_dir)) + std::string(kPathDelimiter);
#elif defined(WEBRTC_WIN)
wchar_t buf[MAX_PATH];
buf[0] = 0;
@ -105,7 +108,7 @@ absl::optional<std::string> ProjectRootPath() {
std::string exe_path = rtc::ToUtf8(std::wstring(buf));
std::string exe_dir = DirName(exe_path);
return DirName(DirName(exe_dir)) + kPathDelimiter;
return DirName(DirName(exe_dir)) + std::string(kPathDelimiter);
#endif
}
@ -113,7 +116,7 @@ std::string OutputPath() {
#if defined(WEBRTC_IOS)
return IOSOutputPath();
#elif defined(WEBRTC_ANDROID)
return kAndroidChromiumTestsRoot;
return std::string(kAndroidChromiumTestsRoot);
#else
absl::optional<std::string> path_opt = ProjectRootPath();
RTC_DCHECK(path_opt);
@ -121,13 +124,13 @@ std::string OutputPath() {
if (!CreateDir(path)) {
return "./";
}
return path + kPathDelimiter;
return path + std::string(kPathDelimiter);
#endif
}
std::string WorkingDir() {
#if defined(WEBRTC_ANDROID)
return kAndroidChromiumTestsRoot;
return std::string(kAndroidChromiumTestsRoot);
#else
char path_buffer[FILENAME_MAX];
if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) {
@ -139,15 +142,15 @@ std::string WorkingDir() {
#endif
}
std::string ResourcePath(const std::string& name,
const std::string& extension) {
std::string ResourcePath(absl::string_view name, absl::string_view extension) {
#if defined(WEBRTC_IOS)
return IOSResourcePath(name, extension);
#else
absl::optional<std::string> path_opt = ProjectRootPath();
RTC_DCHECK(path_opt);
std::string resources_path = *path_opt + kResourcesDirName + kPathDelimiter;
return resources_path + name + "." + extension;
rtc::StringBuilder os(*path_opt);
os << kResourcesDirName << kPathDelimiter << name << "." << extension;
return os.Release();
#endif
}

View file

@ -8,11 +8,13 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string>
#ifndef TEST_TESTSUPPORT_FILE_UTILS_OVERRIDE_H_
#define TEST_TESTSUPPORT_FILE_UTILS_OVERRIDE_H_
#include <string>
#include "absl/strings/string_view.h"
namespace webrtc {
namespace test {
namespace internal {
@ -46,7 +48,7 @@ std::string WorkingDir();
// If a directory path is prepended to the filename, a subdirectory
// hierarchy reflecting that path is assumed to be present.
// extension - File extension, without the dot, i.e. "bmp" or "yuv".
std::string ResourcePath(const std::string& name, const std::string& extension);
std::string ResourcePath(absl::string_view name, absl::string_view extension);
} // namespace internal
} // namespace test

View file

@ -16,6 +16,7 @@
#include <fstream>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "rtc_base/checks.h"
#include "test/gmock.h"
@ -32,15 +33,15 @@ namespace test {
namespace {
std::string Path(const std::string& path) {
std::string result = path;
std::replace(result.begin(), result.end(), '/', *kPathDelimiter);
std::string Path(absl::string_view path) {
std::string result = std::string(path);
std::replace(result.begin(), result.end(), '/', kPathDelimiter[0]);
return result;
}
// Remove files and directories in a directory non-recursively and writes the
// number of deleted items in `num_deleted_entries`.
void CleanDir(const std::string& dir, size_t* num_deleted_entries) {
void CleanDir(absl::string_view dir, size_t* num_deleted_entries) {
RTC_DCHECK(num_deleted_entries);
*num_deleted_entries = 0;
absl::optional<std::vector<std::string>> dir_content = ReadDirectory(dir);
@ -58,8 +59,8 @@ void CleanDir(const std::string& dir, size_t* num_deleted_entries) {
}
}
void WriteStringInFile(const std::string& what, const std::string& file_path) {
std::ofstream out(file_path);
void WriteStringInFile(absl::string_view what, absl::string_view file_path) {
std::ofstream out(std::string{file_path});
out << what;
out.close();
}
@ -110,7 +111,7 @@ TEST_F(FileUtilsTest, OutputPathFromUnchangedWorkingDir) {
// Tests with current working directory set to a directory higher up in the
// directory tree than the project root dir.
TEST_F(FileUtilsTest, OutputPathFromRootWorkingDir) {
ASSERT_EQ(0, chdir(kPathDelimiter));
ASSERT_EQ(0, chdir(kPathDelimiter.data()));
std::string expected_end = ExpectedRootDirByPlatform();
std::string result = webrtc::test::OutputPath();
@ -179,7 +180,7 @@ TEST_F(FileUtilsTest, ResourcePathReturnsCorrectPath) {
}
TEST_F(FileUtilsTest, ResourcePathFromRootWorkingDir) {
ASSERT_EQ(0, chdir(kPathDelimiter));
ASSERT_EQ(0, chdir(kPathDelimiter.data()));
std::string resource = webrtc::test::ResourcePath("whatever", "ext");
#if !defined(WEBRTC_IOS)
ASSERT_NE(resource.find("resources"), std::string::npos);
@ -202,7 +203,8 @@ TEST_F(FileUtilsTest, GetFileSizeExistingFile) {
}
TEST_F(FileUtilsTest, GetFileSizeNonExistingFile) {
ASSERT_EQ(0u, webrtc::test::GetFileSize("non-existing-file.tmp"));
ASSERT_EQ(0u, webrtc::test::GetFileSize(
absl::string_view("non-existing-file.tmp")));
}
TEST_F(FileUtilsTest, DirExists) {

View file

@ -13,12 +13,15 @@
#include <string>
#include "absl/strings/string_view.h"
namespace webrtc {
namespace test {
std::string IOSOutputPath();
std::string IOSRootPath();
std::string IOSResourcePath(std::string name, std::string extension);
std::string IOSResourcePath(absl::string_view name,
absl::string_view extension);
} // namespace test
} // namespace webrtc

View file

@ -15,6 +15,7 @@
#import "sdk/objc/helpers/NSString+StdString.h"
#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
namespace webrtc {
@ -23,11 +24,11 @@ namespace test {
// For iOS, resource files are added to the application bundle in the root
// and not in separate folders as is the case for other platforms. This method
// therefore removes any prepended folders and uses only the actual file name.
std::string IOSResourcePath(std::string name, std::string extension) {
std::string IOSResourcePath(absl::string_view name, absl::string_view extension) {
@autoreleasepool {
NSString* path = [NSString stringForStdString:name];
NSString* path = [NSString stringForAbslStringView:name];
NSString* fileName = path.lastPathComponent;
NSString* fileType = [NSString stringForStdString:extension];
NSString* fileType = [NSString stringForAbslStringView:extension];
// Get full pathname for the resource identified by the name and extension.
NSString* pathString = [[NSBundle mainBundle] pathForResource:fileName
ofType:fileType];