📄 wstring
字号:
// wstring -- convert wide strings using codecvt facet
#pragma once
#ifndef _CVT_WSTRING_
#define _CVT_WSTRING_
#ifndef RC_INVOKED
#include <cstring>
#include <locale>
#include <stdexcept>
#include <string>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
namespace stdext {
namespace cvt {
// TEMPLATE CLASS wstring_convert
template<class _Codecvt,
class _Elem = wchar_t>
class wstring_convert
{ // converts between _Elem (wide) and char (byte) strings
enum {_BUF_INC = 8, _BUF_MAX = 16};
void _Init(_Codecvt *_Pcvt_arg = new _Codecvt)
{ // initialize the object
_Pcvt = _Pcvt_arg;
_Loc = _STD _ADDFAC(_Loc, _Pcvt);
_Nconv = 0;
}
public:
typedef _STD basic_string<char> byte_string;
typedef _STD basic_string<_Elem> wide_string;
typedef typename _Codecvt::state_type state_type;
typedef typename wide_string::traits_type::int_type int_type;
wstring_convert()
: _Has_berr(false), _Has_werr(false), _Has_state(false)
{ // construct with no error strings
_Init();
}
wstring_convert(_Codecvt *_Pcvt_arg)
: _Has_berr(false), _Has_werr(false), _Has_state(false)
{ // construct with no error strings and codecvt
_Init(_Pcvt_arg);
}
wstring_convert(_Codecvt *_Pcvt_arg, state_type _State_arg)
: _Has_berr(false), _Has_werr(false), _Has_state(true)
{ // construct with no error strings, codecvt, and state
_Init(_Pcvt_arg);
_State = _State_arg;
}
wstring_convert(const byte_string& _Berr_arg)
: _Has_berr(true), _Has_werr(false), _Has_state(false),
_Berr(_Berr_arg)
{ // construct with byte error string
_Init();
}
wstring_convert(const byte_string& _Berr_arg,
const wide_string& _Werr_arg)
: _Has_berr(true), _Has_werr(true), _Has_state(false),
_Berr(_Berr_arg), _Werr(_Werr_arg)
{ // construct with byte and wide error strings
_Init();
}
virtual ~wstring_convert()
{ // destroy the object
}
size_t converted() const
{ // get conversion count
return (_Nconv);
}
state_type state() const
{ // get state
return (_State);
}
wide_string from_bytes(char _Byte)
{ // convert a byte to a wide string
return (from_bytes(&_Byte, &_Byte + 1));
}
wide_string from_bytes(const char *_Ptr)
{ // convert a NTBS to a wide string
return (from_bytes(_Ptr, _Ptr + strlen(_Ptr)));
}
wide_string from_bytes(const byte_string& _Bstr)
{ // convert a byte string to a wide string
const char *_Ptr = _Bstr.c_str();
return (from_bytes(_Ptr, _Ptr + _Bstr.size()));
}
wide_string from_bytes(const char *_First, const char *_Last)
{ // convert byte sequence [_First, _Last) to a wide string
static state_type _State0;
wide_string _Wbuf, _Wstr;
const char *_First_sav = _First;
if (!_Has_state)
_State = _State0; // reset state if not remembered
_Wbuf.append((_CSTD size_t)_BUF_INC, (_Elem)'\0');
for (_Nconv = 0; _First != _Last; _Nconv = _First - _First_sav)
{ // convert one or more bytes
_Elem *_Dest = &*_Wbuf.begin();
_Elem *_Dnext;
switch (_Pcvt->in(_State,
_First, _Last, _First,
_Dest, _Dest + _Wbuf.size(), _Dnext))
{ // test result of converting one or more bytes
case _Codecvt::partial:
case _Codecvt::ok:
if (_Dest < _Dnext)
_Wstr.append(_Dest, (_CSTD size_t)(_Dnext - _Dest));
else if (_Wbuf.size() < _BUF_MAX)
_Wbuf.append((_CSTD size_t)_BUF_INC, '\0');
else if (_Has_werr)
return (_Werr);
else
_THROW(_STD range_error, "bad conversion");
break;
case _Codecvt::noconv:
for (; _First != _Last; ++_First)
_Wstr.append((_CSTD size_t)1,
(_Elem)(unsigned char)*_First);
break; // no conversion, just copy code values
default:
if (_Has_werr)
return (_Werr);
else
_THROW(_STD range_error, "bad conversion");
}
}
return (_Wstr);
}
byte_string to_bytes(_Elem _Char)
{ // convert a wide char to a byte string
return (to_bytes(&_Char, &_Char + 1));
}
byte_string to_bytes(const _Elem *_Wptr)
{ // convert a NTWCS to a byte string
const _Elem *_Next = _Wptr;
for (; (int_type)*_Next != 0; ++_Next)
;
return (to_bytes(_Wptr, _Next));
}
byte_string to_bytes(const wide_string& _Wstr)
{ // convert a wide string to a byte string
const _Elem *_Wptr = _Wstr.c_str();
return (to_bytes(_Wptr, _Wptr + _Wstr.size()));
}
byte_string to_bytes(const _Elem *_First, const _Elem *_Last)
{ // convert wide sequence [_First, _Last) to a byte string
static state_type _State0;
byte_string _Bbuf, _Bstr;
const _Elem *_First_sav = _First;
if (!_Has_state)
_State = _State0; // reset state if not remembered
_Bbuf.append((_CSTD size_t)_BUF_INC, '\0');
for (_Nconv = 0; _First != _Last; _Nconv = _First - _First_sav)
{ // convert one or more wide chars
char *_Dest = &*_Bbuf.begin();
char *_Dnext;
switch (_Pcvt->out(_State,
_First, _Last, _First,
_Dest, _Dest + _Bbuf.size(), _Dnext))
{ // test result of converting one or more wide chars
case _Codecvt::partial:
case _Codecvt::ok:
if (_Dest < _Dnext)
_Bstr.append(_Dest, (_CSTD size_t)(_Dnext - _Dest));
else if (_Bbuf.size() < _BUF_MAX)
_Bbuf.append((_CSTD size_t)_BUF_INC, '\0');
else if (_Has_berr)
return (_Berr);
else
_THROW(_STD range_error, "bad conversion");
break;
case _Codecvt::noconv:
for (; _First != _Last; ++_First)
_Bstr.append((_CSTD size_t)1,
(char)(int_type)*_First);
break; // no conversion, just copy code values
default:
if (_Has_berr)
return (_Berr);
else
_THROW(_STD range_error, "bad conversion");
}
}
return (_Bstr);
}
private:
_Codecvt *_Pcvt; // the codecvt facet
_STD locale _Loc; // manages reference to codecvt facet
byte_string _Berr;
wide_string _Werr;
state_type _State; // the remembered state
bool _Has_state;
bool _Has_berr;
bool _Has_werr;
size_t _Nconv;
};
} // namespace cvt
} // namespace stdext
#pragma warning(pop)
#pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _CVT_WSTRING_ */
/*
* Copyright (c) 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.20:0009 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -