message_reader.h 6.8 KB

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