diff options
Diffstat (limited to 'src/lib/util/filename.cc')
-rw-r--r-- | src/lib/util/filename.cc | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/lib/util/filename.cc b/src/lib/util/filename.cc new file mode 100644 index 0000000..8cd9cd3 --- /dev/null +++ b/src/lib/util/filename.cc @@ -0,0 +1,148 @@ +// Copyright (C) 2011-2021 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <iostream> +#include <algorithm> +#include <string> + +#include <ctype.h> + +#include <util/filename.h> + +using namespace std; + + +namespace isc { +namespace util { + +// Split string into components. Any backslashes are assumed to have +// been replaced by forward slashes. + +void +Filename::split(const string& full_name, string& directory, string& name, + string& extension) const { + directory = name = extension = ""; + if (!full_name.empty()) { + + bool dir_present = false; + // Find the directory. + size_t last_slash = full_name.find_last_of('/'); + if (last_slash != string::npos) { + + // Found the last slash, so extract directory component and + // set where the scan for the last_dot should terminate. + directory = full_name.substr(0, last_slash + 1); + if (last_slash == full_name.size()) { + + // The entire string was a directory, so exit not and don't + // do any more searching. + return; + } + + // Found a directory so note the fact. + dir_present = true; + } + + // Now search backwards for the last ".". + size_t last_dot = full_name.find_last_of('.'); + if ((last_dot == string::npos) || + (dir_present && (last_dot < last_slash))) { + + // Last "." either not found or it occurs to the left of the last + // slash if a directory was present (so it is part of a directory + // name). In this case, the remainder of the string after the slash + // is the name part. + name = full_name.substr(last_slash + 1); + return; + } + + // Did find a valid dot, so it and everything to the right is the + // extension... + extension = full_name.substr(last_dot); + + // ... and the name of the file is everything in between. + if ((last_dot - last_slash) > 1) { + name = full_name.substr(last_slash + 1, last_dot - last_slash - 1); + } + } + +} + +// Expand the stored filename with the default. + +string +Filename::expandWithDefault(const string& defname) const { + + string def_directory(""); + string def_name(""); + string def_extension(""); + + // Normalize the input string. + string copy_defname = isc::util::str::trim(defname); +#ifdef WIN32 + isc::util::str::normalizeSlash(copy_defname); +#endif + + // Split into the components + split(copy_defname, def_directory, def_name, def_extension); + + // Now construct the result. + string retstring = + (directory_.empty() ? def_directory : directory_) + + (name_.empty() ? def_name : name_) + + (extension_.empty() ? def_extension : extension_); + return (retstring); +} + +// Use the stored name as default for a given name + +string +Filename::useAsDefault(const string& name) const { + + string name_directory(""); + string name_name(""); + string name_extension(""); + + // Normalize the input string. + string copy_name = isc::util::str::trim(name); +#ifdef WIN32 + isc::util::str::normalizeSlash(copy_name); +#endif + + // Split into the components + split(copy_name, name_directory, name_name, name_extension); + + // Now construct the result. + string retstring = + (name_directory.empty() ? directory_ : name_directory) + + (name_name.empty() ? name_ : name_name) + + (name_extension.empty() ? extension_ : name_extension); + return (retstring); +} + +void +Filename::setDirectory(const std::string& new_directory) { + std::string directory(new_directory); + + if (directory.length() > 0) { + // append '/' if necessary + size_t sep = directory.rfind('/'); + if (sep == std::string::npos || sep < directory.size() - 1) { + directory += "/"; + } + } + // and regenerate the full name + std::string full_name = directory + name_ + extension_; + + directory_.swap(directory); + full_name_.swap(full_name); +} + + +} // namespace log +} // namespace isc |