// 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); }
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 }
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); } }