filename.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #ifndef FILENAME_H
  7. #define FILENAME_H
  8. #include <string>
  9. #include <util/strutil.h>
  10. namespace isc {
  11. namespace util {
  12. /// \brief Class to Manipulate Filenames
  13. ///
  14. /// This is a utility class to manipulate filenames. It repeats some of the
  15. /// features found in the Boost filename class, but is self-contained so avoids
  16. /// the need to link in the Boost library.
  17. ///
  18. /// A Unix-style filename comprises three parts:
  19. ///
  20. /// Directory - everything up to and including the last "/". If there is no
  21. /// "/" in the string, there is no directory component. Note that the
  22. /// requirement of a trailing slash eliminates the ambiguity of whether a
  23. /// component is a directory or not, e.g. in /alpha/beta", "beta" could be the
  24. /// name of a directory or is could be a file. The interpretation here is that
  25. /// "beta" is the name of a file (although that file could be a directory).
  26. ///
  27. /// Note: Under Windows, the drive letter is considered to be part of the
  28. /// directory specification. Unless this class becomes more widely-used on
  29. /// Windows, there is no point in adding redundant code.
  30. ///
  31. /// Name - everything from the character after the last "/" up to but not
  32. /// including the last ".".
  33. ///
  34. /// Extension - everything from the right-most "." (after the right-most "/") to
  35. /// the end of the string. If there is no "." after the last "/", there is
  36. /// no file extension.
  37. ///
  38. /// (Note that on Windows, this function will replace all "\" characters
  39. /// with "/" characters on input strings.)
  40. ///
  41. /// This class provides functions for extracting the components and for
  42. /// substituting components.
  43. class Filename {
  44. public:
  45. /// \brief Constructor
  46. Filename(const std::string& name) :
  47. full_name_(""), directory_(""), name_(""), extension_("")
  48. {
  49. setName(name);
  50. }
  51. /// \brief Sets Stored Filename
  52. ///
  53. /// \param name New name to replaced currently stored name
  54. void setName(const std::string& name) {
  55. full_name_ = isc::util::str::trim(name);
  56. #ifdef WIN32
  57. isc::util::str::normalizeSlash(full_name_);
  58. #endif
  59. split(full_name_, directory_, name_, extension_);
  60. }
  61. /// \return Stored Filename
  62. std::string fullName() const {
  63. return (full_name_);
  64. }
  65. /// \return Directory of Given File Name
  66. std::string directory() const {
  67. return (directory_);
  68. }
  69. /// \brief Set directory for the file
  70. ///
  71. /// \param new_directory The directory to set. If this is an empty
  72. /// string, the directory this filename object currently
  73. /// has will be removed.
  74. void setDirectory(const std::string& new_directory);
  75. /// \return Name of Given File Name
  76. std::string name() const {
  77. return (name_);
  78. }
  79. /// \return Extension of Given File Name
  80. std::string extension() const {
  81. return (extension_);
  82. }
  83. /// \return Name + extension of Given File Name
  84. std::string nameAndExtension() const {
  85. return (name_ + extension_);
  86. }
  87. /// \brief Expand Name with Default
  88. ///
  89. /// A default file specified is supplied and used to fill in any missing
  90. /// fields. For example, if the name stored is "/a/b" and the supplied
  91. /// name is "c.d", the result is "/a/b.d": the only field missing from the
  92. /// stored name is the extension, which is supplied by the default.
  93. /// Another example would be to store "a.b" and to supply a default of
  94. /// "/c/d/" - the result is "/c/d/a.b". (Note that if the supplied default
  95. /// was "/c/d", the result would be "/c/a.b", even if "/c/d" were actually
  96. /// a directory.)
  97. ///
  98. /// \param defname Default name
  99. ///
  100. /// \return Name expanded with defname.
  101. std::string expandWithDefault(const std::string& defname) const;
  102. /// \brief Use as Default and Substitute into String
  103. ///
  104. /// Does essentially the inverse of expand(); that filled in the stored
  105. /// name with a default and returned the result. This treats the stored
  106. /// name as the default and uses it to fill in a given name. In essence,
  107. /// the code:
  108. /// \code
  109. /// Filename f("/a/b");
  110. /// result = f.expandWithdefault("c.d");
  111. /// \endcode
  112. /// gives as a result "/a/b.d". This is the same as:
  113. /// \code
  114. /// Filename f("c.d");
  115. /// result = f.useAsDefault("/a/b");
  116. /// \endcode
  117. ///
  118. /// \param name Name to expand
  119. ///
  120. /// \return Name expanded with stored name
  121. std::string useAsDefault(const std::string& name) const;
  122. private:
  123. /// \brief Split Name into Components
  124. ///
  125. /// Splits the file name into the directory, name and extension parts.
  126. /// The name is assumed to have had back slashes replaced by forward
  127. /// slashes (if appropriate).
  128. ///
  129. /// \param full_name Name to split
  130. /// \param directory Returned directory part
  131. /// \param name Returned name part
  132. /// \param extension Returned extension part
  133. void split(const std::string& full_name, std::string& directory,
  134. std::string& name, std::string& extension) const;
  135. // Members
  136. std::string full_name_; ///< Given name
  137. std::string directory_; ///< Directory part
  138. std::string name_; ///< Name part
  139. std::string extension_; ///< Extension part
  140. };
  141. } // namespace util
  142. } // namespace isc
  143. #endif // FILENAME_H