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 __MESSAGE_READER_H
16 : : #define __MESSAGE_READER_H
17 : :
18 : : #include <map>
19 : : #include <string>
20 : : #include <vector>
21 : :
22 : : #include <log/message_dictionary.h>
23 : : #include <log/message_types.h>
24 : :
25 : : namespace isc {
26 : : namespace log {
27 : :
28 : : /// \brief Read Message File
29 : : ///
30 : : /// Reads a message file and creates a map of identifier against the text of the
31 : : /// message. This map can be retrieved for subsequent processing.
32 : :
33 : : class MessageReader {
34 : : public:
35 : :
36 : : /// \brief Read Mode
37 : : ///
38 : : /// If ADD, messages are added to the dictionary if the ID does not exist
39 : : /// there. If it does, the ID is added to the dictionary's overflow
40 : : /// vector.
41 : : ///
42 : : /// If REPLACE, the dictionary is only modified if the message ID already
43 : : /// exists in it. New message IDs are added to the overflow vector.
44 : : typedef enum {
45 : : ADD,
46 : : REPLACE
47 : : } Mode;
48 : :
49 : : /// \brief Visible collection types
50 : : typedef std::vector<std::string> MessageIDCollection;
51 : :
52 : : /// \brief Constructor
53 : : ///
54 : : /// Default constructor. All work is done in the main readFile code (so
55 : : /// that a status return can be returned instead of needing to throw an
56 : : /// exception).
57 : : ///
58 : : /// \param dictionary Dictionary to which messages read read from the file
59 : : /// are added. (This should be a local dictionary when the class is used in
60 : : /// the message compiler, and the global dictionary when used in a server.
61 : : /// The ownership of the dictionary object is not transferred - the caller
62 : : /// is responsible for managing the lifetime of the dictionary.
63 : : MessageReader(MessageDictionary* dictionary = NULL) :
64 : 39 : dictionary_(dictionary), lineno_(0)
65 : : {}
66 : :
67 : : /// \brief Virtual Destructor
68 : 13 : virtual ~MessageReader()
69 : 13 : {}
70 : :
71 : : /// \brief Get Dictionary
72 : : ///
73 : : /// Returns the pointer to the dictionary object. Note that ownership is
74 : : /// not transferred - the caller should not delete it.
75 : : ///
76 : : /// \return Pointer to current dictionary object
77 : 0 : MessageDictionary* getDictionary() const {
78 : 0 : return (dictionary_);
79 : : }
80 : :
81 : :
82 : : /// \brief Set Dictionary
83 : : ///
84 : : /// Sets the current dictionary object.
85 : : ///
86 : : /// \param dictionary New dictionary object. The ownership of the dictionary
87 : : /// object is not transferred - the caller is responsible for managing the
88 : : /// lifetime of the dictionary.
89 : 0 : void setDictionary(MessageDictionary* dictionary) {
90 : 10 : dictionary_ = dictionary;
91 : 0 : }
92 : :
93 : :
94 : : /// \brief Read File
95 : : ///
96 : : /// This is the main method of the class and reads in the file, parses it,
97 : : /// and stores the result in the message dictionary.
98 : : ///
99 : : /// \param file Name of the message file.
100 : : /// \param mode Addition mode. See the description of the "Mode" enum.
101 : : virtual void readFile(const std::string& file, Mode mode = ADD);
102 : :
103 : :
104 : : /// \brief Process Line
105 : : ///
106 : : /// Parses a text line and adds it to the message map. Although this is
107 : : /// for use in readFile, it can also be used to add individual messages
108 : : /// to the message map.
109 : : ///
110 : : /// \param line Line of text to process
111 : : /// \param mode If a message line, how to add the message to the dictionary.
112 : : virtual void processLine(const std::string& line, Mode mode = ADD);
113 : :
114 : :
115 : : /// \brief Get Namespace
116 : : ///
117 : : /// \return Argument to the $NAMESPACE directive (if present)
118 : 0 : virtual std::string getNamespace() const {
119 : 5 : return (ns_);
120 : : }
121 : :
122 : :
123 : : /// \brief Clear Namespace
124 : : ///
125 : : /// Clears the current namespace.
126 : 0 : virtual void clearNamespace() {
127 : 2 : ns_ = "";
128 : 0 : }
129 : :
130 : :
131 : : /// \brief Get Prefix
132 : : ///
133 : : /// \return Argument to the $PREFIX directive (if present)
134 : 0 : virtual std::string getPrefix() const {
135 : 5 : return (prefix_);
136 : : }
137 : :
138 : :
139 : : /// \brief Clear Prefix
140 : : ///
141 : : /// Clears the current prefix.
142 : 0 : virtual void clearPrefix() {
143 : 1 : prefix_ = "";
144 : 0 : }
145 : :
146 : :
147 : : /// \brief Get Not-Added List
148 : : ///
149 : : /// Returns the list of IDs that were not added during the last
150 : : /// read of the file.
151 : : ///
152 : : /// \return Collection of messages not added
153 : 5 : MessageIDCollection getNotAdded() const {
154 [ + - ]: 6 : return (not_added_);
155 : : }
156 : :
157 : : private:
158 : :
159 : : /// \brief Handle a Message Definition
160 : : ///
161 : : /// Passed a line that should contain a message, this processes that line
162 : : /// and adds it to the dictionary according to the mode setting.
163 : : ///
164 : : /// \param line Line of text
165 : : /// \param ADD or REPLACE depending on how the reader is operating. (See
166 : : /// the description of the Mode typedef for details.)
167 : : void parseMessage(const std::string& line, Mode mode);
168 : :
169 : :
170 : : /// \brief Handle Directive
171 : : ///
172 : : /// Passed a line starting with a "$", this handles the processing of
173 : : /// directives.
174 : : ///
175 : : /// \param line Line of text that starts with "$",
176 : : void parseDirective(const std::string& line);
177 : :
178 : :
179 : : /// \brief Parse $PREFIX line
180 : : ///
181 : : /// \param tokens $PREFIX line split into tokens
182 : : void parsePrefix(const std::vector<std::string>& tokens);
183 : :
184 : :
185 : : /// \brief Parse $NAMESPACE line
186 : : ///
187 : : /// \param tokens $NAMESPACE line split into tokens
188 : : void parseNamespace(const std::vector<std::string>& tokens);
189 : :
190 : : /// \brief Check for invalid C++ symbol name
191 : : ///
192 : : /// The message ID (or concatenation of prefix and message ID) will be used
193 : : /// as the name of a symbol in C++ code. This function checks if the name
194 : : /// is invalid (contains anything other than alphanumeric characters or
195 : : /// underscores, or starts with a digit).
196 : : ///
197 : : /// \param symbol name to check to see if it is an invalid C++ symbol.
198 : : ///
199 : : /// \return true if the name is invalid, false if it is valid.
200 : : bool invalidSymbol(const std::string& symbol);
201 : :
202 : :
203 : :
204 : : /// Attributes
205 : : MessageDictionary* dictionary_; ///< Dictionary to add messages to
206 : : MessageIDCollection not_added_; ///< List of IDs not added
207 : : int lineno_; ///< Number of last line read
208 : : std::string prefix_; ///< Argument of $PREFIX statement
209 : : std::string ns_; ///< Argument of $NAMESPACE statement
210 : : };
211 : :
212 : : } // namespace log
213 : : } // namespace isc
214 : :
215 : : #endif // __MESSAGE_READER_H
|