| // WPString.cpp: implementation of the WPString class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WPString.h"
wstring WPString::_AStringToWide(LPCSTR lpszSrc)
{
return _Internal_MBStringToWide(lpszSrc,CP_ACP);
}
wstring WPString::_UTFStringToWide(LPCSTR lpszUTF8)
{
return _Internal_MBStringToWide(lpszUTF8,CP_UTF8);
}
wstring WPString::_Internal_MBStringToWide(LPCSTR lpszSrc, const UINT nSrcCodePage)
{
wstring wstrRet=L"";
if (NULL == lpszSrc)
return wstrRet;
const int nALen=(int)strlen(lpszSrc);
if (0 == nALen)
return wstrRet;
const int nNeeded=MultiByteToWideChar(nSrcCodePage,0,lpszSrc,nALen,NULL,0);
if (0 == nNeeded)
return wstrRet;
enum {STACK_SIZE_MAX=2000};
const BOOL bDelete=nNeeded > (STACK_SIZE_MAX-1);
wchar_t szBuffer[STACK_SIZE_MAX];
wchar_t* const pBuffer=bDelete ? new wchar_t[nNeeded+1] : szBuffer;
if (NULL == pBuffer)
return wstrRet;
const int nEncode=MultiByteToWideChar(nSrcCodePage,0,lpszSrc,nALen,pBuffer,nNeeded);
if (0 == nEncode) {
if (bDelete)
delete[] pBuffer;
return wstrRet;
}
*(pBuffer+nEncode)=L'\0';
wstrRet.reserve(nEncode);
wstrRet=wstring(pBuffer);
if (bDelete)
delete[] pBuffer;
return wstrRet;
}
wstring WPString::_AStringToWide_ByANSICodePageThread(LPCSTR lpszSrc)
{
return _Internal_MBStringToWide(lpszSrc, CP_THREAD_ACP);
}
astring WPString::_WideStringToACP(LPCWSTR lpszW)
{
return _Internal_WideStringToMBCS(lpszW,CP_THREAD_ACP);
}
astring WPString::_WideStringToCodePage(LPCWSTR lpszW, const DWORD code_page)
{
return _Internal_WideStringToMBCS(lpszW,code_page);
}
astring WPString::_WideStringToUTF(LPCWSTR lpszWide)
{
return _Internal_WideStringToMBCS(lpszWide,CP_UTF8);
}
astring WPString::_Internal_WideStringToMBCS(LPCWSTR lpszWide, const UINT nMBCodePage)
{
astring astrRet="";
if (NULL == lpszWide)
return astrRet;
const int nWLen=(int)wcslen(lpszWide);
if (0==nWLen)
return astrRet;
const int nNeedChar=WideCharToMultiByte(nMBCodePage,0,lpszWide,nWLen,NULL,0,NULL,NULL);
if (0 == nNeedChar)
return astrRet;
enum {STACK_SIZE_MAX=2000};
const BOOL bDelete=nNeedChar > (STACK_SIZE_MAX-1);
char szBuffer[STACK_SIZE_MAX];
char* const pBuffer=bDelete ? new char[nNeedChar+1] : szBuffer;
if (NULL == pBuffer)
return astrRet;
const int nEncode=WideCharToMultiByte(nMBCodePage,0,lpszWide,nWLen,pBuffer,nNeedChar,NULL,NULL);
if (0 == nEncode) {
if (bDelete)
delete[] pBuffer;
return astrRet;
}
*(pBuffer+nEncode)='\0';
astrRet.reserve(nEncode);
astrRet=astring(pBuffer);
if (bDelete)
delete[] pBuffer;
return astrRet;
}
astring WPString::_UTFStringToANSI(LPCSTR lpszUTF8)
{
const wstring ws=_UTFStringToWide(lpszUTF8);
if (ws.empty())
return "";
const astring as=_WideStringToACP(ws.c_str());
return as;
}
wstring WPString::_MBStringToWideWithCodePage(LPCSTR lpszSRC, const DWORD dwCodePage)
{
return _Internal_MBStringToWide(lpszSRC,dwCodePage);
}
astring WPString::_AStringToUTF8(LPCSTR lpszSrc)
{
const wstring wsU=_AStringToWide(lpszSrc);
if (wsU.empty())
return "";
const astring a=_WideStringToUTF(wsU.c_str());
return a;
}
static
wchar_t ToUpperInvariant(wchar_t input)
{
wchar_t result;
LONG lres = LCMapStringW(
LOCALE_INVARIANT,
LCMAP_UPPERCASE,
&input,
1,
&result,
1
);
if (lres == 0)
{
ASSERT(!"LCMapStringW failed to convert a character to upper case");
result = input;
}
return result;
}
int WPString::CompareWP(LPCTSTR sz1, LPCTSTR sz2, const BOOL bCaseSensitive)
{
if (sz1 == sz2)
{
return 0;
}
if (sz1 == NULL) sz1 = TEXT("");
if (sz2 == NULL) sz2 = TEXT("");
for (;; sz1++, sz2++)
{
const wchar_t c1 = *sz1;
const wchar_t c2 = *sz2;
// check for binary equality first
if (c1 == c2)
{
if (c1 == 0)
{
return 0; // We have reached the end of both strings. No difference found.
}
}
else
{
if (c1 == 0 || c2 == 0)
{
return (c1-c2); // We have reached the end of one string
}
// IMPORTANT: this needs to be upper case to match the behavior of the operating system.
// See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/StringsinNET20.asp
const wchar_t u1 = bCaseSensitive ? c1 : ToUpperInvariant(c1);
const wchar_t u2 = bCaseSensitive ? c2 : ToUpperInvariant(c2);
if (u1 != u2)
{
return (u1-u2); // strings are different
}
}
}
}
static
wstring MFCStringToWPString(LPCWSTR lpsz, const BOOL bCaseSensitive)
{
const int nLen=wcslen(lpsz);
ASSERT(nLen);
if (0 == nLen)
return L"";
wchar_t* p=new wchar_t[nLen+1];
ASSERT(p);
memset(p,0,(nLen+1)*sizeof(wchar_t));
const DWORD dwFlags=bCaseSensitive ? 0 : LCMAP_UPPERCASE;
const LONG lres = LCMapStringW(
LOCALE_INVARIANT,
dwFlags,
lpsz,
nLen,
p,
nLen
);
ASSERT(lres > 0);
if (lres <= 0) {
delete[] p;
return L"";
}
ASSERT(!IsBadStringPtrW(p,INFINITE));
const wstring ws(p);
delete[] p;
return ws;
}
int WPString::FindInStrWP2(const LPCTSTR lpszFindString
, LPCTSTR lpszText
, const BOOL bCaseSensitive
,const int nStart)
{
ASSERT(lpszFindString);
ASSERT(!IsBadStringPtr(lpszFindString,INFINITE));
ASSERT(_tcslen(lpszFindString));
ASSERT(lpszText);
ASSERT(!IsBadStringPtr(lpszText,INFINITE));
ASSERT(_tcslen(lpszText));
if (0 == _tcslen(lpszText))
return -1;
if (0 == _tcslen(lpszFindString))
return -1;
const wstring wsFindString=MFCStringToWPString(lpszFindString,bCaseSensitive);
const wstring wsText=MFCStringToWPString(lpszText,bCaseSensitive);
const CString strFind(wsFindString.c_str());
const CString strText(wsText.c_str());
const int nFind=strText.Find(strFind,nStart);
return nFind;
//const int szT=wsText.find(wsFindString.c_str(),nStart);
//return szT;
}
wstring WPString::_OemStringToWide(LPCSTR lpszSrc)
{
const int nLen=strlen(lpszSrc);
ASSERT(nLen);
if (0 == nLen)
return L"";
wchar_t* const pChar=new wchar_t[nLen*2];
ASSERT(pChar);
if (NULL == pChar)
return L"";
memset(pChar,0,(nLen*sizeof(wchar_t)*2));
const BOOL b=OemToCharW(lpszSrc,pChar);
ASSERT(b);
if (!b) {
delete[] pChar;
}
const wstring ws(pChar);
delete[] pChar;
return ws;
}
|