Botan 3.13.0
Crypto and TLS for C&
charset.h
Go to the documentation of this file.
1/*
2* Character Set Conversions
3* (C) 1999-2007 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_CHARSET_H_
9#define BOTAN_CHARSET_H_
10
11#include <botan/types.h>
12#include <array>
13#include <span>
14#include <string>
15#include <string_view>
16#include <vector>
17
18namespace Botan {
19
20/**
21* Convert a sequence of UCS-2 (big endian) characters to a UTF-8 string
22* This is used for ASN.1 BMPString type
23* @param ucs2 the sequence of UCS-2 characters, length must be a multiple of 2
24*/
25BOTAN_TEST_API std::string ucs2_to_utf8(std::span<const uint8_t> ucs2);
26
27/**
28 * Convert a UTF-8 string to a sequence of UCS-2 (big endian) characters
29 * This is used for ASN.1 BMPString type
30 * @param utf8 the UTF-8 string
31 * @return a vector of bytes containing the UCS-2 (big endian) encoding
32 * @throws Decoding_Error if the input is not valid UTF-8 (including overlong encodings,
33 * surrogate code points, or values outside Unicode), or if a code point exceeds
34 * U+FFFF and cannot be represented in UCS-2
35 */
36BOTAN_TEST_API std::vector<uint8_t> utf8_to_ucs2(std::string_view utf8);
37
38/**
39* Convert a sequence of UCS-4 (big endian) characters to a UTF-8 string
40* This is used for ASN.1 UniversalString type
41* @param ucs4 the sequence of UCS-4 characters, length must be a multiple of 4
42*/
43BOTAN_TEST_API std::string ucs4_to_utf8(std::span<const uint8_t> ucs4);
44
45/**
46 * Convert a UTF-8 string to a sequence of UCS-4 (big endian) characters
47 * This is used for ASN.1 UniversalString type
48 * @param utf8 the UTF-8 string
49 * @return a vector of bytes containing the UCS-4 (big endian) encoding
50 * @throws Decoding_Error if the input is not valid UTF-8 (including overlong encodings,
51 * surrogate code points, or values outside the Unicode scalar value range U+0000..U+10FFFF)
52 */
53BOTAN_TEST_API std::vector<uint8_t> utf8_to_ucs4(std::string_view utf8);
54
55BOTAN_TEST_API std::string latin1_to_utf8(std::span<const uint8_t> latin1);
56
57/**
58* Return true if this string seems to contain a valid sequence of UTF-8
59*/
60bool is_valid_utf8(std::string_view str);
61
62/**
63* Return true if c is a control character (0x00..0x1F) or DEL (0x7F)
64*/
66
67/**
68* Return true if the Unicode code point cp is a control character: a C0 control
69* (U+0000..U+001F), DEL (U+007F), or a C1 control (U+0080..U+009F)
70*/
72
73/**
74* Map the low four bits of b to an uppercase hex digit ('0'..'9','A'..'F')
75*/
76inline constexpr char nibble_to_hex(uint8_t b) {
77 const uint8_t n = b & 0x0F;
78 return static_cast<char>(n < 10 ? '0' + n : 'A' + (n - 10));
79}
80
81/**
82* Decode the UTF-8 code point beginning at utf8[pos], advancing pos past it
83* @throws Decoding_Error if the bytes at pos are not a valid UTF-8 sequence
84*/
85uint32_t next_utf8_codepoint(std::string_view utf8, size_t& pos);
86
87/**
88* Return a copy of utf8 with control characters escaped for safe display
89*
90* C0 controls (0x00..0x1F), DEL (0x7F), and C1 controls (U+0080..U+009F) are
91* each replaced by a "\xHH" escape per byte; all other code points, including
92* printable non-ASCII, are passed through unchanged. Any byte that is not part
93* of a valid UTF-8 sequence is escaped individually.
94*/
95BOTAN_TEST_API std::string escape_control_chars(std::string_view utf8);
96
97/**
98* Return a string containing 'c', quoted and possibly escaped
99*
100* This is used when creating an error message noting an invalid character
101* in some codec (for example during hex decoding)
102*
103* Tab, newline, and carriage return are escaped as "\t", "\n", and "\r".
104* Any other control character (or DEL), and any byte above 0x7F, is escaped
105* as "\xHH" where HH is the hex code.
106*/
107std::string format_char_for_display(char c);
108
109/**
110* Character classifier
111*/
112class CharacterValidityTable final {
113 public:
114 static constexpr CharacterValidityTable alpha_numeric_plus(std::string_view extras) {
115 TableStorage tbl{};
116
117 set_tbl_range(tbl, "0123456789");
118 set_tbl_range(tbl, "abcdefghijklmnopqrstuvwxyz");
119 set_tbl_range(tbl, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
120 set_tbl_range(tbl, extras);
121
122 return CharacterValidityTable(tbl);
123 }
124
125 constexpr bool operator()(char c) const {
126 const uint8_t uc = static_cast<uint8_t>(c);
127 return ((m_tbl[uc / 32] >> (uc % 32)) & 1) != 0;
128 }
129
130 constexpr CharacterValidityTable invert() const {
131 TableStorage inverted = m_tbl;
132 for(auto& v : inverted) {
133 v = ~v;
134 }
135 return CharacterValidityTable(inverted);
136 }
137
138 private:
139 using TableStorage = std::array<uint32_t, 8>; // 256 bits of storage
140
141 static constexpr void set_tbl_range(TableStorage& tbl, std::string_view valid_chars) {
142 for(const char c : valid_chars) {
143 const uint8_t uc = static_cast<uint8_t>(c);
144 tbl[uc / 32] |= (uint32_t{1} << (uc % 32));
145 }
146 }
147
148 explicit constexpr CharacterValidityTable(TableStorage tbl) : m_tbl(tbl) {}
149
150 TableStorage m_tbl;
151};
152
153} // namespace Botan
154
155#endif
#define BOTAN_TEST_API
Definition api.h:41
static constexpr CharacterValidityTable alpha_numeric_plus(std::string_view extras)
Definition charset.h:114
constexpr CharacterValidityTable invert() const
Definition charset.h:130
constexpr bool operator()(char c) const
Definition charset.h:125
std::string format_char_for_display(char c)
Definition charset.cpp:243
constexpr char nibble_to_hex(uint8_t b)
Definition charset.h:76
bool is_unicode_control_char(uint32_t cp)
Definition charset.cpp:203
bool is_valid_utf8(std::string_view utf8)
Definition charset.cpp:108
std::string latin1_to_utf8(std::span< const uint8_t > chars)
Definition charset.cpp:190
std::vector< uint8_t > utf8_to_ucs4(std::string_view utf8)
Definition charset.cpp:171
bool is_ascii_control_char(char c)
Definition charset.cpp:198
uint32_t next_utf8_codepoint(std::string_view utf8, size_t &pos)
Definition charset.cpp:53
std::string ucs2_to_utf8(std::span< const uint8_t > ucs2)
Definition charset.cpp:121
std::string ucs4_to_utf8(std::span< const uint8_t > ucs4)
Definition charset.cpp:155
std::string escape_control_chars(std::string_view utf8)
Definition charset.cpp:207
std::vector< uint8_t > utf8_to_ucs2(std::string_view utf8)
Definition charset.cpp:137