|
| 1 | +#ifndef SOURCEMETA_CORE_PUNYCODE_H_ |
| 2 | +#define SOURCEMETA_CORE_PUNYCODE_H_ |
| 3 | + |
| 4 | +#ifndef SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 5 | +#include <sourcemeta/core/punycode_export.h> |
| 6 | +#endif |
| 7 | + |
| 8 | +// NOLINTBEGIN(misc-include-cleaner) |
| 9 | +#include <sourcemeta/core/punycode_error.h> |
| 10 | +// NOLINTEND(misc-include-cleaner) |
| 11 | + |
| 12 | +#include <istream> // std::istream |
| 13 | +#include <ostream> // std::ostream |
| 14 | +#include <string> // std::string, std::u32string |
| 15 | +#include <string_view> // std::string_view, std::u32string_view |
| 16 | + |
| 17 | +/// @defgroup punycode Punycode |
| 18 | +/// @brief An implementation of RFC 3492 Punycode. |
| 19 | +/// |
| 20 | +/// This functionality is included as follows: |
| 21 | +/// |
| 22 | +/// ```cpp |
| 23 | +/// #include <sourcemeta/core/punycode.h> |
| 24 | +/// ``` |
| 25 | + |
| 26 | +namespace sourcemeta::core { |
| 27 | + |
| 28 | +// See https://www.rfc-editor.org/rfc/rfc3492 |
| 29 | + |
| 30 | +/// @ingroup punycode |
| 31 | +/// Encode Unicode code points (UTF-32) to Punycode. For example: |
| 32 | +/// |
| 33 | +/// ```cpp |
| 34 | +/// #include <sourcemeta/core/punycode.h> |
| 35 | +/// #include <cassert> |
| 36 | +/// |
| 37 | +/// const std::u32string input{0x0048, 0x0065, 0x006C, 0x006C, 0x006F, |
| 38 | +/// 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, |
| 39 | +/// 0x306E, 0x5834, 0x6240}; |
| 40 | +/// assert(sourcemeta::core::utf32_to_punycode(input) == |
| 41 | +/// "Hello--fc4qua05auwb3674vfr0b"); |
| 42 | +/// ``` |
| 43 | +/// |
| 44 | +/// Note that stream-based overloads for UTF-32 are not provided |
| 45 | +/// because the C++ standard library does not define the required locale facets |
| 46 | +/// (`std::ctype<char32_t>`) for `std::basic_istream<char32_t>` and |
| 47 | +/// `std::basic_ostream<char32_t>` to function properly. |
| 48 | +SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 49 | +auto utf32_to_punycode(std::u32string_view input) -> std::string; |
| 50 | + |
| 51 | +/// @ingroup punycode |
| 52 | +/// Encode UTF-8 to Punycode using streams. For example: |
| 53 | +/// |
| 54 | +/// ```cpp |
| 55 | +/// #include <sourcemeta/core/punycode.h> |
| 56 | +/// #include <sstream> |
| 57 | +/// #include <cassert> |
| 58 | +/// |
| 59 | +/// std::istringstream input{"M\xC3\xBCnchen"}; |
| 60 | +/// std::ostringstream output; |
| 61 | +/// sourcemeta::core::utf8_to_punycode(input, output); |
| 62 | +/// assert(output.str() == "Mnchen-3ya"); |
| 63 | +/// ``` |
| 64 | +SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 65 | +auto utf8_to_punycode(std::istream &input, std::ostream &output) -> void; |
| 66 | + |
| 67 | +/// @ingroup punycode |
| 68 | +/// Encode UTF-8 to Punycode. For example: |
| 69 | +/// |
| 70 | +/// ```cpp |
| 71 | +/// #include <sourcemeta/core/punycode.h> |
| 72 | +/// #include <cassert> |
| 73 | +/// |
| 74 | +/// assert(sourcemeta::core::utf8_to_punycode("M\xC3\xBCnchen") == |
| 75 | +/// "Mnchen-3ya"); |
| 76 | +/// ``` |
| 77 | +SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 78 | +auto utf8_to_punycode(std::string_view input) -> std::string; |
| 79 | + |
| 80 | +/// @ingroup punycode |
| 81 | +/// Decode Punycode to Unicode code points (UTF-32). For example: |
| 82 | +/// |
| 83 | +/// ```cpp |
| 84 | +/// #include <sourcemeta/core/punycode.h> |
| 85 | +/// #include <cassert> |
| 86 | +/// |
| 87 | +/// const std::u32string expected{0x0048, 0x0065, 0x006C, 0x006C, 0x006F, |
| 88 | +/// 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, |
| 89 | +/// 0x306E, 0x5834, 0x6240}; |
| 90 | +/// assert(sourcemeta::core::punycode_to_utf32("Hello--fc4qua05auwb3674vfr0b") |
| 91 | +/// == |
| 92 | +/// expected); |
| 93 | +/// ``` |
| 94 | +/// |
| 95 | +/// Note that stream-based overloads for UTF-32 are not provided |
| 96 | +/// because the C++ standard library does not define the required locale facets |
| 97 | +/// (`std::ctype<char32_t>`) for `std::basic_istream<char32_t>` and |
| 98 | +/// `std::basic_ostream<char32_t>` to function properly. |
| 99 | +SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 100 | +auto punycode_to_utf32(std::string_view input) -> std::u32string; |
| 101 | + |
| 102 | +/// @ingroup punycode |
| 103 | +/// Decode Punycode to UTF-8 using streams. For example: |
| 104 | +/// |
| 105 | +/// ```cpp |
| 106 | +/// #include <sourcemeta/core/punycode.h> |
| 107 | +/// #include <sstream> |
| 108 | +/// #include <cassert> |
| 109 | +/// |
| 110 | +/// std::istringstream input{"Mnchen-3ya"}; |
| 111 | +/// std::ostringstream output; |
| 112 | +/// sourcemeta::core::punycode_to_utf8(input, output); |
| 113 | +/// assert(output.str() == "M\xC3\xBCnchen"); |
| 114 | +/// ``` |
| 115 | +SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 116 | +auto punycode_to_utf8(std::istream &input, std::ostream &output) -> void; |
| 117 | + |
| 118 | +/// @ingroup punycode |
| 119 | +/// Decode Punycode to UTF-8. For example: |
| 120 | +/// |
| 121 | +/// ```cpp |
| 122 | +/// #include <sourcemeta/core/punycode.h> |
| 123 | +/// #include <cassert> |
| 124 | +/// |
| 125 | +/// assert(sourcemeta::core::punycode_to_utf8("Mnchen-3ya") == |
| 126 | +/// "M\xC3\xBCnchen"); |
| 127 | +/// ``` |
| 128 | +SOURCEMETA_CORE_PUNYCODE_EXPORT |
| 129 | +auto punycode_to_utf8(std::string_view input) -> std::string; |
| 130 | + |
| 131 | +} // namespace sourcemeta::core |
| 132 | + |
| 133 | +#endif |
0 commit comments