File Index Symbol Index

// xlocbuf internal header (from <locale>)
#pragma once
#ifndef _XLOCBUF_
#define _XLOCBUF_
#ifndef RC_INVOKED
#include <xlocale>
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
#pragma warning(push) #pragma warning(disable:
4996
)
// CLASS TEMPLATE wbuffer_convert
template
<
class
_Codecvt
,
class
_Elem
=
wchar_t
,
class
_Traits
=
char_traits
<
_Elem
> > :
public
basic_streambuf
<
_Elem
,
_Traits
> {
// stream buffer associated with a codecvt facet
enum
_Mode
{
_Unused
,
_Wrote
,
_Need
,
_Got
,
_Eof
};
enum
{
_STRING_INC
=
8
};
public
:
typedef
streambuf
_Mysb
;
typedef
char_traits
<
char
>
_Byte_traits
;
typedef
typename
_Traits
::int_type
int_type
;
typedef
typename
_Traits
::pos_type
pos_type
;
typedef
typename
_Traits
::off_type
off_type
;
typedef
typename
_Codecvt
::state_type
state_type
;
explicit
wbuffer_convert
(
_Mysb
*
_Strbuf
=
nullptr
) : _State(), _Pcvt(
new
_Codecvt
), _Mystrbuf(
_Strbuf
), _Status(
_Unused
), _Nback(
0
) {
// construct with byte stream buffer pointer
_Loc
=
locale
(
_Loc
,
_Pcvt
); }
wbuffer_convert
(
_Mysb
*
_Strbuf
,
const
_Codecvt
*
_Pcvt_arg
) : _State(), _Pcvt(
_Pcvt_arg
), _Mystrbuf(
_Strbuf
), _Status(
_Unused
), _Nback(
0
) {
// construct with byte stream buffer pointer and codecvt
_Loc
=
locale
(
_Loc
,
_Pcvt
); }
wbuffer_convert
(
_Mysb
*
_Strbuf
,
const
_Codecvt
*
_Pcvt_arg
,
state_type
_State_arg
) : _State(
_State_arg
), _Pcvt(
_Pcvt_arg
), _Mystrbuf(
_Strbuf
), _Status(
_Unused
), _Nback(
0
) {
// construct with byte stream buffer pointer, codecvt, and state
_Loc
=
locale
(
_Loc
,
_Pcvt
); }
virtual
~
wbuffer_convert
()
noexcept
{
// destroy the object
char
*
_Buf
= (
char
*)
_Str
.
c_str
();
while
(
_Status
=
=
_Wrote
) {
// put any trailing homing shift
char
*
_Dest
;
if
(
_Str
.
size
()
<
_STRING_INC
)
_Str
.
assign
(
_STRING_INC
,
'\0'
);
switch
(
_Pcvt
->unshift(
_State
,
_Buf
,
_Buf
+
_Str
.
size
(),
_Dest
)) {
// test result of homing conversion
case
_Codecvt
::ok:
_Status
=
_Unused
;
// homed successfully
case
_Codecvt
::partial:
// fall through
{
// put any generated bytes
int
_Count
= (
int
)(
_Dest
-
_Buf
);
if
(
0
<
_Count
&&
_Byte_traits
::
eq_int_type
(
_Byte_traits
::
eof
(), (
_Byte_traits
::
int_type
)
_Mystrbuf
->
sputn
(
_Buf
,
_Count
)))
return
;
// write failed
if
(
_Status
=
=
_Wrote
&&
_Count
=
=
0
)
_Str
.
append
(
_STRING_INC
,
'\0'
);
// try with more space
break
; }
case
_Codecvt
::noconv:
return
;
// nothing to do
default
:
return
;
// conversion failed
} } } {
// return byte stream buffer pointer
return
(
_Mystrbuf
); }
_Mysb
*
rdbuf
(
_Mysb
*
_Strbuf
) {
// set byte stream buffer pointer
_Mysb
*
_Oldstrbuf
=
_Mystrbuf
;
_Mystrbuf
=
_Strbuf
;
return
(
_Oldstrbuf
); } {
// get state
return
(
_State
); }
wbuffer_convert
(
const
wbuffer_convert
&) =
delete
;
wbuffer_convert
&
operator
=
(
const
wbuffer_convert
&) =
delete
;
protected
:
virtual
int_type
overflow
(
int_type
_Meta
=
_Traits
::eof()) {
// put an element to stream
if
(
_Traits
::eq_int_type(
_Traits
::eof(),
_Meta
))
return
(
_Traits
::not_eof(
_Meta
));
// EOF, return success code
else
if
(
_Mystrbuf
==
nullptr
||
0
<
_Nback
|| (
_Status
!
=
_Unused
&&
_Status
!=
_Wrote
))
return
(
_Traits
::eof());
// no buffer or reading, fail
else
{
// put using codecvt facet
char
*
_Buf
= (
char
*)
_Str
.
c_str
();
const
_Elem
_Ch
=
_Traits
::to_char_type(
_Meta
);
const
_Elem
*
_Src
;
char
*
_Dest
;
if
(
_Str
.
size
()
<
_STRING_INC
)
_Str
.
assign
(
_STRING_INC
,
'\0'
);
for
(
_Status
=
_Wrote
; ; )
switch
(
_Pcvt
->out(
_State
, &
_Ch
, &
_Ch
+
1
,
_Src
,
_Buf
,
_Buf
+
_Str
.
size
(),
_Dest
)) {
// test result of converting one element
case
_Codecvt
::partial:
case
_Codecvt
::ok: {
// converted something, try to put it out
int
_Count
= (
int
)(
_Dest
-
_Buf
);
if
(
0
<
_Count
&&
_Byte_traits
::
eq_int_type
(
_Byte_traits
::
eof
(), (
_Byte_traits
::
int_type
)
_Mystrbuf
->
sputn
(
_Buf
,
_Count
))) {
return
(
_Traits
::eof());
// write failed
}
if
(
_Src
!= &
_Ch
) {
return
(
_Meta
);
// converted whole element
}
if
(
0
>=
_Count
) {
if
(
_Str
.
size
() >=
4
*
_STRING_INC
) {
return
(
_Traits
::eof());
// conversion failed
}
_Str
.
append
(
_STRING_INC
,
'\0'
);
// try with more space
}
break
; }
case
_Codecvt
::noconv:
if
(
_Traits
::eq_int_type(
_Traits
::eof(), (
typename
_Traits
::int_type)
_Mystrbuf
->
sputn
( (
char
*)&
_Ch
, (
streamsize
)
sizeof
(
_Elem
)))) {
return
(
_Traits
::eof()); }
return
(
_Meta
);
// put native byte order
default
:
return
(
_Traits
::eof());
// conversion failed
} } }
virtual
int_type
pbackfail
(
int_type
_Meta
=
_Traits
::eof()) {
// put an element back to stream
if
(
sizeof
(
_Myback
) /
sizeof
(
_Myback
[
0
]) <=
_Nback
||
_Status
==
_Wrote
)
return
(
_Traits
::eof());
// nowhere to put back
else
{
// enough room, put it back
if
(!
_Traits
::eq_int_type(
_Traits
::eof(),
_Meta
))
_Myback
[
_Nback
] =
_Traits
::to_char_type(
_Meta
); ++
_Nback
;
if
(
_Status
=
=
_Unused
)
_Status
=
_Got
;
return
(
_Meta
); } }
virtual
int_type
underflow
() {
// get an element from stream, but don't point past it
int_type
_Meta
;
if
(
0
>=
_Nback
) {
if
(
_Traits
::eq_int_type(
_Traits
::eof(),
_Meta
=
_Get_elem
())) {
return
(
_Meta
);
// _Get_elem failed, return EOF
}
_Myback
[
_Nback
++] =
_Traits
::to_char_type(
_Meta
); }
return
(
_Traits
::to_int_type(
_Myback
[
_Nback
-
1
])); } #pragma warning(push)
// the readable size is 'X' bytes, but 'Y' bytes may be read.
virtual
int_type
uflow
() {
// get an element from stream, point past it
int_type
_Meta
;
if
(
0
>=
_Nback
) {
if
(
_Traits
::eq_int_type(
_Traits
::eof(),
_Meta
=
_Get_elem
())) {
return
(
_Meta
);
// _Get_elem failed, return EOF
}
_Myback
[
_Nback
++] =
_Traits
::to_char_type(
_Meta
); }
return
(
_Traits
::to_int_type(
_Myback
[--
_Nback
])); } #pragma warning(pop)
virtual
pos_type
seekoff
(
off_type
,
ios
::
seekdir
,
ios
::
openmode
= (
ios
::
openmode
)(
ios
::
in
|
ios
::
out
)) {
// change position by _Off
return
(
pos_type
(-
1
));
// always fail
}
virtual
pos_type
seekpos
(
pos_type
,
ios
::
openmode
= (
ios
::
openmode
)(
ios
::
in
|
ios
::
out
)) {
// change position to _Pos
return
(
pos_type
(-
1
));
// always fail
}
private
:
int_type
_Get_elem
() {
// compose an element from byte stream buffer
if
(
_Mystrbuf
!=
nullptr
&&
_Status
!=
_Wrote
) {
// got buffer, haven't written, try to compose an element
if
(
_Status
!
=
_Eof
) {
if
(
_Str
.
empty
()) {
_Status
=
_Need
; }
else
{
_Status
=
_Got
; } }
while
(
_Status
!
=
_Eof
) {
// get using codecvt facet
char
*
_Buf
= (
char
*)
_Str
.
c_str
();
_Elem
_Ch
, *
_Dest
;
const
char
*
_Src
;
int
_Meta
;
if
(
_Status
=
=
_Need
) {
if
(
_Byte_traits
::
eq_int_type
(
_Byte_traits
::
eof
(),
_Meta
=
_Mystrbuf
->
sbumpc
())) {
_Status
=
_Eof
; }
else
{
_Str
.
push_back
(
_Byte_traits
::
to_char_type
(
_Meta
)); } }
switch
(
_Pcvt
->in(
_State
,
_Buf
,
_Buf
+
_Str
.
size
(),
_Src
, &
_Ch
, &
_Ch
+
1
,
_Dest
)) {
// test result of converting one element
case
_Codecvt
::partial:
case
_Codecvt
::ok:
_Str
.
erase
((
size_t
)
0
,
// discard any used input
(
size_t
)(
_Src
-
_Buf
));
if
(
_Dest
!= &
_Ch
)
return
(
_Traits
::to_int_type(
_Ch
));
break
;
case
_Codecvt
::noconv:
if
(
_Str
.
size
()
<
sizeof
(
_Elem
))
break
;
// no conversion, but need more chars
sizeof
(
_Elem
));
// copy raw bytes to element
_Str
.
erase
((
size_t
)
0
,
sizeof
(
_Elem
));
return
(
_Traits
::to_int_type(
_Ch
));
// return result
default
:
_Status
=
_Eof
;
// conversion failed
} } }
return
(
_Traits
::eof()); }
state_type
_State
;
// code conversion state
const
_Codecvt
*
_Pcvt
;
// the codecvt facet
_Mysb
*
_Mystrbuf
;
// pointer to stream buffer
_Mode
_Status
;
// buffer read/write status
size_t
_Nback
;
// number of elements in putback buffer
_Elem
_Myback
[
8
];
// putback buffer
string
_Str
;
// unconsumed input bytes
locale
_Loc
;
// manages reference to codecvt facet
};
// CLASS TEMPLATE wstring_convert
template
<
class
_Codecvt
,
class
_Elem
=
wchar_t
,
class
_Walloc
=
allocator
<
_Elem
>,
class
_Balloc
=
allocator
<
char
> > {
// converts between _Elem (wide) and char (byte) strings
enum
{
_BUF_INC
=
8
,
_BUF_MAX
=
16
};
void
_Init
(
const
_Codecvt
*
_Pcvt_arg
=
new
_Codecvt
) {
// initialize the object
_State
=
state_type
{};
_Pcvt
=
_Pcvt_arg
;
_Loc
=
locale
(
_Loc
,
_Pcvt
);
_Nconv
=
0
; }
public
:
typedef
basic_string
<
char
,
char_traits
<
char
>,
_Balloc
>
byte_string
;
typedef
basic_string
<
_Elem
,
char_traits
<
_Elem
>,
_Walloc
>
wide_string
;
typedef
typename
_Codecvt
::state_type
state_type
;
typedef
typename
wide_string
::
traits_type
::
int_type
int_type
;
wstring_convert
() : _Has_state(
false
), _Has_berr(
false
), _Has_werr(
false
) {
// construct with no error strings
_Init
(); }
explicit
wstring_convert
(
const
_Codecvt
*
_Pcvt_arg
) : _Has_state(
false
), _Has_berr(
false
), _Has_werr(
false
) {
// construct with no error strings and codecvt
_Init
(
_Pcvt_arg
); }
wstring_convert
(
const
_Codecvt
*
_Pcvt_arg
,
state_type
_State_arg
) : _Has_state(
true
), _Has_berr(
false
), _Has_werr(
false
) {
// construct with no error strings, codecvt, and state
_Init
(
_Pcvt_arg
);
_State
=
_State_arg
; }
explicit
wstring_convert
(
const
byte_string
&
_Berr_arg
) : _Berr(
_Berr_arg
), _Has_state(
false
), _Has_berr(
true
), _Has_werr(
false
) {
// construct with byte error string
_Init
(); }
wstring_convert
(
const
byte_string
&
_Berr_arg
,
const
wide_string
&
_Werr_arg
) : _Berr(
_Berr_arg
), _Werr(
_Werr_arg
), _Has_state(
false
), _Has_berr(
true
), _Has_werr(
true
) {
// construct with byte and wide error strings
_Init
(); }
virtual
~
wstring_convert
()
noexcept
{
// destroy the object
} {
// get conversion count
return
(
_Nconv
); } {
// get state
return
(
_State
); } {
// convert a byte to a wide string
return
(
from_bytes
(&
_Byte
, &
_Byte
+
1
)); } {
// convert a NTBS to a wide string
} {
// convert a byte string to a wide string
const
char
*
_Ptr
=
_Bstr
.
c_str
();
return
(
from_bytes
(
_Ptr
,
_Ptr
+
_Bstr
.
size
())); } {
// convert byte sequence [_First, _Last) to a wide string
wide_string
_Wbuf
,
_Wstr
;
const
char
*
_First_sav
=
_First
;
if
(!
_Has_state
)
_State
=
state_type
{};
// reset state if not remembered
for
(
_Nconv
=
0
;
_First
!
=
_Last
;
_Nconv
=
static_cast
<
size_t
>(
_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
,
static_cast
<
size_t
>(
_Dnext
-
_Dest
));
else
if
(
_Wbuf
.
size
()
<
_BUF_MAX
)
_Wbuf
.
append
(
static_cast
<
size_t
>(
_BUF_INC
),
'\0'
);
else
if
(
_Has_werr
)
return
(
_Werr
);
else
break
;
case
_Codecvt
::noconv:
for
(;
_First
!
=
_Last
; ++
_First
)
_Wstr
.
push_back
((
_Elem
)(
unsigned
char
)*
_First
);
break
;
// no conversion, just copy code values
default
:
if
(
_Has_werr
)
return
(
_Werr
);
else
} }
return
(
_Wstr
); } {
// convert a wide char to a byte string
return
(
to_bytes
(&
_Char
, &
_Char
+
1
)); } {
// convert a NTWCS to a byte string
const
_Elem
*
_Next
=
_Wptr
;
while
((
int_type
)*
_Next
!
=
0
) { ++
_Next
; }
return
(
to_bytes
(
_Wptr
,
_Next
)); } {
// convert a wide string to a byte string
const
_Elem
*
_Wptr
=
_Wstr
.
c_str
();
return
(
to_bytes
(
_Wptr
,
_Wptr
+
_Wstr
.
size
())); } {
// convert wide sequence [_First, _Last) to a byte string
byte_string
_Bbuf
,
_Bstr
;
const
_Elem
*
_First_sav
=
_First
;
if
(!
_Has_state
)
_State
=
state_type
{};
// reset state if not remembered
for
(
_Nconv
=
0
;
_First
!
=
_Last
;
_Nconv
=
static_cast
<
size_t
>(
_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
)
else
if
(
_Bbuf
.
size
()
<
_BUF_MAX
)
else
if
(
_Has_berr
)
return
(
_Berr
);
else
break
;
case
_Codecvt
::noconv:
for
(;
_First
!
=
_Last
; ++
_First
)
_Bstr
.
push_back
((
char
)(
int_type
)*
_First
);
break
;
// no conversion, just copy code values
default
:
if
(
_Has_berr
)
return
(
_Berr
);
else
} }
return
(
_Bstr
); }
wstring_convert
(
const
wstring_convert
&) =
delete
;
wstring_convert
&
operator
=
(
const
wstring_convert
&) =
delete
;
private
:
const
_Codecvt
*
_Pcvt
;
// the codecvt facet
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
; }; #pragma warning(pop)
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
/* * Copyright (c) by P.J. Plauger. All rights reserved. * Consult your license regarding permissions and restrictions. V6.50:0009 */