📄 common.cpp
字号:
//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1998 By Microsoft Corporation.
//
// @doc
//
// @module COMMON.CPP
//
//-----------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// Include
//
/////////////////////////////////////////////////////////////////////////////
#include "common.h"
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToMBCS
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertToMBCS(WCHAR* pwsz, CHAR* psz, ULONG cStrLen)
{
ASSERT(psz);
//No-op
if(pwsz==NULL)
{
psz[0] = EOL;
return S_FALSE;
}
//Convert the string to MBCS
INT iResult = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, cStrLen, NULL, NULL);
//Add NULL Terminator
psz[min((ULONG)iResult, cStrLen-1)] = EOL;
return iResult ? S_OK : E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToMBCS
// Dynamically allocated memory
/////////////////////////////////////////////////////////////////////////////
CHAR* ConvertToMBCS(WCHAR* pwsz)
{
//no-op case
if(!pwsz)
return NULL;
//Determine the space required for the conversion
LONG iLen = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);
//Allocate space for the string
CHAR* pszBuffer = NULL;
SAFE_ALLOC(pszBuffer, CHAR, iLen+1);
//Now convert the string
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, pszBuffer, iLen+1, NULL, NULL);
CLEANUP:
return pszBuffer;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToWCHAR
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertToWCHAR(CHAR* psz, WCHAR* pwsz, ULONG cStrLen)
{
ASSERT(pwsz);
//No-op
if(psz==NULL)
{
pwsz[0] = wEOL;
return S_FALSE;
}
//Convert the string to MBCS
INT iResult = MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cStrLen);
//Add NULL Terminator
pwsz[min((ULONG)iResult, cStrLen-1)] = wEOL;
return iResult ? S_OK : E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToWCHAR
// Dynamically allocated memory
/////////////////////////////////////////////////////////////////////////////
WCHAR* ConvertToWCHAR(CHAR* psz)
{
//no-op case
if(!psz)
return NULL;
//Determine the space required for the conversion
LONG iLen = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
//Allocate space for the string
WCHAR* pwszBuffer = NULL;
SAFE_ALLOC(pwszBuffer, WCHAR, iLen+1);
//Now convert the string
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwszBuffer, iLen+1);
CLEANUP:
return pwszBuffer;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT GUIDFromString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GUIDFromString(CHAR* psz, GUID* pGuid)
{
if(psz == NULL || pGuid == NULL)
return E_FAIL;
WCHAR* pwsz = ConvertToWCHAR(psz);
HRESULT hr = CLSIDFromString(pwsz, pGuid);
SAFE_FREE(pwsz);
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertString(CHAR* psz, ULONG ulMaxSize, DWORD dwFlags)
{
ASSERT(psz);
ASSERT(ulMaxSize);
CHAR* pszStop = NULL;
//Currently only deals with HEX or DECIMAL
ASSERT(dwFlags & CONV_HEX || dwFlags & CONV_DECIMAL);
//Convert String to integer
LONG lValue = strtol(psz, &pszStop, 10);
if(lValue == LONG_MAX || lValue == 0 || pszStop==NULL || pszStop[0]!=EOL)
return E_FAIL;
//Convert Integer back to requested Format
if(dwFlags & CONV_HEX)
sprintf(psz, "0x%x", lValue);
else
sprintf(psz, "%d", lValue);
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT BYTESToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT BYTESToString(BYTE* pb, CHAR* pszBuffer, ULONG cBytes, ULONG* pulStrLen)
{
ASSERT(pb && pszBuffer);
// Process the byte stream, converting each byte into
// its two character unicode hexaDECIMAL representation
static CHAR s_chHex[] =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for(ULONG i=0; i<cBytes; i++)
{
*pszBuffer++ = s_chHex[*pb >> 4];
*pszBuffer++ = s_chHex[*pb & 0x0F];
pb++;
}
*pszBuffer = EOL;
if(pulStrLen)
*pulStrLen = cBytes << 1;
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT StringToBYTES
//
/////////////////////////////////////////////////////////////////////////////
HRESULT StringToBYTES(CHAR* pszBuffer, BYTE* pb, ULONG cBytes, ULONG* pcbBytes)
{
ASSERT(pszBuffer && pb);
// Process the byte stream, converting each byte into
// its two character unicode hexaDECIMAL representation
static CHAR s_chByte[] =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '?', '?', '?', '?', '?', '?', '?', 'A', 'B', 'C', 'D', 'E', 'F'};
for(ULONG i=0; i<cBytes; i++)
{
// Process first character of pair
CHAR ch = *pszBuffer++;
if( ch >= '0' && ch <= '9' )
ch -= '0';
else if( ch >= 'A' && ch <= 'F' )
ch -= 'A' - 10;
else if( ch >= 'a' && ch <= 'f' )
ch -= 'a' - 10;
else
return DB_E_CANTCONVERTVALUE;
*pb = (BYTE)ch << 4;
// Advance to second character of pair
ch = *pszBuffer++;
if( ch >= '0' && ch <= '9' )
ch -= '0';
else if( ch >= 'A' && ch <= 'F' )
ch -= 'A' - 10;
else if( ch >= 'a' && ch <= 'f' )
ch -= 'a' - 10;
else
return DB_E_CANTCONVERTVALUE;
*pb |= (BYTE)ch;
// Done two characters -- created one byte
pb++;
}
if(pcbBytes)
*pcbBytes = cBytes;
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT VariantToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT VariantToString(VARIANT* pVariant, CHAR* psz, ULONG ulMaxSize, DWORD dwFlags)
{
//Convert a VARIANT to a WCHAR
ASSERT(pVariant);
ASSERT(psz);
ASSERT(ulMaxSize > 0);
HRESULT hr = S_OK;
//Find the VariantType
DBTYPE wType = V_VT(pVariant);
VARIANT VarTemp;
VariantInit(&VarTemp);
static LCID lcid = GetSystemDefaultLCID();
//VT_ARRAY is not handled by VariantChangeTypeEx
if(wType & VT_ARRAY)
{
TESTC(hr = SafeArrayToString(V_ARRAY(pVariant), wType, psz, ulMaxSize));
goto CLEANUP;
}
switch(wType)
{
case VT_NULL:
case VT_EMPTY:
psz[0] = EOL;
break;
case VT_BOOL:
if(V_BOOL(pVariant) == VARIANT_TRUE)
sprintf(psz, "%s", dwFlags & CONV_VARBOOL ? "VARIANT_TRUE" : "True");
else if(V_BOOL(pVariant) == VARIANT_FALSE)
sprintf(psz, "%s", dwFlags & CONV_VARBOOL ? "VARIANT_FALSE" : "False");
else
sprintf(psz, "%d", V_BOOL(pVariant));
break;
case VT_ERROR:
sprintf(psz, "%d", V_ERROR(pVariant));
break;
default:
{
//Delgate
TESTC(hr = VariantChangeTypeEx(
&VarTemp, // Destination (convert not in place)
pVariant, // Source
lcid, // LCID
0, // dwFlags
VT_BSTR ));
//Convert to MBCS
ConvertToMBCS(V_BSTR(&VarTemp), psz, ulMaxSize);
}
};
CLEANUP:
psz[ulMaxSize-1] = EOL;
XTEST(NULL, VariantClear(&VarTemp));
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT VariantToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT VariantToString(VARIANT* pVariant, WCHAR* pwsz, ULONG ulMaxSize, DWORD dwFlags)
{
//Convert a VARIANT to a WCHAR
ASSERT(pVariant);
ASSERT(pwsz);
ASSERT(ulMaxSize > 0);
HRESULT hr = S_OK;
//Find the VariantType
DBTYPE wType = V_VT(pVariant);
VARIANT VarTemp;
VariantInit(&VarTemp);
static LCID lcid = GetSystemDefaultLCID();
//VT_ARRAY is not handled by VariantChangeTypeEx
if(wType & VT_ARRAY)
{
CHAR szBuffer[MAX_COL_SIZE];
ASSERT(ulMaxSize >= MAX_COL_SIZE);
TESTC(hr = SafeArrayToString(V_ARRAY(pVariant), wType, szBuffer, MAX_COL_SIZE));
ConvertToWCHAR(szBuffer, pwsz, MAX_COL_SIZE);
goto CLEANUP;
}
switch(wType)
{
case VT_NULL:
case VT_EMPTY:
pwsz[0] = EOL;
break;
case VT_BOOL:
if(V_BOOL(pVariant) == VARIANT_TRUE)
swprintf(pwsz, L"%s", dwFlags & CONV_VARBOOL ? L"VARIANT_TRUE" : L"True");
else if(V_BOOL(pVariant) == VARIANT_FALSE)
swprintf(pwsz, L"%s", dwFlags & CONV_VARBOOL ? L"VARIANT_FALSE" : L"False");
else
swprintf(pwsz, L"%d", V_BOOL(pVariant));
break;
case VT_ERROR:
swprintf(pwsz, L"%d", V_ERROR(pVariant));
break;
default:
{
TESTC(hr = VariantChangeTypeEx(
&VarTemp, // Destination (convert not in place)
pVariant, // Source
lcid, // LCID
0, // dwFlags
VT_BSTR ));
//Convert to MBCS
wcsncpy(pwsz, V_BSTR(&VarTemp), ulMaxSize);
//May need Hex postprocessing
if(dwFlags & CONV_HEX)
{
switch(V_VT(pVariant))
{
case DBTYPE_I4:
swprintf(pwsz, L"0x%x", V_I4(pVariant));
break;
}
}
}
};
CLEANUP:
pwsz[ulMaxSize-1] = wEOL;
XTEST(NULL, VariantClear(&VarTemp));
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT StringToVariant
//
/////////////////////////////////////////////////////////////////////////////
HRESULT StringToVariant(WCHAR* pwsz, VARTYPE vt, VARIANT* pVariant, DWORD dwFlags)
{
//Convert a VARIANT to a WCHAR
ASSERT(pwsz);
ASSERT(pVariant);
HRESULT hr = S_OK;
//Assign the type...
V_VT(pVariant) = vt;
static LCID lcid = GetSystemDefaultLCID();
//VariantChangeTypeEx seems to handle most types,
//except the following cases...
switch(vt)
{
case VT_NULL:
case VT_EMPTY:
break;
case VT_BOOL:
{
if(dwFlags & CONV_VARBOOL && _wcsicmp(pwsz, L"VARIANT_TRUE")==0)
V_BOOL(pVariant) = VARIANT_TRUE;
else if(dwFlags & CONV_VARBOOL && _wcsicmp(pwsz, L"VARIANT_FALSE")==0)
V_BOOL(pVariant) = VARIANT_FALSE;
else if(dwFlags & CONV_ALPHABOOL && _wcsicmp(pwsz, L"True")==0)
V_BOOL(pVariant) = VARIANT_TRUE;
else if(dwFlags & CONV_ALPHABOOL && _wcsicmp(pwsz, L"False")==0)
V_BOOL(pVariant) = VARIANT_FALSE;
else
{
LONG lValue = wcstol(pwsz, NULL, 0);
if(lValue == LONG_MAX || lValue>SHRT_MAX || lValue<SHRT_MIN)
{
hr = E_FAIL;
goto CLEANUP;
}
V_BOOL(pVariant) = (VARIANT_BOOL)lValue;
}
break;
}
case VT_I4:
case VT_UI4:
case VT_ERROR:
{
//We handle this case seperatly since we want to handle HEX values
WCHAR* pwszStop = NULL;
LONG ulValue = wcstol(pwsz, &pwszStop, 0);
if(pwszStop==NULL || pwszStop[0]!=wEOL)
{
hr = E_FAIL;
goto CLEANUP;
}
V_I4(pVariant) = ulValue;
break;
}
default:
{
//Place the string into the BSTR of the VARIANT
V_VT(pVariant) = VT_BSTR;
V_BSTR(pVariant) = SysAllocString(pwsz);
//Now delegate to VariantChangeType...
TESTC(hr = VariantChangeTypeEx(
pVariant, // Destination (convert in place)
pVariant, // Source
lcid, // LCID
0, // dwFlags
vt ));
}
};
CLEANUP:
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT SafeArrayToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT SafeArrayToString(SAFEARRAY* pSafeArray, DBTYPE wType, CHAR* pszBuffer, ULONG ulMaxSize)
{
ASSERT(pSafeArray);
//This method is capable of handling N-Dimenstions of Data!!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -