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