filename.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id$
  15. #ifndef __FILENAME_H
  16. #define __FILENAME_H
  17. #include <string>
  18. #include <strutil.h>
  19. namespace isc {
  20. namespace log {
  21. /// \brief Class to Manipulate Filenames
  22. ///
  23. /// This is a utility class to manipulate filenames. It repeats some of the
  24. /// features found in the Boost filename class, but is self-contained so avoids
  25. /// the need to link in the Boost library.
  26. ///
  27. /// A Unix-style filename comprises three parts:
  28. ///
  29. /// Directory - everything up to and including the last "/". If there is no
  30. /// "/" in the string, there is no directory component. Note that the
  31. /// requirement of a trailing slash eliminates the ambiguity of whether a
  32. /// component is a directory or not, e.g. in /alpha/beta", "beta" could be the
  33. /// name of a directory or is could be a file. The interpretation here is that
  34. /// "beta" is the name of a file (although that file could be a directory).
  35. ///
  36. /// Note: Under Windows, the drive letter is considered to be part of the
  37. /// directory specification. Unless this class becomes more widely-used on
  38. /// Windows, there is no point in adding redundant code.
  39. ///
  40. /// Name - everthing from the character after the last "/" up to but not
  41. /// including the last ".".
  42. ///
  43. /// Extension - everthing from the right-most "." (after the right-most "/") to
  44. /// the end of the string. If there is no "." after the last "/", there is
  45. /// no file extension.
  46. ///
  47. /// (Note that on Windows, this function will replace all "\" characters
  48. /// with "/" characters on input strings.)
  49. ///
  50. /// This class provides functions for extracting the components and for
  51. /// substituting components.
  52. class Filename {
  53. public:
  54. /// \brief Constructor
  55. Filename(const std::string& name) :
  56. full_name_(""), directory_(""), name_(""), extension_("")
  57. {
  58. setName(name);
  59. }
  60. /// \brief Sets Stored Filename
  61. ///
  62. /// \param name New name to replaced currently stored name
  63. void setName(const std::string& name) {
  64. full_name_ = isc::strutil::trim(name);
  65. #ifdef WIN32
  66. isc::strutil::normalizeSlash(full_name_);
  67. #endif
  68. split(full_name_, directory_, name_, extension_);
  69. }
  70. /// \return Stored Filename
  71. std::string fullName() const {
  72. return full_name_;
  73. }
  74. /// \return Directory of Given File Name
  75. std::string directory() const {
  76. return directory_;
  77. }
  78. /// \return Name of Given File Name
  79. std::string name() const {
  80. return name_;
  81. }
  82. /// \return Extension of Given File Name
  83. std::string extension() const {
  84. return extension_;
  85. }
  86. /// \brief Expand Name with Default
  87. ///
  88. /// A default file specified is supplied and used to fill in any missing
  89. /// fields. For example, if the name stored is "/a/b" and the supplied
  90. /// name is "c.d", the result is "/a/b.d": the only field missing from the
  91. /// stored name is the extension, which is supplied by the default.
  92. /// Another example would be to store "a.b" and to supply a default of
  93. /// "/c/d/" - the result is "/c/d/a.b". (Note that if the supplied default
  94. /// was "/c/d", the result would be "/c/a.b", even if "/c/d" were actually
  95. /// a directory.)
  96. ///
  97. /// \param defname Default name
  98. ///
  99. /// \return Name expanded with defname.
  100. std::string expandWithDefault(const std::string& defname) const;
  101. /// \brief Use as Default and Substitute into String
  102. ///
  103. /// Does essentially the inverse of expand(); that filled in the stored
  104. /// name with a default and returned the result. This treats the stored
  105. /// name as the default and uses it to fill in a given name. In essence,
  106. /// the code:
  107. /// \code
  108. /// Filename f("/a/b");
  109. /// result = f.expandWithdefault("c.d");
  110. /// \endcode
  111. /// gives as a result "/a/b.d". This is the same as:
  112. /// \code
  113. /// Filename f("c.d");
  114. /// result = f.useAsDefault("/a/b");
  115. /// \endcode
  116. ///
  117. /// \param name Name to expand
  118. ///
  119. /// \return Name expanded with stored name
  120. std::string useAsDefault(const std::string&) const;
  121. private:
  122. /// \brief Split Name into Components
  123. ///
  124. /// Splits the file name into the directory, name and extension parts.
  125. /// The name is assumed to have had back slashes replaced by forward
  126. /// slashes (if appropriate).
  127. ///
  128. /// \param full_name Name to split
  129. /// \param directory Returned directory part
  130. /// \param name Returned name part
  131. /// \param extension Returned extension part
  132. void split(const std::string& full_name, std::string& directory,
  133. std::string& name, std::string& extension) const;
  134. // Members
  135. std::string full_name_; ///< Given name
  136. std::string directory_; ///< Directory part
  137. std::string name_; ///< Name part
  138. std::string extension_; ///< Extension part
  139. };
  140. } // namespace log
  141. } // namespace isc
  142. #endif // __FILENAME_H