| /* | |
| * Copyright 2004 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. | |
| */ | |
| #if defined(WEBRTC_WIN) | |
| #include <windows.h> | |
| #include <shellapi.h> | |
| #include <shlobj.h> | |
| #include <tchar.h> | |
| #endif // WEBRTC_WIN | |
| #include "rtc_base/checks.h" | |
| #include "rtc_base/logging.h" | |
| #include "rtc_base/pathutils.h" | |
| #include "rtc_base/stringutils.h" | |
| namespace rtc { | |
| static const char EMPTY_STR[] = ""; | |
| // EXT_DELIM separates a file basename from extension | |
| const char EXT_DELIM = '.'; | |
| // FOLDER_DELIMS separate folder segments and the filename | |
| const char* const FOLDER_DELIMS = "/\\"; | |
| // DEFAULT_FOLDER_DELIM is the preferred delimiter for this platform | |
| #ifdef WEBRTC_WIN | |
| const char DEFAULT_FOLDER_DELIM = '\\'; | |
| #else // !WEBRTC_WIN | |
| const char DEFAULT_FOLDER_DELIM = '/'; | |
| #endif // !WEBRTC_WIN | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // Pathname - parsing of pathnames into components, and vice versa | |
| /////////////////////////////////////////////////////////////////////////////// | |
| bool Pathname::IsFolderDelimiter(char ch) { | |
| return (nullptr != ::strchr(FOLDER_DELIMS, ch)); | |
| } | |
| char Pathname::DefaultFolderDelimiter() { | |
| return DEFAULT_FOLDER_DELIM; | |
| } | |
| Pathname::Pathname() | |
| : folder_delimiter_(DEFAULT_FOLDER_DELIM) { | |
| } | |
| Pathname::Pathname(const Pathname&) = default; | |
| Pathname::Pathname(Pathname&&) = default; | |
| Pathname::Pathname(const std::string& pathname) | |
| : folder_delimiter_(DEFAULT_FOLDER_DELIM) { | |
| SetPathname(pathname); | |
| } | |
| Pathname::Pathname(const std::string& folder, const std::string& filename) | |
| : folder_delimiter_(DEFAULT_FOLDER_DELIM) { | |
| SetPathname(folder, filename); | |
| } | |
| Pathname& Pathname::operator=(const Pathname&) = default; | |
| Pathname& Pathname::operator=(Pathname&&) = default; | |
| std::string Pathname::pathname() const { | |
| std::string pathname(folder_); | |
| pathname.append(basename_); | |
| pathname.append(extension_); | |
| if (pathname.empty()) { | |
| // Instead of the empty pathname, return the current working directory. | |
| pathname.push_back('.'); | |
| pathname.push_back(folder_delimiter_); | |
| } | |
| return pathname; | |
| } | |
| void Pathname::SetPathname(const std::string& pathname) { | |
| std::string::size_type pos = pathname.find_last_of(FOLDER_DELIMS); | |
| if (pos != std::string::npos) { | |
| SetFolder(pathname.substr(0, pos + 1)); | |
| SetFilename(pathname.substr(pos + 1)); | |
| } else { | |
| SetFolder(EMPTY_STR); | |
| SetFilename(pathname); | |
| } | |
| } | |
| void Pathname::SetPathname(const std::string& folder, | |
| const std::string& filename) { | |
| SetFolder(folder); | |
| SetFilename(filename); | |
| } | |
| void Pathname::SetFolder(const std::string& folder) { | |
| folder_.assign(folder); | |
| // Ensure folder ends in a path delimiter | |
| if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) { | |
| folder_.push_back(folder_delimiter_); | |
| } | |
| } | |
| void Pathname::AppendFolder(const std::string& folder) { | |
| folder_.append(folder); | |
| // Ensure folder ends in a path delimiter | |
| if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) { | |
| folder_.push_back(folder_delimiter_); | |
| } | |
| } | |
| bool Pathname::SetBasename(const std::string& basename) { | |
| if(basename.find_first_of(FOLDER_DELIMS) != std::string::npos) { | |
| return false; | |
| } | |
| basename_.assign(basename); | |
| return true; | |
| } | |
| bool Pathname::SetExtension(const std::string& extension) { | |
| if (extension.find_first_of(FOLDER_DELIMS) != std::string::npos || | |
| extension.find_first_of(EXT_DELIM, 1) != std::string::npos) { | |
| return false; | |
| } | |
| extension_.assign(extension); | |
| // Ensure extension begins with the extension delimiter | |
| if (!extension_.empty() && (extension_[0] != EXT_DELIM)) { | |
| extension_.insert(extension_.begin(), EXT_DELIM); | |
| } | |
| return true; | |
| } | |
| std::string Pathname::filename() const { | |
| std::string filename(basename_); | |
| filename.append(extension_); | |
| return filename; | |
| } | |
| bool Pathname::SetFilename(const std::string& filename) { | |
| std::string::size_type pos = filename.rfind(EXT_DELIM); | |
| if ((pos == std::string::npos) || (pos == 0)) { | |
| return SetExtension(EMPTY_STR) && SetBasename(filename); | |
| } else { | |
| return SetExtension(filename.substr(pos)) && SetBasename(filename.substr(0, pos)); | |
| } | |
| } | |
| /////////////////////////////////////////////////////////////////////////////// | |
| } // namespace rtc |