BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlde_charconvertutf16.h
Go to the documentation of this file.
1/// @file bdlde_charconvertutf16.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlde_charconvertutf16.h -*-C++-*-
8#ifndef INCLUDED_BDLDE_CHARCONVERTUTF16
9#define INCLUDED_BDLDE_CHARCONVERTUTF16
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlde_charconvertutf16 bdlde_charconvertutf16
15/// @brief Provide fast, safe conversion between UTF-8 and UTF-16 encodings.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlde
19/// @{
20/// @addtogroup bdlde_charconvertutf16
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlde_charconvertutf16-purpose"> Purpose</a>
25/// * <a href="#bdlde_charconvertutf16-classes"> Classes </a>
26/// * <a href="#bdlde_charconvertutf16-description"> Description </a>
27/// * <a href="#bdlde_charconvertutf16-history-and-motivation"> History and Motivation </a>
28/// * <a href="#bdlde_charconvertutf16-wstrings-and-utf-16"> WSTRINGS and UTF-16 </a>
29/// * <a href="#bdlde_charconvertutf16-usage"> Usage </a>
30/// * <a href="#bdlde_charconvertutf16-example-1-translation-to-fixed-length-buffers"> Example 1: Translation to Fixed-Length Buffers </a>
31/// * <a href="#bdlde_charconvertutf16-example-2-translation-to-stl-containers"> Example 2: Translation to STL Containers </a>
32///
33/// # Purpose {#bdlde_charconvertutf16-purpose}
34/// Provide fast, safe conversion between UTF-8 and UTF-16 encodings.
35///
36/// # Classes {#bdlde_charconvertutf16-classes}
37///
38/// - bdlde::CharConvertUtf16: namespace for conversions between UTF-8 and UTF-16
39///
40/// # Description {#bdlde_charconvertutf16-description}
41/// This component provides a suite of static functions supporting
42/// the *fast* conversion of *valid* UTF-8 encoded strings to *valid* UTF-16
43/// 16-bit word arrays, wstrings, and vectors, and conversion of *valid* UTF-16
44/// encoded word sequences to *valid* UTF-8 byte arrays, strings, and byte
45/// vectors. Invalid byte sequences and code points forbidden by either
46/// encoding are removed and (optionally) replaced by a single word or byte
47/// provided by the caller. In UTF-16 -> UTF-8 conversion, the replacement word
48/// must be a non-zero byte, in the other direction, it must be a single,
49/// non-zero word. The byte or word count and code point count that are
50/// optionally returned through pointer arguments include the terminating null
51/// code point in their count. The byte order of the UTF-16 input or output can
52/// be specified via the optional `byteOrder` argument, which is assumed to be
53/// host byte order if not specified. In functions taking UTF-8, input is in
54/// the form of a `bslstl::StringRef` or a null-terminated `const char *`. In
55/// functions taking UTF-16, input is either in the form of a
56/// `bslstl::StringRefWide` or a pointer to a null-terminated array of
57/// `unsigned short` or `wchar_t`.
58///
59/// ## History and Motivation {#bdlde_charconvertutf16-history-and-motivation}
60///
61///
62/// UTF-8 is an encoding that allows 32-bit character sets like Unicode
63/// to be represented using (8-bit) byte strings, while allowing "standard
64/// ASCII" strings to be used "as-is". Note that UTF-8 is described in detail
65/// in RFC 3629 (http://www.ietf.org/rfc/rfc3629.txt).
66///
67/// UTF-16 is a 16-bit encoding that allows Unicode code points up to 0x10ffff
68/// to be encoded using one or two 16-bit values. Note that UTF-16 is described
69/// in detail in RFC 2781 (http://www.ietf.org/rfc/rfc2781.txt).
70///
71/// The functions here that translate to fixed buffers make a single pass
72/// through the data. The functions that translate to `bsl::string`s and STL
73/// containers, however, like the `glib` conversion routines, make two passes: a
74/// size estimation pass, after which the output container is sized
75/// appropriately, and then the translation pass.
76///
77/// The methods that output to a `vector`, `string`, or `wstring` will all grow
78/// the output object as necessary to fit the data, and in the end will exactly
79/// resize the object to the output (including the terminating 0 for `vector`,
80/// which is not included for `string` or `wstring`). Note that in the case of
81/// `string` or `wstring`, the terminating 0 code point is still included in the
82/// code point count.
83///
84/// Non-minimal UTF-8 encodings of code points are reported as errors. Octets
85/// and post-conversion code points in the forbidden ranges are treated as
86/// errors and removed (or replaced, if a replacement word is provided).
87///
88/// ## WSTRINGS and UTF-16 {#bdlde_charconvertutf16-wstrings-and-utf-16}
89///
90///
91/// UTF-16 (or UTF-8, for that matter) can be stored in `wstring`s, but note
92/// that the size of a `wstring::value_type`, also known as a `wchar_t` word,
93/// varies across different platforms -- it is 4 bytes on Solaris, Linux, and
94/// Darwin, and 2 bytes on AIX and Windows. So a file of `wchar_t` words
95/// written by one platform may not be readable by another. Byte order is also
96/// a consideration, and a non-host byte order can be handled by using the
97/// optional `byteOrder` argument of these functions. Another factor is that,
98/// since UTF-16 words all fit in 2 bytes, using `wchar_t` to store UTF-16 is
99/// very wasteful of space on many platforms.
100///
101/// ## Usage {#bdlde_charconvertutf16-usage}
102///
103///
104/// This section illustrates intended use of this component.
105///
106/// ### Example 1: Translation to Fixed-Length Buffers {#bdlde_charconvertutf16-example-1-translation-to-fixed-length-buffers}
107///
108///
109/// In this example, we will translate a string containing a non-ASCII code
110/// point from UTF-16 to UTF-8 and back using fixed-length buffers.
111///
112/// First, we create a UTF-16 string spelling `ecole` in French, which begins
113/// with `0xc9`, a non-ASCII `e` with an accent over it:
114/// @code
115/// unsigned short utf16String[] = { 0xc9, 'c', 'o', 'l', 'e', 0 };
116/// @endcode
117/// Then, we create a byte buffer to store the UTF-8 result of the translation
118/// in, and variables to monitor counts of code points and bytes translated:
119/// @code
120/// char utf8String[7];
121/// bsl::size_t numCodePoints, numBytes;
122/// numCodePoints = numBytes = -1; // garbage
123/// @endcode
124/// Next, we call `utf16ToUtf8` to do the translation:
125/// @code
126/// int rc = bdlde::CharConvertUtf16::utf16ToUtf8(utf8String,
127/// sizeof(utf8String),
128/// utf16String,
129/// &numCodePoints,
130/// &numBytes);
131/// @endcode
132/// Then, we observe that no errors or warnings occurred, and that the numbers
133/// of code points and bytes were as expected. Note that both `numCodePoints`
134/// and `numBytes` include the terminating 0:
135/// @code
136/// assert(0 == rc);
137/// assert(6 == numCodePoints);
138/// assert(7 == numBytes);
139/// @endcode
140/// Next, we examine the length of the translated string:
141/// @code
142/// assert(numBytes - 1 == bsl::strlen(utf8String));
143/// @endcode
144/// Then, we examine the individual bytes of the translated UTF-8:
145/// @code
146/// assert((char)0xc3 == utf8String[0]);
147/// assert((char)0x89 == utf8String[1]);
148/// assert('c' == utf8String[2]);
149/// assert('o' == utf8String[3]);
150/// assert('l' == utf8String[4]);
151/// assert('e' == utf8String[5]);
152/// assert(0 == utf8String[6]);
153/// @endcode
154/// Next, in preparation for translation back to UTF-16, we create a buffer of
155/// `short` values and the variable `numWords` to track the number of UTF-16
156/// words occupied by the result:
157/// @code
158/// unsigned short secondUtf16String[6];
159/// bsl::size_t numWords;
160/// numCodePoints = numWords = -1; // garbage
161/// @endcode
162/// Then, we do the reverse translation:
163/// @code
164/// rc = bdlde::CharConvertUtf16::utf8ToUtf16(secondUtf16String,
165/// 6,
166/// utf8String,
167/// &numCodePoints,
168/// &numWords);
169/// @endcode
170/// Next, we observe that no errors or warnings were reported, and that the
171/// number of code points and words were as expected. Note that `numCodePoints`
172/// and `numWords` both include the terminating 0:
173/// @code
174/// assert(0 == rc);
175/// assert(6 == numCodePoints);
176/// assert(6 == numWords);
177/// @endcode
178/// Now, we observe that our output is identical to the original UTF-16 string:
179/// @code
180/// assert(0 == bsl::memcmp(utf16String,
181/// secondUtf16String,
182/// sizeof(utf16String)));
183/// @endcode
184/// Finally, we examine the individual words of the reverse translation:
185/// @code
186/// assert(0xc9 == secondUtf16String[0]);
187/// assert('c' == secondUtf16String[1]);
188/// assert('o' == secondUtf16String[2]);
189/// assert('l' == secondUtf16String[3]);
190/// assert('e' == secondUtf16String[4]);
191/// assert(0 == secondUtf16String[5]);
192/// @endcode
193///
194/// ### Example 2: Translation to STL Containers {#bdlde_charconvertutf16-example-2-translation-to-stl-containers}
195///
196///
197/// The following snippets of code illustrate a typical use of the
198/// `bdlde::CharConvertUtf16` struct's utility functions, first converting from
199/// UTF-8 to UTF-16, and then converting back to make sure the round trip
200/// returns the same value, translating to STL containers in both directions.
201///
202/// First, we declare a string of UTF-8 containing single-, double-, triple-,
203/// and quadruple-octet code points:
204/// @code
205/// const char utf8MultiLang[] = {
206/// "Hello" // -- ASCII
207/// "\xce\x97" "\xce\x95" "\xce\xbb" // -- Greek
208/// "\xe4\xb8\xad" "\xe5\x8d\x8e" // -- Chinese
209/// "\xe0\xa4\xad" "\xe0\xa4\xbe" // -- Hindi
210/// "\xf2\x94\xb4\xa5" "\xf3\xb8\xac\x83" }; // -- Quad octets
211/// @endcode
212/// Then, we declare an `enum` summarizing the counts of code points in the
213/// string and verify that the counts add up to the length of the string:
214/// @code
215/// enum { NUM_ASCII_CODE_POINTS = 5,
216/// NUM_GREEK_CODE_POINTS = 3,
217/// NUM_CHINESE_CODE_POINTS = 2,
218/// NUM_HINDI_CODE_POINTS = 2,
219/// NUM_QUAD_CODE_POINTS = 2 };
220///
221/// assert(1 * NUM_ASCII_CODE_POINTS +
222/// 2 * NUM_GREEK_CODE_POINTS +
223/// 3 * NUM_CHINESE_CODE_POINTS +
224/// 3 * NUM_HINDI_CODE_POINTS +
225/// 4 * NUM_QUAD_CODE_POINTS == bsl::strlen(utf8MultiLang));
226/// @endcode
227/// Next, we declare the vector where our UTF-16 output will go, and a variable
228/// into which the number of code points (not bytes or words) written will be
229/// stored. It is not necessary to initialize `utf16CodePointsWritten`:
230/// @code
231/// bsl::vector<unsigned short> v16;
232/// bsl::size_t utf16CodePointsWritten;
233/// @endcode
234/// Note that for performance, we should `v16.reserve(sizeof(utf8MultiLang))`,
235/// but it's not strictly necessary -- the vector will automatically be grown to
236/// the correct size. Also note that if `v16` were not empty, that wouldn't be
237/// a problem -- any contents will be discarded.
238///
239/// Then, we do the translation to UTF-16:
240/// @code
241/// int retVal = bdlde::CharConvertUtf16::utf8ToUtf16(&v16,
242/// utf8MultiLang,
243/// &utf16CodePointsWritten);
244///
245/// assert(0 == retVal); // verify success
246/// assert(0 == v16.back()); // verify null terminated
247/// @endcode
248/// Next, we verify that the number of code points (not bytes or words) that was
249/// returned is correct:
250/// @code
251/// enum { EXPECTED_CODE_POINTS_WRITTEN =
252/// NUM_ASCII_CODE_POINTS + NUM_GREEK_CODE_POINTS +
253/// NUM_CHINESE_CODE_POINTS + NUM_HINDI_CODE_POINTS +
254/// NUM_QUAD_CODE_POINTS + 1 };
255///
256/// assert(EXPECTED_CODE_POINTS_WRITTEN == utf16CodePointsWritten);
257/// @endcode
258/// Then, we verify that the number of 16-bit words written was correct. The
259/// quad octet code points each require 2 `short` words of output:
260/// @code
261/// enum { EXPECTED_UTF16_WORDS_WRITTEN =
262/// NUM_ASCII_CODE_POINTS + NUM_GREEK_CODE_POINTS +
263/// NUM_CHINESE_CODE_POINTS + NUM_HINDI_CODE_POINTS +
264/// NUM_QUAD_CODE_POINTS * 2 + 1 };
265///
266/// assert(EXPECTED_UTF16_WORDS_WRITTEN == v16.size());
267/// @endcode
268/// Next, we calculate and confirm the difference between the number of UTF-16
269/// words output and the number of bytes input. The ASCII code points will take
270/// 1 16-bit word apiece, the Greek code points are double octets that will
271/// become single `short` values, the Chinese code points are encoded as UTF-8
272/// triple octets that will turn into single 16-bit words, the same for the
273/// Hindi code points, and the quad code points are quadruple octets that will
274/// turn into double `short` values:
275/// @code
276/// enum { SHRINKAGE = NUM_ASCII_CODE_POINTS * (1-1) +
277/// NUM_GREEK_CODE_POINTS * (2-1) +
278/// NUM_CHINESE_CODE_POINTS * (3-1) +
279/// NUM_HINDI_CODE_POINTS * (3-1) +
280/// NUM_QUAD_CODE_POINTS * (4-2) };
281///
282/// assert(v16.size() == sizeof(utf8MultiLang) - SHRINKAGE);
283/// @endcode
284/// Then, we go on to do the reverse `utf16ToUtf8` transform to turn it back
285/// into UTF-8, and we should get a result identical to our original input. We
286/// declare a `bsl::string` for our output, and a variable to count the number
287/// of code points (not bytes or words) translated:
288/// @code
289/// bsl::string s;
290/// bsl::size_t uf8CodePointsWritten;
291/// @endcode
292/// Again, note that for performance, we should ideally
293/// `s.reserve(3 * v16.size())` but it's not really necessary.
294///
295/// Now, we do the reverse transform:
296/// @code
297/// retVal = bdlde::CharConvertUtf16::utf16ToUtf8(&s,
298/// v16.begin(),
299/// &uf8CodePointsWritten);
300/// @endcode
301/// Finally, we verify that a successful status was returned, that the output of
302/// the reverse transform was identical to the original input, and that the
303/// number of code points translated was as expected:
304/// @code
305/// assert(0 == retVal);
306/// assert(utf8MultiLang == s);
307/// assert(s.length() + 1 == sizeof(utf8MultiLang));
308///
309/// assert(EXPECTED_CODE_POINTS_WRITTEN == uf8CodePointsWritten);
310/// assert(utf16CodePointsWritten == uf8CodePointsWritten);
311/// @endcode
312/// @}
313/** @} */
314/** @} */
315
316/** @addtogroup bdl
317 * @{
318 */
319/** @addtogroup bdlde
320 * @{
321 */
322/** @addtogroup bdlde_charconvertutf16
323 * @{
324 */
325
326#include <bdlscm_version.h>
327
328#include <bdlde_byteorder.h>
330
331#include <bsls_libraryfeatures.h>
332
333#include <bsl_cstddef.h> // 'bsl::size_t'
334#include <bsl_string.h>
335#include <bsl_string_view.h>
336#include <bsl_vector.h>
337
338#include <string>
339#include <vector>
340
341
342
343namespace bdlde {
344 // =======================
345 // struct CharConvertUtf16
346 // =======================
347
348/// This `struct` provides a namespace for a suite of static functions to convert buffers or containers between UTF-8 and UTF-16.
349///
350/// \note Note that Byte
351/// Order Mark (BOM) sequences are neither generated nor recognized as
352/// special. If a BOM is present in the input, it will be translated,
353/// whether correct (`0xfeff`) or incorrect (`0xfffe`), into the output
354/// without any special handling.
355///
356/// See @ref bdlde_charconvertutf16
358
359 // CLASS METHODS
360
361 // -- UTF-8 to UTF-16 Methods
362
363 /// Return the number of words required to store the translation of the
364 /// specified UTF-8 string `srcBuffer` into a 0 terminated UTF-16 string
365 /// (including the 0 terminating word into the returned count).
366 /// Optionally specify `endPtr`, referring to one past the last input
367 /// character. If `endPtr` is not supplied, or is 0, treat `srcBuffer` as 0 terminated.
368 ///
369 /// \note Note that this function will return the size
370 /// `utf8ToUtf16` will require, assuming the `errorWord` argument to
371 /// `utf8ToUtf16` is non-zero.
372 static bsl::size_t computeRequiredUtf16Words(const char *srcBuffer,
373 const char *endPtr = 0);
374
375 /// Load into the specified `dstString` the result of converting the
376 /// specified UTF-8 `srcString` to its UTF-16 equivalent. Optionally
377 /// specify `numCodePointsWritten`, which, if not 0, indicates the
378 /// location of the modifiable variable into which the number of Unicode
379 /// code points written, including the terminating null character, is to
380 /// be loaded. Optionally specify an `errorChar` to be substituted, if
381 /// not 0, for invalid encodings in the input string. Optionally
382 /// specify `byteOrder` to indicate the byte order of the UTF-16 output;
383 /// if `byteOrder` is not specified, the output is assumed to be in host
384 /// byte order. Return 0 on success and
385 /// `CharConvertStatus::k_INVALID_INPUT_BIT` otherwise. Invalid
386 /// encodings are multi-byte encoding parts out of sequence, non-minimal
387 // UTF-8 encodings of code points, or code points outside the ranges
388 /// that UTF-16 can validly encode (in the range `[ 1 .. 0xd7ff ]` or
389 /// `[ 0xe000 .. 0x10ffff ]`). If `errorChar` is 0, invalid input code
390 /// points are ignored (i.e., produce no corresponding output).
391 ///
392 /// \pre The behavior is undefined unless `srcString` is null-terminated when specified as a `const char *`.
393 ///
394 /// \note Note that one code point can occupy
395 /// multiple UTF-16 words, and that if `srcString` is a
396 /// `bslstl::StringRef`, it may contain embedded null bytes that will be
397 /// translated to null words embedded in the output.
398 static int utf8ToUtf16(
399 bsl::wstring *dstString,
400 const bsl::string_view& srcString,
401 bsl::size_t *numCodePointsWritten = 0,
402 wchar_t errorWord = '?',
403 ByteOrder::Enum byteOrder =
405 static int utf8ToUtf16(
406 std::wstring *dstString,
407 const bsl::string_view& srcString,
408 bsl::size_t *numCodePointsWritten = 0,
409 wchar_t errorWord = '?',
410 ByteOrder::Enum byteOrder =
412#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
413 static int utf8ToUtf16(
414 std::pmr::wstring *dstString,
415 const bsl::string_view& srcString,
416 bsl::size_t *numCodePointsWritten = 0,
417 wchar_t errorWord = '?',
419#endif
420 static int utf8ToUtf16(
421 bsl::wstring *dstString,
422 const char *srcString,
423 bsl::size_t *numCodePointsWritten = 0,
424 wchar_t errorWord = '?',
425 ByteOrder::Enum byteOrder =
427 static int utf8ToUtf16(
428 std::wstring *dstString,
429 const char *srcString,
430 bsl::size_t *numCodePointsWritten = 0,
431 wchar_t errorWord = '?',
432 ByteOrder::Enum byteOrder =
434#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
435 static int utf8ToUtf16(std::pmr::wstring *dstString,
436 const char *srcString,
437 bsl::size_t *numCodePointsWritten = 0,
438 wchar_t errorWord = '?',
440#endif
441#if defined(BSLS_COMPILERFEATURES_SUPPORT_UNICODE_CHAR_TYPES)
442 static int utf8ToUtf16(
443 bsl::u16string *dstString,
444 const bsl::string_view& srcString,
445 bsl::size_t *numCodePointsWritten = 0,
446 char16_t errorChar = '?',
447 ByteOrder::Enum byteOrder =
449 static int utf8ToUtf16(
450 std::u16string *dstString,
451 const bsl::string_view& srcString,
452 bsl::size_t *numCodePointsWritten = 0,
453 char16_t errorChar = '?',
454 ByteOrder::Enum byteOrder =
456# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
457 static int utf8ToUtf16(
458 std::pmr::u16string *dstString,
459 const bsl::string_view& srcString,
460 bsl::size_t *numCodePointsWritten = 0,
461 char16_t errorChar = '?',
462 ByteOrder::Enum byteOrder =
464# endif
465 static int utf8ToUtf16(
466 bsl::u16string *dstString,
467 const char *srcString,
468 bsl::size_t *numCodePointsWritten = 0,
469 char16_t errorChar = '?',
470 ByteOrder::Enum byteOrder =
472 static int utf8ToUtf16(
473 std::u16string *dstString,
474 const char *srcString,
475 bsl::size_t *numCodePointsWritten = 0,
476 char16_t errorChar = '?',
477 ByteOrder::Enum byteOrder =
479# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
480 static int utf8ToUtf16(
481 std::pmr::u16string *dstString,
482 const char *srcString,
483 bsl::size_t *numCodePointsWritten = 0,
484 char16_t errorChar = '?',
485 ByteOrder::Enum byteOrder =
487# endif
488#endif
489
490 /// Load into the specified `dstVector` the result of converting the
491 /// specified UTF-8 `srcString` to its UTF-16 equivalent. Optionally
492 /// specify `numCodePointsWritten`, which (if not 0) indicates the
493 /// location of the modifiable variable into which the number of UTF-16
494 /// code points (including the null terminator) written is to be loaded.
495 /// Optionally specify an `errorWord` to be substituted (if not 0) for
496 /// invalid encodings in the input string. Invalid encodings are
497 /// multi-byte encoding parts out of sequence, non-minimal UTF-8
498 /// encodings, or code points outside the ranges that UTF-16 can validly
499 /// encode (in the range `[ 1 .. 0xd7ff ]` or `[ 0xe000 .. 0x10ffff ]`).
500 /// If `errorWord` is 0, invalid input is ignored (i.e., produces no
501 /// corresponding output). Optionally specify `byteOrder` to indicate
502 /// the byte order of the UTF-16 output; if `byteOrder` is not
503 /// specified, the output is assumed to be in host byte order. Any
504 /// previous contents of the destination are discarded. Return 0 on
505 /// success and `CharConvertStatus::k_INVALID_INPUT_BIT` otherwise.
506 ///
507 /// \pre The behavior is undefined unless `errorWord` is either 0 or a valid
508 /// single-word encoded UTF-16 code point (in the range
509 /// `[ 1 .. 0xd7ff ]` or `[ 0xe000 .. 0xffff ]`) and `srcString` is null-terminated when specified as a `const char *`.
510 ///
511 /// \note Note that one
512 /// code point can occupy multiple 16-bit words. Also note that the
513 /// size of the result vector is always fitted to the null-terminated
514 /// result, including the terminating 0. Also note that if `srcString`
515 /// is a `bslstl::StringRef`, it may contain embedded null bytes that
516 /// will be translated to null words embedded in the output.
517 static int utf8ToUtf16(
519 const bsl::string_view& srcString,
520 bsl::size_t *numCodePointsWritten = 0,
521 unsigned short errorWord = '?',
522 ByteOrder::Enum byteOrder =
524 static int utf8ToUtf16(
525 std::vector<unsigned short> *dstVector,
526 const bsl::string_view& srcString,
527 bsl::size_t *numCodePointsWritten = 0,
528 unsigned short errorWord = '?',
529 ByteOrder::Enum byteOrder =
531#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
532 static int utf8ToUtf16(
533 std::pmr::vector<unsigned short> *dstVector,
534 const bsl::string_view& srcString,
535 bsl::size_t *numCodePointsWritten = 0,
536 unsigned short errorWord = '?',
538#endif
539 static int utf8ToUtf16(
541 const char *srcString,
542 bsl::size_t *numCodePointsWritten = 0,
543 unsigned short errorWord = '?',
544 ByteOrder::Enum byteOrder =
546 static int utf8ToUtf16(
547 std::vector<unsigned short> *dstVector,
548 const char *srcString,
549 bsl::size_t *numCodePointsWritten = 0,
550 unsigned short errorWord = '?',
551 ByteOrder::Enum byteOrder =
553#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
554 static int utf8ToUtf16(
555 std::pmr::vector<unsigned short> *dstVector,
556 const char *srcString,
557 bsl::size_t *numCodePointsWritten = 0,
558 unsigned short errorWord = '?',
560#endif
561
562 /// Load into the specified `dstBuffer` of the specified `dstCapacity`,
563 /// the result of converting the specified UTF-8 `srcString` to its
564 /// UTF-16 equivalent. Optionally specify `numCodePointsWritten`, which
565 /// (if not 0) indicates the location of the variable into which the
566 /// number of UTF-16 code points (including the null terminator) written
567 /// is to be loaded. Optionally specify `numWordsWritten`, which (if
568 /// not 0) indicates the location of the modifiable variable into which
569 /// the number of `short` *memory words* written (including the null
570 /// terminator) is to be loaded. Optionally specify an `errorWord` to
571 /// be substituted (if not 0) for invalid encodings in the input string.
572 /// Invalid encodings are multi-byte encoding parts out of sequence,
573 /// non-minimal UTF-8 encodings of code points, or code points outside
574 /// the ranges that UTF-16 can validly encode (in the range
575 /// `[ 1 .. 0xd7ff ]` or `[ 0xe000 .. 0x10ffff ]`). If `errorWord` is
576 /// 0, invalid input sequences are ignored (i.e., produce no
577 /// corresponding output). Optionally specify `byteOrder` to indicate
578 /// the byte order of the UTF-16 output; if `byteOrder` is not
579 /// specified, the output is assumed to be in host byte order. Return 0
580 /// on success and a bit-wise or of the bits specified by
581 /// `CharConvertStatus::Enum` otherwise to indicate that there were
582 /// invalid input sequences or if `dstCapacity` was inadequate to store
583 /// the output. If `dstCapacity > 0` yet `dstCapacity` specifies a
584 /// buffer too small to hold the output, the maximal null-terminated
585 /// prefix of the properly converted result string is loaded into `dstBuffer`.
586 ///
587 /// \pre The behavior is undefined unless `dstBuffer` refers to
588 /// an array of at least `dstCapacity` elements, `errorWord` is either 0
589 /// or a valid single-word encoded UTF-16 code point (in the range
590 /// `[ 1 .. 0xd7ff ]` or `[ 0xe000 .. 0xffff ]`), and `srcString` is null-terminated when supplied as a `const char *`.
591 ///
592 /// \note Note that if
593 /// `dstCapacity` is 0, `*dstBuffer` is not modified and this function
594 /// returns a value with `CharConvertStatus::k_OUT_OF_SPACE_BIT` set and
595 /// 0 is written into `*numCodePointsWritten` and `*numWordsWritten` (if
596 /// those pointers are non-null), since there is insufficient space for
597 /// even a null terminator alone. Also note that one code point can
598 /// occupy multiple 16-bit *words*, so that `*numWordsWritten` may be
599 /// greater than `*numCodePointsWritten`, and therefore that an input
600 /// `srcString` of `dstCapacity` code points may not fit into
601 /// `dstBuffer`, however, an input `srcString` of `dstCapacity` bytes
602 /// (including null terminator, if present) will always fit (since the
603 /// UTF-8 encoding of a code point requires at least as many bytes as
604 /// the UTF-16 encoding requires words). Also note that if `srcString`
605 /// is a `bslstl::StringRef`, it may contain embedded null bytes that
606 /// will be translated to null words embedded in the output.
607 static int utf8ToUtf16(
608 unsigned short *dstBuffer,
609 bsl::size_t dstCapacity,
610 const bsl::string_view& srcString,
611 bsl::size_t *numCodePointsWritten = 0,
612 bsl::size_t *numWordsWritten = 0,
613 unsigned short errorWord = '?',
614 ByteOrder::Enum byteOrder =
616 static int utf8ToUtf16(
617 unsigned short *dstBuffer,
618 bsl::size_t dstCapacity,
619 const char *srcString,
620 bsl::size_t *numCodePointsWritten = 0,
621 bsl::size_t *numWordsWritten = 0,
622 unsigned short errorWord = '?',
623 ByteOrder::Enum byteOrder =
625
626 static int utf8ToUtf16(
627 wchar_t *dstBuffer,
628 bsl::size_t dstCapacity,
629 const bsl::string_view& srcString,
630 bsl::size_t *numCodePointsWritten = 0,
631 bsl::size_t *numWordsWritten = 0,
632 wchar_t errorWord = '?',
633 ByteOrder::Enum byteOrder =
635 static int utf8ToUtf16(
636 wchar_t *dstBuffer,
637 bsl::size_t dstCapacity,
638 const char *srcString,
639 bsl::size_t *numCodePointsWritten = 0,
640 bsl::size_t *numWordsWritten = 0,
641 wchar_t errorWord = '?',
642 ByteOrder::Enum byteOrder =
644#if defined(BSLS_COMPILERFEATURES_SUPPORT_UNICODE_CHAR_TYPES)
645 /// Load into the specified `dstBuffer` of the specified `dstCapacity`,
646 /// the result of converting the specified UTF-8 `srcString` to its
647 /// UTF-16 equivalent. Optionally specify `numCodePointsWritten`, which
648 /// (if not 0) indicates the location of the variable into which the
649 /// number of UTF-16 code points (including the terminating 0) written
650 /// is to be loaded. Optionally specify `numWordsWritten`, which (if
651 /// not 0) indicates the location of the modifiable variable into which
652 /// the number of `short` *memory words* written (including the null
653 /// terminator) is to be loaded. Optionally specify an `errorWord` to
654 /// be substituted (if not 0) for invalid encodings in the input string.
655 /// Invalid encodings are multi-byte encoding parts out of sequence,
656 /// non-minimal UTF-8 encodings of code points, or code points outside
657 /// the ranges that UTF-16 can validly encode (in the range
658 /// `[ 1 .. 0xd7ff ]` or `[ 0xde00 .. 0x10ffff ]`). Optionally specify
659 /// `byteOrder` to indicate the byte order of the UTF-16 output; if
660 /// `byteOrder` is not specified, the output is assumed to be in host
661 /// byte order. If `errorWord` is 0, invalid input sequences are
662 /// ignored (i.e., produce no corresponding output). Return 0 on
663 /// success and a bit-wise or of the bits specified by
664 /// `CharConvertStatus::Enum` otherwise to indicate that there were
665 /// invalid sequences or if `dstCapacity` was inadequate to store the
666 /// output. If `dstCapacity > 0` yet `dstCapacity` specifies a buffer
667 /// too small to hold the output, the maximal null-terminated prefix of
668 /// the properly converted result string is loaded into `dstBuffer`.
669 ///
670 /// \pre The behavior is undefined unless `dstBuffer`, if specified, refers
671 /// to an array of at least `dstCapacity` elements, `errorWord` is
672 /// either 0 or a valid single-word encoded UTF-16 code point (in the
673 /// range `[ 1 .. 0xd7ff ]` or `[ 0xe000 .. 0xffff ]`), and `srcString` is null-terminated if supplied as a `const char *`.
674 ///
675 /// \note Note that if
676 /// `dstCapacity` is 0, `*dstBuffer` is not modified and this function
677 /// returns a value with `CharConvertStatus::k_OUT_OF_SPACE_BIT` set and
678 /// 0 is written into `*numCodePointsWritten` and `*numWordsWritten` (if
679 /// those pointers are non-null), since there is insufficient space for
680 /// even a null terminator alone. Also note that one code point can
681 /// occupy multiple 16-bit words, so that `*numWordsWritten` may be
682 /// greater than `*numCodePointsWritten`, and therefore that an input
683 /// `srcString` of `dstCapacity` code points may not fit into
684 /// `dstBuffer`. However, an input `srcString` of `dstCapacity` bytes
685 /// (including terminating 0, if present) will always fit (since the
686 /// UTF-8 encoding of a code point requires at least as many bytes as
687 /// the UTF-16 encoding requires words). Also note that if `srcString`
688 /// is a `bslstl::StringRef`, it may contain embedded null bytes that
689 /// will be translated to null words embedded in the output.
690 static int utf8ToUtf16(
691 char16_t *dstBuffer,
692 bsl::size_t dstCapacity,
693 const bsl::string_view& srcString,
694 bsl::size_t *numCodePointsWritten = 0,
695 bsl::size_t *numWordsWritten = 0,
696 char16_t errorChar = '?',
697 ByteOrder::Enum byteOrder =
699 static int utf8ToUtf16(
700 char16_t *dstBuffer,
701 bsl::size_t dstCapacity,
702 const char *srcString,
703 bsl::size_t *numCodePointsWritten = 0,
704 bsl::size_t *numWordsWritten = 0,
705 char16_t errorChar = '?',
706 ByteOrder::Enum byteOrder =
708#endif
709
710 // -- UTF-16 to UTF-8 Methods
711
712 /// Return the length needed in bytes, for a buffer to hold the
713 /// null-terminated UTF-8 string translated from the specified UTF-16
714 /// string `srcBuffer` (including the terminating '\0' in the returned
715 /// count). Optionally specify `endPtr`, referring to one past the last
716 /// input character. If `endPtr` is not supplied, or is 0, treat
717 /// `srcBuffer` as 0 terminated. Optionally specify `byteOrder`
718 /// indicating the byte order of `srcBuffer`; if `byteOrder` is not supplied, the host byte order is used.
719 ///
720 /// \note Note that this function will
721 /// return the size `utf16ToUtf8` will require, assuming the `errorByte`
722 /// argument to `utf16ToUtf8` is non-zero.
723 static bsl::size_t computeRequiredUtf8Bytes(
724 const unsigned short *srcBuffer,
725 const unsigned short *endPtr = 0,
726 ByteOrder::Enum byteOrder =
728 static bsl::size_t computeRequiredUtf8Bytes(
729 const wchar_t *srcBuffer,
730 const wchar_t *endPtr = 0,
731 ByteOrder::Enum byteOrder =
733#if defined(BSLS_COMPILERFEATURES_SUPPORT_UNICODE_CHAR_TYPES)
734 static bsl::size_t computeRequiredUtf8Bytes(
735 const char16_t *srcBuffer,
736 const char16_t *endPtr = 0,
737 ByteOrder::Enum byteOrder =
739#endif
740
741
742 /// Load into the specified `dstString` the result of converting the
743 /// specified UTF-16 `srcString` to its UTF-8 equivalent. Optionally
744 /// specify `numCodePointsWritten`, which (if not 0) indicates the
745 /// location of the modifiable variable into which the number of Unicode
746 /// code points written, including the null terminator, is to be loaded,
747 /// where one code point may occupy multiple bytes. Optionally specify
748 /// an `errorByte` to be substituted (if not 0) for invalid encodings in
749 /// the input string. Invalid encodings are incomplete multi-word
750 /// encodings or parts of a two-word encoding out of their proper
751 /// sequence. If `errorByte` is 0, invalid input sequences are ignored
752 /// (i.e., produce no corresponding output). Any previous contents of
753 /// the destination are discarded. Optionally specify `byteOrder` to
754 /// indicate the byte order of the UTF-16 input; if `byteOrder` is not
755 /// specified, the input is assumed to be in host byte order. Return 0
756 /// on success and `CharConvertStatus::k_INVALID_INPUT_BIT` if one or
757 /// more invalid sequences were encountered in the input.
758 ///
759 /// \pre The behavior is undefined unless `errorByte` is either 0 or a valid single-byte
760 /// Unicode code point (`0 < errorByte < 0x80`) and `srcString` is null-terminated if supplied as a `const wchar_t *`.
761 ///
762 /// \note Note that if
763 /// `srcString` is a `bslstl::StringRefWide`, it may contain embedded 0
764 /// words that will be translated to null bytes embedded in the output.
765 static int utf16ToUtf8(bsl::string *dstString,
766 const unsigned short *srcString,
767 bsl::size_t *numCodePointsWritten = 0,
768 char errorByte = '?',
769 ByteOrder::Enum byteOrder =
771 static int utf16ToUtf8(std::string *dstString,
772 const unsigned short *srcString,
773 bsl::size_t *numCodePointsWritten = 0,
774 char errorByte = '?',
775 ByteOrder::Enum byteOrder =
777#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
778 static int utf16ToUtf8(
779 std::pmr::string *dstString,
780 const unsigned short *srcString,
781 bsl::size_t *numCodePointsWritten = 0,
782 char errorByte = '?',
784#endif
785 static int utf16ToUtf8(
786 bsl::string *dstString,
787 const unsigned short *srcString,
788 bsl::size_t srcLengthInWords,
789 bsl::size_t *numCodePointsWritten = 0,
790 char errorByte = '?',
792 static int utf16ToUtf8(
793 std::string *dstString,
794 const unsigned short *srcString,
795 bsl::size_t srcLengthInWords,
796 bsl::size_t *numCodePointsWritten = 0,
797 char errorByte = '?',
799#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
800 static int utf16ToUtf8(
801 std::pmr::string *dstString,
802 const unsigned short *srcString,
803 bsl::size_t srcLengthInWords,
804 bsl::size_t *numCodePointsWritten = 0,
805 char errorByte = '?',
807#endif
808 static int utf16ToUtf8(
809 bsl::string *dstString,
810 const bsl::wstring_view& srcString,
811 bsl::size_t *numCodePointsWritten = 0,
812 char errorByte = '?',
813 ByteOrder::Enum byteOrder =
815 static int utf16ToUtf8(
816 std::string *dstString,
817 const bsl::wstring_view& srcString,
818 bsl::size_t *numCodePointsWritten = 0,
819 char errorByte = '?',
820 ByteOrder::Enum byteOrder =
822#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
823 static int utf16ToUtf8(
824 std::pmr::string *dstString,
825 const bsl::wstring_view& srcString,
826 bsl::size_t *numCodePointsWritten = 0,
827 char errorByte = '?',
828 ByteOrder::Enum byteOrder =
830#endif
831 static int utf16ToUtf8(bsl::string *dstString,
832 const wchar_t *srcString,
833 bsl::size_t *numCodePointsWritten = 0,
834 char errorByte = '?',
835 ByteOrder::Enum byteOrder =
837 static int utf16ToUtf8(std::string *dstString,
838 const wchar_t *srcString,
839 bsl::size_t *numCodePointsWritten = 0,
840 char errorByte = '?',
841 ByteOrder::Enum byteOrder =
843#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
844 static int utf16ToUtf8(std::pmr::string *dstString,
845 const wchar_t *srcString,
846 bsl::size_t *numCodePointsWritten = 0,
847 char errorByte = '?',
848 ByteOrder::Enum byteOrder =
850#endif
851#if defined(BSLS_COMPILERFEATURES_SUPPORT_UNICODE_CHAR_TYPES)
852 static int utf16ToUtf8(
853 bsl::string *dstString,
854 const bsl::u16string_view& srcString,
855 bsl::size_t *numCodePointsWritten = 0,
856 char errorByte = '?',
857 ByteOrder::Enum byteOrder =
859 static int utf16ToUtf8(
860 std::string *dstString,
861 const bsl::u16string_view& srcString,
862 bsl::size_t *numCodePointsWritten = 0,
863 char errorByte = '?',
864 ByteOrder::Enum byteOrder =
866# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
867 static int utf16ToUtf8(
868 std::pmr::string *dstString,
869 const bsl::u16string_view& srcString,
870 bsl::size_t *numCodePointsWritten = 0,
871 char errorByte = '?',
872 ByteOrder::Enum byteOrder =
874# endif
875 static int utf16ToUtf8(bsl::string *dstString,
876 const char16_t *srcString,
877 bsl::size_t *numCodePointsWritten = 0,
878 char errorByte = '?',
879 ByteOrder::Enum byteOrder =
881 static int utf16ToUtf8(std::string *dstString,
882 const char16_t *srcString,
883 bsl::size_t *numCodePointsWritten = 0,
884 char errorByte = '?',
885 ByteOrder::Enum byteOrder =
887# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
888 static int utf16ToUtf8(std::pmr::string *dstString,
889 const char16_t *srcString,
890 bsl::size_t *numCodePointsWritten = 0,
891 char errorByte = '?',
892 ByteOrder::Enum byteOrder =
894# endif
895#endif
896
897 /// Load into the specified `dstVector` the null-terminated result of
898 /// converting the specified UTF-16 `*srcString` to its UTF-8
899 /// equivalent. Optionally specify `srcLengthInWords`, the number of
900 /// `unsigned short`s of input. If `srcLengthInWords` is not specified,
901 /// the input must be terminated by a null word. Optionally specify
902 /// `numCodePointsWritten`, which (if not 0) indicates the location of
903 /// the modifiable variable into which the number of Unicode code points
904 /// written, including the null terminator, is to be loaded, where one
905 /// code point may occupy multiple bytes. Optionally specify an
906 /// `errorByte` to be substituted (if not 0) for invalid encodings in
907 /// the input string. Invalid encodings are incomplete multi-word
908 /// encodings or parts of a two-word encoding out of their proper
909 /// sequence. If `errorByte` is 0, invalid input sequences are ignored
910 /// (i.e., produce no corresponding output). Optionally specify
911 /// `byteOrder` to indicate the byte order of the UTF-16 input; if
912 /// `byteOrder` is not specified, the input is assumed to be in host
913 /// byte order. Any previous contents of the destination are discarded.
914 /// Return 0 on success and `CharConvertStatus::k_INVALID_INPUT_BIT` if
915 /// one or more invalid sequences were encountered in the input.
916 ///
917 /// \pre The behavior is undefined unless either `srcLengthInWords` is passed or
918 /// `srcString` is null-terminated, and `errorByte` is either 0 or a
919 /// valid single-byte Unicode code point (`0 < errorByte < 0x80`).
920 static int utf16ToUtf8(bsl::vector<char> *dstVector,
921 const unsigned short *srcString,
922 bsl::size_t *numCodePointsWritten = 0,
923 char errorByte = '?',
924 ByteOrder::Enum byteOrder =
926 static int utf16ToUtf8(std::vector<char> *dstVector,
927 const unsigned short *srcString,
928 bsl::size_t *numCodePointsWritten = 0,
929 char errorByte = '?',
930 ByteOrder::Enum byteOrder =
932#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
933 static int utf16ToUtf8(std::pmr::vector<char> *dstVector,
934 const unsigned short *srcString,
935 bsl::size_t *numCodePointsWritten = 0,
936 char errorByte = '?',
937 ByteOrder::Enum byteOrder =
939#endif
940 static int utf16ToUtf8(bsl::vector<char> *dstVector,
941 const unsigned short *srcString,
942 bsl::size_t srcLengthInWords,
943 bsl::size_t *numCodePointsWritten = 0,
944 char errorByte = '?',
945 ByteOrder::Enum byteOrder =
947 static int utf16ToUtf8(std::vector<char> *dstVector,
948 const unsigned short *srcString,
949 bsl::size_t srcLengthInWords,
950 bsl::size_t *numCodePointsWritten = 0,
951 char errorByte = '?',
952 ByteOrder::Enum byteOrder =
954#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
955 static int utf16ToUtf8(std::pmr::vector<char> *dstVector,
956 const unsigned short *srcString,
957 bsl::size_t srcLengthInWords,
958 bsl::size_t *numCodePointsWritten = 0,
959 char errorByte = '?',
960 ByteOrder::Enum byteOrder =
962#endif
963
964 static int utf16ToUtf8(
965 bsl::vector<char> *dstVector,
966 const bsl::wstring_view& srcString,
967 bsl::size_t *numCodePointsWritten = 0,
968 char errorByte = '?',
969 ByteOrder::Enum byteOrder =
971 static int utf16ToUtf8(
972 std::vector<char> *dstVector,
973 const bsl::wstring_view& srcString,
974 bsl::size_t *numCodePointsWritten = 0,
975 char errorByte = '?',
976 ByteOrder::Enum byteOrder =
978#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
979 static int utf16ToUtf8(
980 std::pmr::vector<char> *dstVector,
981 const bsl::wstring_view& srcString,
982 bsl::size_t *numCodePointsWritten = 0,
983 char errorByte = '?',
984 ByteOrder::Enum byteOrder =
986#endif
987 static int utf16ToUtf8(
988 bsl::vector<char> *dstVector,
989 const wchar_t *srcString,
990 bsl::size_t *numCodePointsWritten = 0,
991 char errorByte = '?',
992 ByteOrder::Enum byteOrder =
994 static int utf16ToUtf8(
995 std::vector<char> *dstVector,
996 const wchar_t *srcString,
997 bsl::size_t *numCodePointsWritten = 0,
998 char errorByte = '?',
999 ByteOrder::Enum byteOrder =
1001#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1002 static int utf16ToUtf8(
1003 std::pmr::vector<char> *dstVector,
1004 const wchar_t *srcString,
1005 bsl::size_t *numCodePointsWritten = 0,
1006 char errorByte = '?',
1007 ByteOrder::Enum byteOrder =
1009#endif
1010
1011#if defined(BSLS_COMPILERFEATURES_SUPPORT_UNICODE_CHAR_TYPES)
1012 /// Load into the specified `dstVector` the null-terminated result of
1013 /// converting the specified UTF-16 `srcString` to its UTF-8 equivalent.
1014 /// Optionally specify `numCodePointsWritten`, which (if not 0)
1015 /// indicates the location of the modifiable variable into which the
1016 /// number of Unicode code points written, including the null
1017 /// terminator, is to be loaded, where one code point may occupy
1018 /// multiple bytes. Optionally specify an `errorByte` to be substituted
1019 /// (if not 0) for invalid encodings in the input string. Invalid
1020 /// encodings are incomplete multi-word encodings or parts of a two-word
1021 /// encoding out of their proper sequence. If `errorByte` is 0, invalid
1022 /// input sequences are ignored (i.e., produce no corresponding output).
1023 /// Optionally specify `byteOrder` to indicate the byte order of the
1024 /// UTF-16 input; if `byteOrder` is not specified, the input is assumed
1025 /// to be in host byte order. Any previous contents of the destination
1026 /// are discarded. Return 0 on success and
1027 /// `CharConvertStatus::k_INVALID_INPUT_BIT` if one or more invalid
1028 /// sequences were encountered in the input.
1029 ///
1030 /// \pre The behavior is undefined unless `errorByte` is either 0 or a valid single-byte Unicode code
1031 /// point (`0 < errorByte < 0x80`) and `srcString` is null-terminated if supplied as a `const wchar_t *`.
1032 ///
1033 /// \note Note that if `srcString` is a
1034 /// `bslstl::StringRef`, it may contain embedded 0 words that will be
1035 /// translated to null bytes embedded in the output.
1036 static int utf16ToUtf8(
1037 bsl::vector<char> *dstVector,
1038 const bsl::u16string_view& srcString,
1039 bsl::size_t *numCodePointsWritten = 0,
1040 char errorByte = '?',
1041 ByteOrder::Enum byteOrder =
1043 static int utf16ToUtf8(
1044 std::vector<char> *dstVector,
1045 const bsl::u16string_view& srcString,
1046 bsl::size_t *numCodePointsWritten = 0,
1047 char errorByte = '?',
1048 ByteOrder::Enum byteOrder =
1050# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1051 static int utf16ToUtf8(
1052 std::pmr::vector<char> *dstVector,
1053 const bsl::u16string_view& srcString,
1054 bsl::size_t *numCodePointsWritten = 0,
1055 char errorByte = '?',
1056 ByteOrder::Enum byteOrder =
1058# endif
1059 static int utf16ToUtf8(
1060 bsl::vector<char> *dstVector,
1061 const char16_t *srcString,
1062 bsl::size_t *numCodePointsWritten = 0,
1063 char errorByte = '?',
1064 ByteOrder::Enum byteOrder =
1066 static int utf16ToUtf8(
1067 std::vector<char> *dstVector,
1068 const char16_t *srcString,
1069 bsl::size_t *numCodePointsWritten = 0,
1070 char errorByte = '?',
1071 ByteOrder::Enum byteOrder =
1073# ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1074 static int utf16ToUtf8(
1075 std::pmr::vector<char> *dstVector,
1076 const char16_t *srcString,
1077 bsl::size_t *numCodePointsWritten = 0,
1078 char errorByte = '?',
1079 ByteOrder::Enum byteOrder =
1081# endif
1082#endif
1083
1084 /// Load, into the specified `dstBuffer` of the specified `dstCapacity`,
1085 /// the result of converting the specified UTF-16 `srcString` to its
1086 /// UTF-8 equivalent. Optionally specify `numCodePointsWritten`, which
1087 /// (if not 0) indicates the location of the modifiable variable into
1088 /// which the number of Unicode code points (including the terminating
1089 /// 0, if any) written is to be loaded, where one code point can occupy
1090 /// multiple bytes. Optionally specify `numBytesWritten`, which (if not
1091 /// 0) indicates the location of the modifiable variable into which the
1092 /// number of bytes written (including the null terminator, if any) is
1093 /// to be loaded. Optionally specify an `errorByte` to be substituted
1094 /// (if not 0) for invalid encodings in the input string. Invalid
1095 /// encodings are incomplete multi-word encodings or parts of a two-word
1096 /// encoding out of their proper sequence. If `errorByte` is 0, invalid
1097 /// input sequences are ignored (i.e., produce no corresponding output).
1098 /// Optionally specify `byteOrder` to indicate the byte order of the
1099 /// UTF-16 input; if `byteOrder` is not specified, the input is assumed
1100 /// to be in host byte order. Return 0 on success and a bitwise-or of
1101 /// the flags defined by `CharConvertStatus::Enum` otherwise.
1102 /// `CharConvertStatus::k_INVALID_INPUT_BIT` will be set if one or more
1103 /// invalid sequences were encountered in the input, and
1104 /// `CharConvertStatus::k_OUT_OF_SPACE_BIT` will be set if the output
1105 /// space was exhausted before conversion was complete.
1106 ///
1107 /// \pre The behavior is undefined unless `dstBuffer` refers to an array of at least
1108 /// `dstCapacity` elements, `errorByte` is either 0 or a valid
1109 /// single-byte Unicode code point (`0 < errorByte < 0x80`), and
1110 /// `srcString` is null-terminated if supplied as a pointer.
1111 ///
1112 /// \note Note that if `dstCapacity` is 0, this function returns
1113 /// `CharConvertStatus::k_OUT_OF_SPACE_BIT` set and 0 is written into
1114 /// `*numCodePointsWritten` and `*numBytesWritten` (if those pointers
1115 /// are non-null), since there is insufficient space for even a null
1116 /// terminator alone. Also note that since UTF-8 is a variable-length
1117 /// encoding, `numBytesWritten` may be up to four times
1118 /// `numCodePointsWritten`, and therefore that an input `srcString` of
1119 /// `dstCapacity` code points (including the terminating 0, if present)
1120 /// may not fit into `dstBuffer`. A one-word (two-byte) UTF-16 code
1121 /// point will require one to three UTF-8 octets (bytes); a two-word
1122 /// (four-byte) UTF-16 code point will always require four UTF-8 octets.
1123 /// Also note that the amount of room needed will vary with the contents
1124 /// of the data and the language being translated, but never will the
1125 /// number of bytes output exceed three times the number of words input.
1126 /// Also note that, if `dstCapacity > 0`, then, after completion,
1127 /// `strlen(dstBuffer) + 1 == *numBytesWritten`. Also note that if
1128 /// `srcString` is a `bslstl::StringRef`, it may contain embedded 0
1129 /// words that will be translated to null bytes embedded in the output.
1130 static int utf16ToUtf8(char *dstBuffer,
1131 bsl::size_t dstCapacity,
1132 const unsigned short *srcString,
1133 bsl::size_t *numCodePointsWritten = 0,
1134 bsl::size_t *numBytesWritten = 0,
1135 char errorByte = '?',
1136 ByteOrder::Enum byteOrder =
1138 static int utf16ToUtf8(char *dstBuffer,
1139 bsl::size_t dstCapacity,
1140 const unsigned short *srcString,
1141 bsl::size_t srcLengthInWords,
1142 bsl::size_t *numCodePointsWritten = 0,
1143 bsl::size_t *numBytesWritten = 0,
1144 char errorByte = '?',
1145 ByteOrder::Enum byteOrder =
1147 static int utf16ToUtf8(
1148 char *dstBuffer,
1149 bsl::size_t dstCapacity,
1150 const bsl::wstring_view& srcString,
1151 bsl::size_t *numCodePointsWritten = 0,
1152 bsl::size_t *numBytesWritten = 0,
1153 char errorByte = '?',
1154 ByteOrder::Enum byteOrder =
1156 static int utf16ToUtf8(
1157 char *dstBuffer,
1158 bsl::size_t dstCapacity,
1159 const wchar_t *srcString,
1160 bsl::size_t *numCodePointsWritten = 0,
1161 bsl::size_t *numBytesWritten = 0,
1162 char errorByte = '?',
1163 ByteOrder::Enum byteOrder =
1165#if defined(BSLS_COMPILERFEATURES_SUPPORT_UNICODE_CHAR_TYPES)
1166 static int utf16ToUtf8(
1167 char *dstBuffer,
1168 bsl::size_t dstCapacity,
1169 const bsl::u16string_view& srcString,
1170 bsl::size_t *numCodePointsWritten = 0,
1171 bsl::size_t *numBytesWritten = 0,
1172 char errorByte = '?',
1173 ByteOrder::Enum byteOrder =
1175 static int utf16ToUtf8(
1176 char *dstBuffer,
1177 bsl::size_t dstCapacity,
1178 const char16_t *srcString,
1179 bsl::size_t *numCodePointsWritten = 0,
1180 bsl::size_t *numBytesWritten = 0,
1181 char errorByte = '?',
1182 ByteOrder::Enum byteOrder =
1184#endif
1185};
1186} // close package namespace
1187
1188
1189
1190#endif
1191
1192// ----------------------------------------------------------------------------
1193// Copyright 2015 Bloomberg Finance L.P.
1194//
1195// Licensed under the Apache License, Version 2.0 (the "License");
1196// you may not use this file except in compliance with the License.
1197// You may obtain a copy of the License at
1198//
1199// http://www.apache.org/licenses/LICENSE-2.0
1200//
1201// Unless required by applicable law or agreed to in writing, software
1202// distributed under the License is distributed on an "AS IS" BASIS,
1203// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1204// See the License for the specific language governing permissions and
1205// limitations under the License.
1206// ----------------------------- END-OF-FILE ----------------------------------
1207
1208/** @} */
1209/** @} */
1210/** @} */
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
Definition bslstl_vector.h:1120
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlde_base64alphabet.h:118
Enum
Definition bdlde_byteorder.h:136
@ e_HOST
Definition bdlde_byteorder.h:146
Definition bdlde_charconvertutf16.h:357
static int utf16ToUtf8(std::string *dstString, const wchar_t *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::vector< char > *dstVector, const unsigned short *srcString, bsl::size_t srcLengthInWords, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::string *dstString, const bsl::wstring_view &srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::vector< char > *dstVector, const unsigned short *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(char *dstBuffer, bsl::size_t dstCapacity, const unsigned short *srcString, bsl::size_t srcLengthInWords, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numBytesWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::string *dstString, const unsigned short *srcString, bsl::size_t srcLengthInWords, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(wchar_t *dstBuffer, bsl::size_t dstCapacity, const bsl::string_view &srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numWordsWritten=0, wchar_t errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::string *dstString, const bsl::wstring_view &srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::string *dstString, const unsigned short *srcString, bsl::size_t srcLengthInWords, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::vector< char > *dstVector, const wchar_t *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(char *dstBuffer, bsl::size_t dstCapacity, const unsigned short *srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numBytesWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::string *dstString, const wchar_t *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::vector< char > *dstVector, const unsigned short *srcString, bsl::size_t srcLengthInWords, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(char *dstBuffer, bsl::size_t dstCapacity, const wchar_t *srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numBytesWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::vector< char > *dstVector, const bsl::wstring_view &srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static bsl::size_t computeRequiredUtf8Bytes(const wchar_t *srcBuffer, const wchar_t *endPtr=0, ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(std::wstring *dstString, const bsl::string_view &srcString, bsl::size_t *numCodePointsWritten=0, wchar_t errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static bsl::size_t computeRequiredUtf8Bytes(const unsigned short *srcBuffer, const unsigned short *endPtr=0, ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(bsl::wstring *dstString, const char *srcString, bsl::size_t *numCodePointsWritten=0, wchar_t errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::string *dstString, const unsigned short *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static bsl::size_t computeRequiredUtf16Words(const char *srcBuffer, const char *endPtr=0)
static int utf8ToUtf16(wchar_t *dstBuffer, bsl::size_t dstCapacity, const char *srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numWordsWritten=0, wchar_t errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(bsl::wstring *dstString, const bsl::string_view &srcString, bsl::size_t *numCodePointsWritten=0, wchar_t errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::vector< char > *dstVector, const unsigned short *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::vector< char > *dstVector, const bsl::wstring_view &srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(std::wstring *dstString, const char *srcString, bsl::size_t *numCodePointsWritten=0, wchar_t errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(std::vector< unsigned short > *dstVector, const char *srcString, bsl::size_t *numCodePointsWritten=0, unsigned short errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(std::string *dstString, const unsigned short *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(unsigned short *dstBuffer, bsl::size_t dstCapacity, const bsl::string_view &srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numWordsWritten=0, unsigned short errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(unsigned short *dstBuffer, bsl::size_t dstCapacity, const char *srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numWordsWritten=0, unsigned short errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(bsl::vector< unsigned short > *dstVector, const bsl::string_view &srcString, bsl::size_t *numCodePointsWritten=0, unsigned short errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(std::vector< unsigned short > *dstVector, const bsl::string_view &srcString, bsl::size_t *numCodePointsWritten=0, unsigned short errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(bsl::vector< char > *dstVector, const wchar_t *srcString, bsl::size_t *numCodePointsWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf16ToUtf8(char *dstBuffer, bsl::size_t dstCapacity, const bsl::wstring_view &srcString, bsl::size_t *numCodePointsWritten=0, bsl::size_t *numBytesWritten=0, char errorByte='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)
static int utf8ToUtf16(bsl::vector< unsigned short > *dstVector, const char *srcString, bsl::size_t *numCodePointsWritten=0, unsigned short errorWord='?', ByteOrder::Enum byteOrder=ByteOrder::e_HOST)