gnu_gettext.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // https://www.boost.org/LICENSE_1_0.txt
  6. #ifndef BOOST_LOCLAE_GNU_GETTEXT_HPP
  7. #define BOOST_LOCLAE_GNU_GETTEXT_HPP
  8. #include <boost/locale/message.hpp>
  9. #include <functional>
  10. #include <stdexcept>
  11. #include <vector>
  12. namespace boost { namespace locale {
  13. /// \addtogroup message
  14. /// @{
  15. /// \brief This namespace holds classes that provide GNU Gettext message catalogs support.
  16. namespace gnu_gettext {
  17. /// \brief This structure holds all information required for creating gnu-gettext message catalogs,
  18. ///
  19. /// The user is expected to set its parameters to load these catalogs correctly. This structure
  20. /// also allows providing functions for charset conversion. Note, you need to provide them,
  21. /// so this structure is not useful for wide characters without subclassing and it will also
  22. /// ignore gettext catalogs that use a charset different from \a encoding.
  23. struct messages_info {
  24. messages_info() : language("C"), locale_category("LC_MESSAGES") {}
  25. std::string language; ///< The language we load the catalog for, like "ru", "en", "de"
  26. std::string country; ///< The country we load the catalog for, like "US", "IL"
  27. std::string variant; ///< Language variant, like "euro" so it would look for catalog like de_DE\@euro
  28. std::string encoding; ///< Required target charset encoding. Ignored for wide characters.
  29. ///< For narrow, should specify the correct encoding required for this catalog
  30. std::string locale_category; ///< Locale category, is set by default to LC_MESSAGES, but may be changed
  31. ///
  32. /// \brief This type represents GNU Gettext domain name for the messages.
  33. ///
  34. /// It consists of two parameters:
  35. ///
  36. /// - name - the name of the domain - used for opening the file name
  37. /// - encoding - the encoding of the keys in the sources, default - UTF-8
  38. ///
  39. struct domain {
  40. std::string name; ///< The name of the domain
  41. std::string encoding; ///< The character encoding for the domain
  42. domain() = default;
  43. /// Create a domain object from the name that can hold an encoding after symbol "/"
  44. /// such that if n is "hello/cp1255" then the name would be "hello" and "encoding" would
  45. /// be "cp1255" and if n is "hello" then the name would be the same but encoding would be
  46. /// "UTF-8"
  47. domain(const std::string& n)
  48. {
  49. size_t pos = n.find('/');
  50. if(pos == std::string::npos) {
  51. name = n;
  52. encoding = "UTF-8";
  53. } else {
  54. name = n.substr(0, pos);
  55. encoding = n.substr(pos + 1);
  56. }
  57. }
  58. /// Check whether two objects are equivalent, only names are compared, encoding is ignored
  59. bool operator==(const domain& other) const { return name == other.name; }
  60. /// Check whether two objects are distinct, only names are compared, encoding is ignored
  61. bool operator!=(const domain& other) const { return !(*this == other); }
  62. };
  63. typedef std::vector<domain> domains_type; ///< Type that defines a list of domains that are loaded
  64. ///< The first one is the default one
  65. domains_type domains; ///< Message domains - application name, like my_app. So files named my_app.mo
  66. ///< would be loaded
  67. std::vector<std::string> paths; ///< Paths to search files in. Under MS Windows it uses encoding
  68. ///< parameter to convert them to wide OS specific paths.
  69. /// The callback for custom file system support. This callback should read the file named \a file_name
  70. /// encoded in \a encoding character set into std::vector<char> and return it.
  71. ///
  72. /// - If the file does not exist, it should return an empty vector.
  73. /// - If a error occurs during file read it should throw a error.
  74. ///
  75. /// \note The user should support only the encodings the locales are created for. So if the user
  76. /// uses only one encoding or the file system is encoding agnostic, he may ignore the \a encoding parameter.
  77. typedef std::function<std::vector<char>(const std::string& file_name, const std::string& encoding)>
  78. callback_type;
  79. /// The callback for handling custom file systems, if it is empty, the real OS file-system
  80. /// is being used.
  81. callback_type callback;
  82. };
  83. /// Create a message_format facet using GNU Gettext catalogs. It uses \a info structure to get
  84. /// information about where to read them from and uses it for character set conversion (if needed)
  85. template<typename CharType>
  86. message_format<CharType>* create_messages_facet(const messages_info& info);
  87. /// \cond INTERNAL
  88. template<>
  89. BOOST_LOCALE_DECL message_format<char>* create_messages_facet(const messages_info& info);
  90. template<>
  91. BOOST_LOCALE_DECL message_format<wchar_t>* create_messages_facet(const messages_info& info);
  92. #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
  93. template<>
  94. BOOST_LOCALE_DECL message_format<char16_t>* create_messages_facet(const messages_info& info);
  95. #endif
  96. #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
  97. template<>
  98. BOOST_LOCALE_DECL message_format<char32_t>* create_messages_facet(const messages_info& info);
  99. #endif
  100. /// \endcond
  101. } // namespace gnu_gettext
  102. /// @}
  103. }} // namespace boost::locale
  104. #endif