// Helper function for _ungetwc_nolock() that handles text mode ungetting.
static wint_t __cdecl ungetwc_text_mode_nolock(wint_t const c, __crt_stdio_stream const stream) throw()
{
    // The stream is open in text mode, and we need to do the unget differently
    // depending on whether the stream is open in ANSI or Unicode mode.
    __crt_lowio_text_mode const text_mode = _textmode_safe(_fileno(stream.public_stream()));

    int  count = 0;
    char characters[MB_LEN_MAX] = { 0 };

    // If the file is open in ANSI mode, we need to convert the wide character
    // to multibyte so that we can unget the multibyte character back into the
    // stream:
    if (text_mode == __crt_lowio_text_mode::ansi)
    {
        // If conversion fails, errno is set by wctomb_s and we can just return:
        if (wctomb_s(&count, characters, MB_LEN_MAX, c) != 0)
            return WEOF;
    }
    // Otherwise, the file is open in Unicode mode.  This means the characters
    // in the stream were originally Unicode (and not multibyte).  Hence, we
    // do not need to translate back to multibyte.  This is true for both UTF-16
    // and UTF-8, because the lowio read converts UTF-8 data to UTF-16.
    else
    {
        char const* c_bytes = reinterpret_cast<char const*>(&c);
        characters[0] = c_bytes[0];
        characters[1] = c_bytes[1];
        count = 2;
    }

    // At this point, the file must be buffered, so we know the base is non-null.
    // First we need to ensure there is sufficient room in the buffer to store
    // the translated data:
    if (stream->_ptr < stream->_base + count)
    {
        if (stream->_cnt)
            return WEOF;

        if (count > stream->_bufsiz)
            return WEOF;

        stream->_ptr = count + stream->_base;
    }

    for (int i = count - 1; i >= 0; --i)
    {
        *--stream->_ptr = characters[i];
    }

    stream->_cnt += count;

    stream.unset_flags(_IOEOF);
    stream.set_flags(_IOREAD);
    return static_cast<wint_t>(0xffff & c);
}
Beispiel #2
0
void TestFromWide( void )
{
    char                mbs[20];
    wchar_t             wc = L'\0';
    wchar_t             wcs[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

    errno_t             rc;
    size_t              retval;
    size_t              retval2;
    int                 status;
    int                 violations = NumViolations;

    rc = wctomb_s( &status, mbs, 20, wc );
    VERIFY( rc == 0 );
    VERIFY( mbs[0] == '\0' );
    VERIFY( status == 1 );
    VERIFY( violations == NumViolations );

    rc = wctomb_s( &status, mbs, 20, L'X' );
    VERIFY( rc == 0 );
    VERIFY( mbs[0] == 'X' );
    VERIFY( status == 1 );
    VERIFY( violations == NumViolations );

    rc = wctomb_s( &status, NULL, 0, L'X' );
    VERIFY( rc == 0 );
    VERIFY( status == 0 );  /* no state-dependant encodings */
    VERIFY( violations == NumViolations );


    rc = wcstombs_s( &retval, mbs, 20, wcs, 10 );
    VERIFY( rc == 0 );
    VERIFY( retval == 5 );
    VERIFY( !_mbscmp(mbs,"Hello") );
    VERIFY( violations == NumViolations );

    rc = wcstombs_s( &retval2, NULL, 0, wcs, 10 );
    VERIFY( rc == 0 );
    VERIFY( retval2 == 5 );
    VERIFY( violations == NumViolations );


    /***********************************************************************/
    /*  test runtime-constraints                                           */
    /***********************************************************************/
    rc = wctomb_s( &status, NULL, 20, wc );
    VERIFY( rc != 0 );
    VERIFY( ++violations == NumViolations );

    rc = wctomb_s( &status, mbs, 0, wc );
    VERIFY( rc != 0 );
    VERIFY( ++violations == NumViolations );

#if RSIZE_MAX != SIZE_MAX
    rc = wctomb_s( &status, mbs, ~0, wc );
    VERIFY( rc != 0 );
    VERIFY( ++violations == NumViolations );
#endif

    rc = wctomb_s( &status, mbs, 1, '\x81\xFC' );
    VERIFY( rc != 0 );
    VERIFY( ++violations == NumViolations );


    mbs[0]= 'X';
    rc = wcstombs_s( NULL, mbs, 20, wcs, 10 );
    VERIFY( rc != 0 );
    VERIFY( mbs[0] == '\0' );
    VERIFY( ++violations == NumViolations );

    mbs[0]= 'X';
    rc = wcstombs_s( &retval, mbs, 20, NULL, 10 );
    VERIFY( rc != 0 );
    VERIFY( retval == -1 );
    VERIFY( mbs[0] == '\0' );
    VERIFY( ++violations == NumViolations );

#if RSIZE_MAX != SIZE_MAX
    mbs[0]= 'X';
    rc = wcstombs_s( &retval, mbs, ~0, wcs, 10 );
    VERIFY( rc != 0 );
    VERIFY( retval == -1 );
    VERIFY( mbs[0] == 'X' );
    VERIFY( ++violations == NumViolations );

    mbs[0]= 'X';
    rc = wcstombs_s( &retval, mbs, 20, wcs, ~0 );
    VERIFY( rc != 0 );
    VERIFY( retval == -1 );
    VERIFY( mbs[0] == '\0' );
    VERIFY( ++violations == NumViolations );
#endif



}
Beispiel #3
0
void CSoftUninstall::GetPinYin(const std::wstring &name, std::wstring &whole, std::wstring &acronym)
{
	typedef list<string>					str_list;
	typedef str_list::iterator				str_iter;
	typedef string_tokeniser<string, char>	string_tokeniser_a;

	typedef void (string::*PFPushback)(char);
	typedef string& (string::*PFAppend)(const char*);

	PFAppend pfAppend = &string::append;
	PFPushback pfPushback = &string::push_back;

	char mbcs[5];
	str_list wholeList, acronymList;
	wholeList.push_back(string());
	acronymList.push_back(string());

	for(wstring::size_type i = 0; i < name.size(); ++i)
	{
		if(iswascii(name[i]) == 0)
		{	// 非ASCII码
			int ret;
			if(wctomb_s(&ret, mbcs, sizeof(mbcs), name[i]) != 0) continue;
			mbcs[ret] = '\0';

			PinYinCIter itPinYin = _hashPinYin.find(mbcs);
			if(itPinYin != _hashPinYin.end())
			{
				const PinYin &pinyin = itPinYin->second;

				// M X N组合
				{
					string_tokeniser_a tokeniser(pinyin._whole, ' ');

					str_list resultList;
					string_tokeniser_a::const_iterator end = tokeniser.end();
					for(string_tokeniser_a::const_iterator it = tokeniser.begin(); it != end; ++it)
					{
						str_iter endList = wholeList.end();
						for(str_iter itList = wholeList.begin(); itList != endList; ++itList)
							resultList.push_back(*itList + *it);
					}
					wholeList.swap(resultList);
				}
				{
					string_tokeniser_a tokeniser(pinyin._acronym, ' ');

					str_list resultList;
					string_tokeniser_a::const_iterator end = tokeniser.end();
					for(string_tokeniser_a::const_iterator it = tokeniser.begin(); it != end; ++it)
					{
						str_iter endList = acronymList.end();
						for(str_iter itList = acronymList.begin(); itList != endList; ++itList)
							resultList.push_back(*itList + *it);
					}
					acronymList.swap(resultList);
				}
			}
			else
			{
				for_each(wholeList.begin(), wholeList.end(), bind2nd(mem_fun1_ref(pfAppend), mbcs));
				for_each(acronymList.begin(), acronymList.end(), bind2nd(mem_fun1_ref(pfAppend), mbcs));
			}
		}
		else
		{
			// ASCII码直接组合
			for_each(wholeList.begin(), wholeList.end(), bind2nd(mem_fun1_ref(pfPushback), (char)towlower(name[i])));
			for_each(acronymList.begin(), acronymList.end(), bind2nd(mem_fun1_ref(pfPushback), (char)tolower(name[i])));
		}
	}

	// 合并结果
	{
		ostringstream os;
		copy(wholeList.begin(), wholeList.end(), ostream_iterator<string>(os, " "));

		whole = CA2W(os.str().c_str());
		trim_right(whole);
	}

	{
		ostringstream os;
		copy(acronymList.begin(), acronymList.end(), ostream_iterator<string>(os, " "));

		acronym = CA2W(os.str().c_str());
		trim_right(acronym);
	}
}