4.4 Implicit Conversions
A
conversion context specifies the converter to use for
implicit conversions to and from Unicode. This is a convenient alternative to converting character sequences explicitly using
RWUToUnicodeConverter and
RWUFromUnicodeConverter. The Internationalization Module provides three conversion context classes:
4.4.1 The Conversion Context Stacks
The conversion context classes manage internal, per-thread stacks of conversion context instances. A conversion context constructor pushes a reference to the new instance onto the appropriate conversion context stack(s). A destructor pops the instance off the stack(s). The top-level element of a stack defines the conversion context currently in effect for all implicit conversions.
The current conversion context remains in effect until either a new conversion context instance is constructed, or until it goes out of scope and is destroyed. Note that the current conversion context also applies within any functions called from the block where the context was created.
4.4.2 Creating Conversion Contexts
A conversion context instance is associated with an encoding at construction time. This association cannot be changed once a conversion context object is instantiated. For example, the following code creates an
RWUToUnicodeConversionContext instance for subsequent implicit conversions from ISO-8859-1 to UTF-16:
RWUToUnicodeConversionContext fromIso_8859_1Context("ISO-8859-1");
Similarly, the following code constructs an
RWUFromUnicodeConversionContext instance for subsequent implicit conversions from UTF-16 to Shift-JIS:
RWUFromUnicodeConversionContext toShiftJisContext("Shift-JIS");
The encoding names recognized by the Internationalization Module can be accessed programmatically, as described in
Section 4.2.
4.4.3 Implicitly Converting to Unicode
Each
RWUToUnicodeConversionContext instance contains a unique
RWUToUnicodeConverter instance used for all relevant implicit conversions. For example, this code sets the to-Unicode conversion context to ASCII, then uses implicit conversion to construct an
RWUString:
RWUToUnicodeConversionContext fromAsciiContext("US-ASCII");
RWUString str = "hello";
The code above is a convenient alternative to the following explicit conversion, especially when you are creating many strings with the same encoding conversion:
RWUToUnicodeConverter fromAscii("US-ASCII");
RWUString str("hello", fromAscii);
As outlined in
Section 4.4.1,
RWUToUnicodeConversionContext manages internal, per-thread stacks of
RWUToUnicodeConversionContext instances. The static method
RWUToUnicodeConversionContext::getContext() returns a reference to the
RWUToUnicodeConversionContext currently in effect.
Within any local scope, you can create an
RWUToUnicodeConversionContext. For example, this code creates two conversion contexts, one nested inside the other:
RWUToUnicodeConversionContext fromAsciiContext("US-ASCII");
RWUString str1 = "hello";
{
RWUToUnicodeConversionContext
fromIso_8859_1Context("ISO-8859-1");
RWUString str2 = "goodbye";
}
At the closing curly brace, the nested
RWUToUnicodeConversionContext instance goes out of scope and is destroyed. Destroying the instance automatically pops it off the current thread’s to-Unicode stack.
Do not create unnamed, temporary instances of
RWUToUnicodeConversionContext. The destructors for such objects pop the context off the context stack immediately. For example, although this code would compile, it may not have the intended effect:
RWUToUnicodeConversionContext("US-ASCII"); // Wrong!
RWUString str("hello");
Do not create unnamed, temporary instances of RWUToUnicodeConversionContext.
The
getConverter() method returns a reference to the
RWUToUnicodeConverter instance held by an
RWUToUnicodeConversionContext object. For example, you might want to set the conversion error-handling behavior of the underlying converter (
Section 4.3.4), as follows:
RWUToUnicodeConversionContext fromAsciiContext("US-ASCII");
fromAsciiContext.getConverter().setErrorResponse(
RWUToUnicodeConverter::Skip);
RWUString str("hello");
4.4.4 Implicitly Converting from Unicode
Each
RWUFromUnicodeConversionContext instance contains a unique
RWUFromUnicodeConverter instance used for all relevant implicit conversions.
For example, if
str is an
RWUString instance, you could write out a Shift-JIS representation of
str like this:
RWUFromUnicodeConversionContext toShiftJisContext("Shift-JIS");
std::cout << str << std::endl;
The stream insertion operator for
RWUString writes the sequence of bytes that are produced when the contents of
str are converted into the encoding specified by the currently active
RWUFromUnicodeConversionContext.
When called with no arguments, the
RWUString::toBytes() method also serializes the contents of an
RWUString using the currently active
RWUFromUnicodeConversionContext.
As outlined in
Section 4.4.1,
RWUFromUnicodeConversionContext manages internal, per-thread stacks of
RWUFromUnicodeConversionContext instances. The static
RWUFromUnicodeConversionContext::getContext() method returns a reference to the
RWUFromUnicodeConversionContext currently in effect.
Within any local scope, you can create an
RWUFromUnicodeConversionContext. For example, this code outputs the contents of
str first in the ISO-8859-1 encoding, then in Shift-JIS:
RWUFromUnicodeConversionContext toShiftJisContext("Shift-JIS");
{
RWUFromUnicodeConversionContext
toIso_8859_1Context("ISO-8859-1");
std::cout << str << std::endl; // ISO-8859-1
}
std::cout << str << std::endl; // Shift-JIS
At the closing curly brace, the nested
RWUFromUnicodeConversionContext instance goes out of scope and is destroyed. Destroying the instance automatically pops it off the current thread’s from-Unicode stack.
Do not create unnamed, temporary instances of
RWUFromUnicodeConversionContext. The destructors for such objects pop the context off the context stack immediately. For example, although this code would compile, it may not have the intended effect:
RWUFromUnicodeConversionContext("ISO-8859-1"); // Wrong!
std::cout << str << std::endl;
Do not create unnamed, temporary instances of RWUFromUnicodeConversionContext.
The
getConverter() method returns a reference to the
RWUFromUnicodeConverter instance held by an
RWUFromUnicodeConversionContext object. For example, you might want to set the conversion error-handling behavior of the underlying converter (
Section 4.3.4):
RWUFromUnicodeConversionContext toShiftJisContext("Shift-JIS");
toShiftJisContext.getConverter().setErrorResponse(
RWUFromUnicodeConverter::EscapeNativeHexadecimal);
std::cout << str << std::endl;
4.4.5 Bidirectional Conversions
RWUConversionContext combines the functionality provided by
RWUToUnicodeConversionContext and
RWUFromUnicodeConversionContext to provide a single convenient means for specifying the encoding for conversions to and from Unicode. For example:
RWUConversionContext context("ISO-8859-1");
RWUString str("hello");
std::cout << str << std::endl;
RWUConversionContext manages both the to-Unicode and from-Unicode conversion context stacks described in
Section 4.4.1.
As with all conversion contexts, you can create an
RWUConversionContext within any local scope. When an
RWUConversionContext instance goes out of scope, it is destroyed, and destroying the instance automatically pops it off the current thread’s to-Unicode and from-Unicode stacks.
Do not create unnamed, temporary instances of
RWUConversionContext. The destructors for such objects pop the context off the context stacks immediately. For example, although this code would compile, it may not have the intended effect:
RWUConversionContext("Shift-JIS"); // Wrong!
std::cout << str << std::endl;
Do not create unnamed, temporary instances of RWUConversionContext.
Note that
RWUConversionContext derives from both
RWUToUnicodeConversionContext and
RWUFromUnicodeConversionContext, so if you want to call either of the inherited
getConverter() methods to return a reference to one of the underlying converters, you must disambiguate them. For example, the following code sets the escape sequence for the underlying
RWUFromUnicodeConverter instance:
RWUConversionContext context("Shift-JIS");
context.RWUFromUnicodeConverter::getConverter().setErrorResponse(
RWUFromUnicodeConverter::EscapeNativeHexadecimal);
std::cout << str << std::endl;