Listing 3: Class codecvt<wchar_t, wchar, mbstate_t>
// CLASS codecvt<wchar_t, char, mbstate_t>
template<>
class codecvt<wchar_t, char, mbstate_t>
: public codecvt_base {
public:
typedef wchar_t _E;
typedef char _To;
typedef mbstate_t _St;
typedef _E intern_type;
typedef _To extern_type;
typedef _St state_type;
result in(_St& _State,
const _To *_F1, const _To *_L1, const _To *& _Mid1,
_E *_F2, _E *_L2, _E *& _Mid2) const
{return (do_in(_State,
_F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
result out(_St& _State,
const _E *_F1, const _E *_L1, const _E *& _Mid1,
_To *_F2, _To *_L2, _To *& _Mid2) const
{return (do_out(_State,
_F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
result unshift(_St& _State,
_To *_F2, _To *_L2, _To *& _Mid2) const
{return (do_unshift(_State,
_F2, _L2, _Mid2)); }
int length(_St& _State, const _E *_F1,
const _E *_L1, size_t _N2) const throw ()
{return (do_length(_State, _F1, _L1, _N2)); }
static locale::id id;
explicit codecvt(size_t _R = 0)
: codecvt_base(_R) {_Init(_Locinfo()); }
codecvt(const _Locinfo& _Lobj, size_t _R = 0)
: codecvt_base(_R) {_Init(_Lobj); }
static size_t _CDECL _Getcat()
{return (_X_CTYPE); }
protected:
virtual ~codecvt()
{};
void _Init(const _Locinfo& _Lobj)
{_Cvt = _Lobj._Getcvt(); }
virtual result do_in(_St& _State,
const _To *_F1, const _To *_L1, const _To *& _Mid1,
_E *_F2, _E *_L2, _E *& _Mid2) const
{_Mid1 = _F1, _Mid2 = _F2;
result _Ans = _Mid1 == _L1 ? ok : partial;
int _N;
while (_Mid1 != _L1 && _Mid2 != _L2)
switch (_N = _Mbrtowc(_Mid2, _Mid1, _L1 - _Mid1,
&_State, &_Cvt))
{case -2:
_Mid1 = _L1;
return (_Ans);
case -1:
return (error);
case 0:
_N = strlen(_Mid1) + 1;
default: // fall through
_Mid1 += _N, ++_Mid2, _Ans = ok; }
return (_Ans); }
virtual result do_out(_St& _State,
const _E *_F1, const _E *_L1, const _E *& _Mid1,
_To *_F2, _To *_L2, _To *& _Mid2) const
{_Mid1 = _F1, _Mid2 = _F2;
result _Ans = _Mid1 == _L1 ? ok : partial;
int _N;
while (_Mid1 != _L1 && _Mid2 != _L2)
if (MB_CUR_MAX <= _L2 - _Mid2)
if ((_N = _Wcrtomb(_Mid2, *_Mid1,
&_State, &_Cvt)) <= 0)
return (error);
else
++_Mid1, _Mid2 += _N, _Ans = ok;
else
{_To _Buf[MB_LEN_MAX];
_St _Stsave = _State;
if ((_N = _Wcrtomb(_Buf, *_Mid1,
&_State, &_Cvt)) <= 0)
return (error);
else if (_L2 - _Mid2 < _N)
{_State = _Stsave;
return (_Ans); }
else
{memcpy(_Mid2, _Buf, _N);
++_Mid1, _Mid2 += _N, _Ans = ok; }}
return (_Ans); }
virtual result do_unshift(_St& _State,
_To *_F2, _To *_L2, _To *& _Mid2) const
{_Mid2 = _F2;
result _Ans = ok;
int _N;
_To _Buf[MB_LEN_MAX];
_St _Stsave = _State;
if ((_N = _Wcrtomb(_Buf, L'\0', &_State, &_Cvt)) <= 0)
_Ans = error;
else if (_L2 - _Mid2 < --_N)
{_State = _Stsave;
_Ans = partial; }
else if (0 < _N)
{memcpy(_Mid2, _Buf, _N);
_Mid2 += _N; }
return (_Ans); }
virtual int do_length(_St& _State, const _E *_F1,
const _E *_L1, size_t _N2) const throw ()
{const _E *_Mid1;
_To _Buf[MB_LEN_MAX];
int _N;
for (_Mid1 = _F1; _Mid1 != _L1 && 0 < _N2;
++_Mid1, _N2 -= _N)
if ((_N = _Wcrtomb(_Buf, *_Mid1,
&_State, &_Cvt)) <= 0 || _N2 < _N)
break;
return (_Mid1 - _F1); }
virtual bool do_always_noconv() const throw ()
{return (false); }
virtual int do_max_length() const throw ()
{return (MB_LEN_MAX); }
virtual int do_encoding() const throw ()
{return (0); }
private:
_Locinfo::_Cvtvec _Cvt;
};
// must define id in an object file as follows:
//template<>
// locale::id codecvt<wchar_t, char, mbstate_t>::id = 0;
//End of File