def_8655.htm
来自「C++标准库 C++标准库 C++标准库 C++标准库」· HTM 代码 · 共 269 行 · 第 1/2 页
HTM
269 行
<LI><P>Define the code conversion facet.</P></LI><LI><P>Instantiate new stream types using the new character traits type.</P></LI><LI><P>Imbue a file stream's buffer with a locale that carries the new code conversion facet.</P></LI></OL><P>These steps are explained in detail in the following sections.</P></LI></OL><A NAME="2.13.4.1"><H4>2.13.4.1 Define a New Conversion State Type</H4></A><P>While parsing or creating a sequence of multibytes in a state-dependent multibyte encoding, the code conversion facet has to maintain a conversion state. This state is by default of type <SAMP>mbstate_t</SAMP>, which is the implementation-dependent state type defined by the C library. If this type does not suffice to keep track of the conversion state, you have to provide your own conversion state type. We will see how this is done in the code below, but please note first that the new state type must have the following member functions:</P><UL><LI><P>A constructor. The argument <SAMP>0</SAMP> has the special meaning of creating a conversion state object that represents the initial conversion state;</P></LI><LI><P>Copy constructor and assignment;</P></LI><LI><P>Comparison for equality and inequality.</P></LI></UL><P>Now here is the sketch of a new conversion state type:</P><PRE>class JISstate_t {public: JISstate_t( int state=0 ) : state_(state) { ; } JISstate_t(const JISstate_t& state) : state_(state.state_) { ; } JISstate_t& operator=(const JISstate_t& state) { if ( &state != this ) state_= state.state_; return *this; } JISstate_t& operator=(const int state) { state_= state; return *this; } bool operator==(const JISstate_t& state) const { return ( state_ == state.state_ ); } bool operator!=(const JISstate_t& state) const { return ( !(state_ == state.state_) ); } private: int state_; };</PRE></LI></OL><A NAME="2.13.4.2"><H4>2.13.4.2 Define a New Character Traits Type</H4></A><P>The conversion state type is part of the character traits. Hence, with a new conversion state type, you need a new character traits type.</P><P>Rogue Wave's implementation of the <I>Standard C++ Library</I> has a non-standard extension to the standard character traits class template <SAMP>char_traits</SAMP>. The extension is an additional template parameter for the conversion state type. For this reason, you can create a new character traits type by instantiating the character traits with your new conversion state type:</P><PRE>char_traits<wchar_t, JISstate_t></PRE><P>However, if you do not want to rely on a non-standard and thus non-portable feature of the library, you have to define a new character traits type and redefine the necessary types:</P><PRE>struct JIS_char_traits: public char_traits<wchar_t> { typedef JISstate_t state_type; typedef fpos<state_type> pos_type; typedef wstreamoff off_type;};</PRE><A NAME="2.13.4.3"><H4>2.13.4.3 Define the Code Conversion Facet</H4></A><P>Just as in the first example, you have to define the actual code conversion facet. The steps are basically the same as before, too: define a new class template for the new code conversion type and specialize it. The code would look like this:</P><PRE>template <class internT, class externT, class stateT>class UnicodeJISConversion: public codecvt<internT, externT, stateT>{};class UnicodeJISConversion<wchar_t, char, JISstate_t>: public codecvt<wchar_t, char, JISstate_t>{protected: result do_in(JISstate_t& state, const char* from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_limit, wchar_t*& to_next) const; result do_out(JISstate_t& state, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_limit, char*& to_next) const; bool do_always_noconv() const throw() { return false; }; int do_encoding() const throw(); { return -1; } };</PRE><P>In this case, the function <SAMP>do_encoding()</SAMP>has to return -1, which identifies the code conversion as state-dependent. Again, the functions <SAMP>in()</SAMP> and <SAMP>out()</SAMP> have to conform to the error indication policy explained under class <B><I><B><I>codecvt</I></B></B></I> in the <I>Class Reference.</I></P><P>The distinguishing characteristic of a state-independent conversion is that the conversion state argument to <SAMP>in()</SAMP> and <SAMP>out()</SAMP> is used for communication between the file stream buffer and the code conversion facet. The file stream buffer is responsible for creating, maintaining, and deleting the conversion state. At the beginning, the file stream buffer creates a conversion state object that represents the initial conversion state and hands it over to the code conversion facet. The facet modifies it according to the conversion it performs. The file stream buffer receives it and stores it between two subsequent code conversions.</P><A NAME="2.13.4.4"><H4>2.13.4.4 Use the New Code Conversion Facet</H4></A><P>Here is an example of how the new code conversion facet can be used:</P><PRE>typedef basic_fstream<wchar_t,JIS_char_traits> JIS_fstream; \\1JIS_fstream inout("/tmp/fil");UnicodeJISConversion<wchar_t,char,JISstate_t> cvtfac;locale cvtloc(locale(),&cvtfac);inout.rdbuf()->pubimbue(cvtloc) \\2wcout << inout.rdbuf(); \\3</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>Our Unicode-JIS code conversion needs a conversion state type different from the default type <SAMP>mbstate_t</SAMP>. Since the conversion state type is contained in the character traits, we have to create a new file type. Instead of <SAMP>JIS_char_traits</SAMP>, we could have taken advantage of the non-standard extension to the character traits template and have used <SAMP>char_traits<wchar_t,JISstate_t></SAMP>.</TD></TR><TR VALIGN="top"><TD>//2</TD><TD>Here the stream buffer's locale is replaced by a copy of the global locale that has a Unicode-JIS code conversion facet.</TD></TR><TR VALIGN="top"><TD>//3</TD><TD>The content of the JIS encoded file <SAMP>"/tmp/fil"</SAMP> is read, automatically converted to Unicode, and written to <SAMP>wcout</SAMP>.</TD></TR></TABLE><HR><A HREF="cre_2288.htm"><IMG SRC="images/prev.gif"></A> <A HREF="booktoc2.htm"><IMG SRC="images/toc.gif"></A><A HREF="dif_2395.htm"><IMG SRC="images/next.gif"></A><P>©Copyright 1996, Rogue Wave Software, Inc.</P></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?