// xlocale internal header (from ) #ifndef _XLOCALE_ #define _XLOCALE_ #include #include #include #include #include #include #ifdef _MSC_VER /* * Currently, all MS C compilers for Win32 platforms default to 8 byte * alignment. */ #pragma pack(push,8) #endif /* _MSC_VER */ // CLASS locale class locale { public: enum _Category {collate = _M_COLLATE, ctype = _M_CTYPE, monetary = _M_MONETARY, numeric = _M_NUMERIC, time = _M_TIME, messages = _M_MESSAGE, all = _M_ALL, none = 0}; typedef int category; // CLASS id class id { public: operator size_t() {_Lockit _Lk; if (_Id == 0) _Id = ++_Id_cnt; return (_Id); } private: size_t _Id; static int _Id_cnt; }; class _Locimp; // class facet class facet { friend class locale; friend class _Locimp; public: static size_t _Getcat() {return (0); } void _Incref() {_Lockit _Lk; if (_Refs < (size_t)(-1)) ++_Refs; } _PROTECTED: virtual ~facet() {} protected: explicit facet(size_t _R = 0) : _Refs(_R) {} private: facet(const facet&); // undefined const facet& operator=(const facet&); // undefined facet *_Decref() {_Lockit _Lk; if (0 < _Refs && _Refs < (size_t)(-1)) --_Refs; return (_Refs == 0 ? this : 0); } size_t _Refs; }; // CLASS _Locimp class _Locimp : public facet { _PROTECTED: ~_Locimp(); private: friend class locale; _Locimp(bool _Xp = false); _Locimp(const _Locimp&); void _Addfac(facet *, size_t); static _Locimp * __cdecl _Makeloc(const _Locinfo&, category, _Locimp *, const locale *); static void __cdecl _Makewloc(const _Locinfo&, category, _Locimp *, const locale *); static void __cdecl _Makexloc(const _Locinfo&, category, _Locimp *, const locale *); facet **_Fv; size_t _Nfv; category _Cat; bool _Xpar; string _Name; static _Locimp *_Clocptr, *_Global; }; locale& _Addfac(facet *, size_t, size_t); bool operator()(const string&, const string&) const; locale() _THROW0() : _Ptr(_Init()) {_Locimp::_Global->_Incref(); } locale(_Uninitialized) {} locale(const locale& _X) _THROW0() : _Ptr(_X._Ptr) {_Ptr->_Incref(); } locale(const locale&, const locale&, category); explicit locale(const char *, category = all); locale(const locale&, const char *, category); ~locale() _THROW0() {if (_Ptr != 0) delete _Ptr->_Decref(); } locale& operator=(const locale& _X) _THROW0() {if (_Ptr != _X._Ptr) {delete _Ptr->_Decref(); _Ptr = _X._Ptr; _Ptr->_Incref(); } return (*this); } string name() const {return (_Ptr->_Name); } const facet *_Getfacet(size_t _Id, bool _Xp = false) const; bool _Iscloc() const; bool operator==(const locale& _X) const; static const locale& __cdecl classic(); static locale __cdecl global(const locale&); static locale __cdecl empty(); private: locale(_Locimp *_P) : _Ptr(_P) {} static _Locimp *__cdecl _Init(); _Locimp *_Ptr; }; _BITMASK_OPS(locale::_Category); // SUPPORT TEMPLATES #define _ADDFAC(loc, pfac) _Addfac(loc, pfac) #define _USEFAC(loc, fac) use_facet(loc, (fac *)0) #define _USE(loc, fac) use_facet(loc, (fac *)0, true) template inline locale _Addfac(locale _X, _F *_Fac) {return (_X._Addfac(_Fac, _F::id, _F::_Getcat())); } template inline const _F& __cdecl use_facet(const locale& _L, const _F *, bool _Cfacet = false) {static const locale::facet *_Psave = 0; size_t _Id = _F::id; const locale::facet *_Pf = _L._Getfacet(_Id, true); if (_Pf != 0) ; else if (!_Cfacet || !_L._Iscloc()) _THROW(bad_cast("missing locale facet")); else if (_Psave == 0) _Pf = _Psave = new _F, ((locale::facet *)_Pf)->_Incref(); else _Pf = _Psave; return (*(const _F *)_Pf); } // TEMPLATE FUNCTION _Narrow #define _NARROW(T, V) _Narrow((T)(V)) template inline int _Narrow(_E _C) // needs _E::operator char() {return ((unsigned char)(char)_C); } inline int _Narrow(wchar_t _C) {return (wctob(_C)); } // TEMPLATE FUNCTION _Widen #define _WIDEN(T, V) _Widen(V, (T *)0) template inline _E _Widen(char _Ch, _E *) // needs _E(char) {return (_Ch); } inline wchar_t _Widen(char _Ch, wchar_t *) {return (btowc(_Ch)); } // TEMPLATE FUNCTION _Getloctxt template inline int __cdecl _Getloctxt(_II& _F, _II& _L, size_t _N, const _E *_S) {for (size_t _I = 0; _S[_I] != (_E)0; ++_I) if (_S[_I] == _S[0]) ++_N; string _Str(_N, '\0'); int _Ans = -2; for (size_t _J = 1; ; ++_J, ++_F, _Ans = -1) {bool _Pfx; size_t _I, _K; for (_I = 0, _K = 0, _Pfx = false; _K < _N; ++_K) {for (; _S[_I] != (_E)0 && _S[_I] != _S[0]; ++_I) ; if (_Str[_K] != '\0') _I += _Str[_K]; else if (_S[_I += _J] == _S[0] || _S[_I] == (_E)0) {_Str[_K] = _J < 127 ? _J : 127; _Ans = _K; } else if (_F == _L || _S[_I] != *_F) _Str[_K] = _J < 127 ? _J : 127; else _Pfx = true; } if (!_Pfx || _F == _L) break; } return (_Ans); } // TEMPLATE FUNCTION _Maklocstr #define _MAKLOCSTR(T, S) _Maklocstr(S, (T *)0) template inline _E * __cdecl _Maklocstr(const char *_S, _E *) {size_t _L = strlen(_S) + 1; _E *_X = new _E[_L]; for (_E *_P = _X; 0 < _L; --_L, ++_P, ++_S) *_P = _WIDEN(_E, *_S); return (_X); } // STRUCT codecvt_base class codecvt_base : public locale::facet { public: enum _Result {ok, partial, error, noconv}; _BITMASK(_Result, result); codecvt_base(size_t _R = 0) : locale::facet(_R) {} bool always_noconv() const _THROW0() {return (do_always_noconv()); } int max_length() const _THROW0() {return (do_max_length()); } protected: virtual bool do_always_noconv() const _THROW0() {return (true); } virtual int do_max_length() const _THROW0() {return (1); } }; _BITMASK_OPS(codecvt_base::_Result); // TEMPLATE CLASS codecvt template class codecvt : public codecvt_base { public: typedef _E from_type; typedef _To to_type; typedef _St state_type; result convert(_St& _State, const _E *_F1, const _E *_L1, const _E *& _M01, _To *_F2, _To *_L2, _To *& _M02) const {return (do_convert(_State, _F1, _L1, _M01, _F2, _L2, _M02)); } int length(_St& _State, const _E *_F1, const _E *_L1, size_t _N2) const _THROW0() {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 _Getcat() {return (_LC_CTYPE); } _PROTECTED: virtual ~codecvt() {}; protected: void _Init(const _Locinfo& _Lobj) {_Cvt = _Lobj._Getcvt(); } virtual result do_convert(_St& _State, const _E *_F1, const _E *, const _E *& _M01, _To *_F2, _To *, _To *& _M02) const {_M01 = _F1, _M02 = _F2; return (noconv); } virtual int do_length(_St& _State, const _E *_F1, const _E *_L1, size_t _N2) const _THROW0() {return (_N2 < _L1 - _F1 ? _N2 : _L1 - _F1); } private: _Locinfo::_Cvtvec _Cvt; }; template locale::id codecvt<_E, _To, _St>::id; // CLASS codecvt class codecvt : public codecvt_base { public: typedef char _E; typedef wchar_t _To; typedef mbstate_t _St; typedef _E from_type; typedef _To to_type; typedef _St state_type; result convert(_St& _State, const _E *_F1, const _E *_L1, const _E *& _M01, _To *_F2, _To *_L2, _To *& _M02) const {return (do_convert(_State, _F1, _L1, _M01, _F2, _L2, _M02)); } int length(_St& _State, const _E *_F1, const _E *_L1, size_t _N2) const _THROW0() {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 _Getcat() {return (_LC_CTYPE); } _PROTECTED: virtual ~codecvt() {}; protected: void _Init(const _Locinfo& _Lobj) {_Cvt = _Lobj._Getcvt(); } virtual result do_convert(_St& _State, const _E *_F1, const _E *_L1, const _E *& _M01, _To *_F2, _To *_L2, _To *& _M02) const {_M01 = _F1, _M02 = _F2; result _Ans = _M01 == _L1 ? ok : partial; int _N; while (_M01 != _L1 && _M02 != _L2) switch (_N = _Mbrtowc(_M02, _M01, _L1 - _M01, &_State, &_Cvt)) {case -2: _M01 = _L1; return (_Ans); case -1: return (error); case 0: _N = strlen(_M01) + 1; default: // fall through _M01 += _N, ++_M02, _Ans = ok; } return (_Ans); } virtual int do_length(_St& _State, const _E *_F1, const _E *_L1, size_t _N2) const _THROW0() {const _E *_M01; int _N; for (_M01 = _F1; _M01 != _L1 && 0 < _N2; _M01 += _N, --_N2) if ((_N = _Mbrtowc(0, _M01, _L1 - _M01, &_State, &_Cvt)) < 0) break; else if (_N == 0) _N = 1; return (_M01 - _F1); } virtual bool do_always_noconv() const _THROW0() {return (false); } private: _Locinfo::_Cvtvec _Cvt; }; // CLASS codecvt class codecvt : public codecvt_base { public: typedef wchar_t _E; typedef char _To; typedef mbstate_t _St; typedef _E from_type; typedef _To to_type; typedef _St state_type; result convert(_St& _State, const _E *_F1, const _E *_L1, const _E *& _M01, _To *_F2, _To *_L2, _To *& _M02) const {return (do_convert(_State, _F1, _L1, _M01, _F2, _L2, _M02)); } int length(_St& _State, const _E *_F1, const _E *_L1, size_t _N2) const _THROW0() {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 _Getcat() {return (_LC_CTYPE); } _PROTECTED: virtual ~codecvt() {}; protected: void _Init(const _Locinfo& _Lobj) {_Cvt = _Lobj._Getcvt(); } virtual result do_convert(_St& _State, const _E *_F1, const _E *_L1, const _E *& _M01, _To *_F2, _To *_L2, _To *& _M02) const {_M01 = _F1, _M02 = _F2; result _Ans = _M01 == _L1 ? ok : partial; int _N; while (_M01 != _L1 && _M02 != _L2) if (MB_CUR_MAX <= _L2 - _M02) if ((_N = _Wcrtomb(_M02, *_M01, &_State, &_Cvt)) <= 0) return (error); else ++_M01, _M02 += _N, _Ans = ok; else {_To _Buf[MB_LEN_MAX]; _St _Stsave = _State; if ((_N = _Wcrtomb(_Buf, *_M01, &_State, &_Cvt)) <= 0) return (error); else if (_L2 - _M02 < _N) {_State = _Stsave; return (_Ans); } else {memcpy(_M02, _Buf, _N); ++_M01, _M02 += _N, _Ans = ok; }} return (_Ans); } virtual int do_length(_St& _State, const _E *_F1, const _E *_L1, size_t _N2) const _THROW0() {const _E *_M01; _To _Buf[MB_LEN_MAX]; int _N; for (_M01 = _F1; _M01 != _L1 && 0 < _N2; ++_M01, _N2 -= _N) if ((_N = _Wcrtomb(_Buf, *_M01, &_State, &_Cvt)) <= 0 || _N2 < _N) break; return (_M01 - _F1); } virtual bool do_always_noconv() const _THROW0() {return (false); } virtual int do_max_length() const _THROW0() {return (MB_LEN_MAX); } private: _Locinfo::_Cvtvec _Cvt; }; // TEMPLATE CLASS codecvt_byname template class codecvt_byname : public codecvt<_E, _TYPE, _St> { public: explicit codecvt_byname(const char *_S, size_t _R = 0) : codecvt<_E, _TYPE, _St>(_Locinfo(_S), _R) {} _PROTECTED: virtual ~codecvt_byname() {} }; // STRUCT ctype_base struct ctype_base : public locale::facet { enum _Mask {alnum = _DI|_LO|_UP|_XA, alpha = _LO|_UP|_XA, cntrl = _BB, digit = _DI, graph = _DI|_LO|_PU|_UP|_XA, lower = _LO, print = _DI|_LO|_PU|_SP|_UP|_XA, punct = _PU, space = _CN|_SP|_XS, upper = _UP, xdigit = _XD}; // _BITMASK(_Mask, mask); typedef short mask; // to match ctype_base(size_t _R = 0) : locale::facet(_R) {} }; _BITMASK_OPS(ctype_base::_Ctype); // TEMPLATE CLASS ctype template class ctype : public ctype_base { public: typedef _E char_type; bool is(mask _M, _E _C) const {return (do_is(_M, _C)); } const _E *is(const _E *_F, const _E *_L, mask *_V) const {return (do_is(_F, _L, _V)); } const _E *scan_is(mask _M, const _E *_F, const _E *_L) const {return (do_scan_is(_M, _F, _L)); } const _E *scan_not(mask _M, const _E *_F, const _E *_L) const {return (do_scan_not(_M, _F, _L)); } _E tolower(_E _C) const {return (do_tolower(_C)); } const _E *tolower(_E *_F, const _E *_L) const {return (do_tolower(_F, _L)); } _E toupper(_E _C) const {return (do_toupper(_C)); } const _E *toupper(_E *_F, const _E *_L) const {return (do_toupper(_F, _L)); } _E widen(char _X) const {return (do_widen(_X)); } const char *widen(const char *_F, const char *_L, _E *_V) const {return (do_widen(_F, _L, _V)); } char narrow(_E _C, char _D = '\0') const {return (do_narrow(_C, _D)); } const _E *narrow(const _E *_F, const _E *_L, char _D, char *_V) const {return (do_narrow(_F, _L, _D, _V)); } static locale::id id; explicit ctype(size_t _R = 0) : ctype_base(_R) {_Init(_Locinfo()); } ctype(const _Locinfo& _Lobj, size_t _R = 0) : ctype_base(_R) {_Init(_Lobj); } static size_t _Getcat() {return (_LC_CTYPE); } _PROTECTED: virtual ~ctype() {if (_Ctype._Delfl) free((void *)_Ctype._Table); } protected: void _Init(const _Locinfo& _Lobj) {_Ctype = _Lobj._Getctype(); } virtual bool do_is(mask _M, _E _C) const {return (_Ctype._Table[narrow(_C)] & _M); } virtual const _E *do_is(const _E *_F, const _E *_L, mask *_V) const {for (; _F != _L; ++_F, ++_V) *_V = _Ctype._Table[narrow(*_F)]; return (_F); } virtual const _E *do_scan_is(mask _M, const _E *_F, const _E *_L) const {for (; _F != _L && !is(_M, *_F); ++_F) ; return (_F); } virtual const _E *do_scan_not(mask _M, const _E *_F, const _E *_L) const {for (; _F != _L && is(_M, *_F); ++_F) ; return (_F); } virtual _E do_tolower(_E _C) const {return (widen(_Tolower(narrow(_C), &_Ctype))); } virtual const _E *do_tolower(_E *_F, const _E *_L) const {for (; _F != _L; ++_F) *_F = _Tolower(*_F, &_Ctype); return ((const _E *)_F); } virtual _E do_toupper(_E _C) const {return (widen(_Toupper(narrow(_C), &_Ctype))); } virtual const _E *do_toupper(_E *_F, const _E *_L) const {for (; _F != _L; ++_F) *_F = _Toupper(*_F, &_Ctype); return ((const _E *)_F); } virtual _E do_widen(char _X) const {return (_WIDEN(_E, _X)); } virtual const char *do_widen(const char *_F, const char *_L, _E *_V) const {for (; _F != _L; ++_F, ++_V) *_V = _WIDEN(_E, *_F); return (_F); } virtual char do_narrow(_E _C, char) const {return (_NARROW(_E, _C)); } virtual const _E *do_narrow(const _E *_F, const _E *_L, char, char *_V) const {for (; _F != _L; ++_F, ++_V) *_V = _NARROW(_E, *_F); return (_F); } private: _Locinfo::_Ctypevec _Ctype; }; template locale::id ctype<_E>::id; // CLASS ctype class ctype : public ctype_base { public: typedef char _E; typedef _E char_type; bool is(mask _M, _E _C) const {return (_Ctype._Table[(unsigned char)_C] & _M); } const _E *is(const _E *_F, const _E *_L, mask *_V) const {for (; _F != _L; ++_F, ++_V) *_V = _Ctype._Table[(unsigned char)*_F]; return (_F); } const _E *scan_is(mask _M, const _E *_F, const _E *_L) const {for (; _F != _L && !is(_M, *_F); ++_F) ; return (_F); } const _E *scan_not(mask _M, const _E *_F, const _E *_L) const {for (; _F != _L && is(_M, *_F); ++_F) ; return (_F); } _E tolower(_E _C) const {return (do_tolower(_C)); } const _E *tolower(_E *_F, const _E *_L) const {return (do_tolower(_F, _L)); } _E toupper(_E _C) const {return (do_toupper(_C)); } const _E *toupper(_E *_F, const _E *_L) const {return (do_toupper(_F, _L)); } _E widen(char _X) const {return (_X); } const _E *widen(const char *_F, const char *_L, _E *_V) const {memcpy(_V, _F, _L - _F); return (_L); } _E narrow(_E _C, char _D = '\0') const {return (_C); } const _E *narrow(const _E *_F, const _E *_L, char _D, char *_V) const {memcpy(_V, _F, _L - _F); return (_L); } static locale::id id; explicit ctype(const mask *_Tab = 0, bool _Df = false, size_t _R = 0) : ctype_base(_R) {_Init(_Locinfo()); if (_Ctype._Delfl) free((void *)_Ctype._Table), _Ctype._Delfl = false; if (_Tab == 0) _Ctype._Table = _Cltab; else _Ctype._Table = _Tab, _Ctype._Delfl = _Df; } ctype(const _Locinfo& _Lobj, size_t _R = 0) : ctype_base(_R) {_Init(_Lobj); } static size_t _Getcat() {return (_LC_CTYPE); } static const size_t table_size; _PROTECTED: virtual ~ctype() {if (_Ctype._Delfl) free((void *)_Ctype._Table); } protected: void _Init(const _Locinfo& _Lobj) {_Ctype = _Lobj._Getctype(); if (_Cltab == 0) _Cltab = _Ctype._Table, _Ctype._Delfl = false; } virtual _E do_tolower(_E _C) const {return (_Tolower((unsigned char)_C, &_Ctype)); } virtual const _E *do_tolower(_E *_F, const _E *_L) const {for (; _F != _L; ++_F) *_F = _Tolower(*_F, &_Ctype); return ((const _E *)_F); } virtual _E do_toupper(_E _C) const {return (_Toupper((unsigned char)_C, &_Ctype)); } virtual const _E *do_toupper(_E *_F, const _E *_L) const {for (; _F != _L; ++_F) *_F = _Toupper(*_F, &_Ctype); return ((const _E *)_F); } const mask *table() const _THROW0() {return (_Ctype._Table); } static const mask *classic_table() _THROW0() {if (_Cltab == 0) locale::classic(); // force locale::_Init() call return (_Cltab); } private: _Locinfo::_Ctypevec _Ctype; static const mask *_Cltab; }; // TEMPLATE CLASS ctype_byname template class ctype_byname : public ctype<_E> { public: explicit ctype_byname(const char *_S, size_t _R = 0) : ctype<_E>(_Locinfo(_S), _R) {} _PROTECTED: virtual ~ctype_byname() {} }; #ifdef _MSC_VER #pragma pack(pop) #endif /* _MSC_VER */ #endif /* _XLOCALE_ */ /* * Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */