📄 datatype.cpp
字号:
ce::wstring* pSBuffer;
TRY
{
pReturn->reserve(25);
pReturn->resize(0);
pSBuffer = pReturn;
memset(&udate, 0, sizeof(udate));
hr = VarUdateFromDate(*pdate, 0, &udate);
if (FAILED(hr))
goto Cleanup;
// parse date if allowed
if (dt < DT_TIME_ISO8601)
{
if ((hr = UnparseDecimal(pSBuffer, udate.st.wYear, 4)) != S_OK)
goto Cleanup;
pSBuffer->append(_T('-'));
if ((hr = UnparseDecimal(pSBuffer, udate.st.wMonth, 2)) != S_OK)
goto Cleanup;
pSBuffer->append(_T('-'));
if ((hr = UnparseDecimal(pSBuffer, udate.st.wDay, 2)) != S_OK)
goto Cleanup;
if (dt >= DT_DATETIME_ISO8601)
{
// starts with T
pSBuffer->append(_T('T'));
}
}
// parse time if allowed
if (dt >= DT_DATETIME_ISO8601)
{
if ((hr = UnparseDecimal(pSBuffer, udate.st.wHour, 2)) != S_OK)
goto Cleanup;
pSBuffer->append(_T(':'));
if ((hr = UnparseDecimal(pSBuffer, udate.st.wMinute, 2)) != S_OK)
goto Cleanup;
pSBuffer->append(_T(':'));
if ((hr = UnparseDecimal(pSBuffer, udate.st.wSecond, 2)) != S_OK)
goto Cleanup;
pSBuffer->append(_T('.'));
if ((hr = UnparseDecimal(pSBuffer, udate.st.wMilliseconds, 3)) != S_OK)
goto Cleanup;
}
//if (dt == DT_DATETIME_ISO8601TZ || dt == DT_TIME_ISO8601TZ)
// no time zone...
}
CATCH
{
hr = ERESULT_NOINFO;
}
ENDTRY
Cleanup:
return hr;
//Error:
hr = E_FAIL;
goto Cleanup;
}
HRESULT
UnparseBinHex( ce::wstring * pReturn, BYTE * abData, long lLen)
{
WCHAR * pText;
WCHAR * pwc;
BYTE * pb = abData;
BYTE nibble;
long lStrLen = lLen * 2;
HRESULT hr = S_OK;
pText = new WCHAR[lStrLen];
if ( !pText)
{
return E_OUTOFMEMORY;
}
pwc = pText;
while ( lLen--)
{
// high nibble
nibble = ((0xf0) & *pb) >> 4;
if ( nibble > 9)
*pwc++ = L'a' + nibble - 10;
else
*pwc++ = L'0' + nibble;
// low nibble
nibble = (0x0f) & *pb;
if ( nibble > 9)
*pwc++ = L'a' + nibble - 10;
else
*pwc++ = L'0' + nibble;
// next byte...
pb++;
}
TRY
{
pReturn->assign(pText, lStrLen);
}
CATCH
{
hr = ERESULT_NOINFO;
}
ENDTRY
//Cleanup:
delete [] pText;
return hr;
}
//==============================================================================
// Base64 code from MTS code sample (SimpleLog)
// These characters are the legal digits, in order, that are
// used in Base64 encoding
//
static
const WCHAR rgwchBase64[] =
L"ABCDEFGHIJKLMNOPQ"
L"RSTUVWXYZabcdefgh"
L"ijklmnopqrstuvwxy"
L"z0123456789+/";
HRESULT
UnparseBase64(void * pvData, int cbData, ce::wstring * pReturn)
{
int cb = cbData;
HRESULT hr = S_OK;
int cchPerLine = 72; // conservative, must be mult of 4 for us
int cbPerLine = cchPerLine / 4 * 3;
int cbSafe = cb + 3; // allow for padding
int cLine = cbSafe / cbPerLine + 2; // conservative
int cchNeeded = cLine * (cchPerLine + 2 /*CRLF*/) + 1 /*NULL*/;
int cbNeeded = cchNeeded * sizeof(WCHAR);
WCHAR * wsz = new WCHAR[cbNeeded];
BYTE* pb = (BYTE*)pvData;
WCHAR* pch = wsz;
int cchLine = 0;
if (!wsz)
{
hr = E_OUTOFMEMORY;
}
else
{
//
// Main encoding loop
//
while (cb >= 3)
{
BYTE b0 = ((pb[0]>>2) & 0x3F);
BYTE b1 = ((pb[0]&0x03)<<4) | ((pb[1]>>4) & 0x0F);
BYTE b2 = ((pb[1]&0x0F)<<2) | ((pb[2]>>6) & 0x03);
BYTE b3 = ((pb[2]&0x3F));
*pch++ = rgwchBase64[b0];
*pch++ = rgwchBase64[b1];
*pch++ = rgwchBase64[b2];
*pch++ = rgwchBase64[b3];
pb += 3;
cb -= 3;
// put in line breaks
cchLine += 4;
if (cchLine >= cchPerLine)
{
*pch++ = L'\r';
*pch++ = L'\n';
cchLine = 0;
}
}
//
// Account for gunk at the end
//
if ((cchLine+4) >= cchPerLine)
{
*pch++ = L'\r'; // easier than keeping track
*pch++ = L'\n';
}
if (cb==0)
{
// nothing to do
}
else if (cb==1)
{
BYTE b0 = ((pb[0]>>2) & 0x3F);
BYTE b1 = ((pb[0]&0x03)<<4) | 0;
*pch++ = rgwchBase64[b0];
*pch++ = rgwchBase64[b1];
*pch++ = L'=';
*pch++ = L'=';
}
else if (cb==2)
{
BYTE b0 = ((pb[0]>>2) & 0x3F);
BYTE b1 = ((pb[0]&0x03)<<4) | ((pb[1]>>4) & 0x0F);
BYTE b2 = ((pb[1]&0x0F)<<2) | 0;
*pch++ = rgwchBase64[b0];
*pch++ = rgwchBase64[b1];
*pch++ = rgwchBase64[b2];
*pch++ = L'=';
}
//
// NULL terminate the string
//
*pch = NULL;
//
// Allocate our final output
//
*pReturn = (wsz);
#ifdef _DEBUG
if (hr==S_OK)
{
int cb; void * pv = new BYTE[cbData+1];
if(pv)
{
assert(S_OK == ParseBase64(wsz, (LONG)(pch - wsz), pv, &cb, null));
assert(cb == cbData);
assert(memcmp(pv, pvData, cbData) == 0);
delete [] (BYTE *)pv;
}
}
#endif
delete [] wsz;
}
//Cleanup:
return hr;
}
HRESULT
ParseBase64(const WCHAR * pwc, int cch,
void * pvData, int * pcbData,
const WCHAR ** ppwcNext)
{
HRESULT hr = S_OK;
BYTE* rgb = (BYTE *)pvData;
BYTE mpwchb[256];
BYTE bBad = (BYTE)-1;
BYTE i;
if ( !rgb)
{
hr = E_OUTOFMEMORY;
}
else
{
//
// Initialize our decoding array
//
memset(&mpwchb[0], bBad, 256);
for (i = 0; i < 64; i++)
{
WCHAR wch = rgwchBase64[i];
mpwchb[wch] = i;
}
//
// Loop over the entire input buffer
//
ULONG bCurrent = 0; // what we're in the process of filling up
int cbitFilled = 0; // how many bits in it we've filled
BYTE* pb = rgb; // current destination (not filled)
const WCHAR* pwch;
WCHAR wch;
//
for (pwch=pwc; (wch = *pwch) && cch--; pwch++)
{
//
// Ignore white space
//
if (wch==0x0A || wch==0x0D || wch==0x20 || wch==0x09)
continue;
//
// Have we reached the end?
//
if (wch==L'=')
break;
//
// How much is this character worth?
//
BYTE bDigit;
if (wch > 127 || (bDigit = mpwchb[wch]) == bBad)
{
hr = E_INVALIDARG;
goto Cleanup;
}
//
// Add in its contribution
//
bCurrent <<= 6;
bCurrent |= bDigit;
cbitFilled += 6;
//
// If we've got enough, output a byte
//
if (cbitFilled >= 8)
{
ULONG b = (bCurrent >> (cbitFilled-8)); // get's top eight valid bits
*pb++ = (BYTE)(b&0xFF); // store the byte away
cbitFilled -= 8;
}
}
*pcbData = (ULONG)(pb-rgb); // length
while (wch==L'=')
{
cbitFilled = 0;
pwch++;
wch = *pwch;
}
if (cbitFilled)
{
ULONG b = (bCurrent >> (cbitFilled-8)); // get's top eight valid bits
if (b)
{
hr = E_INVALIDARG;
goto Cleanup;
}
}
// characters used
if (ppwcNext)
*ppwcNext = pwch;
}
Cleanup:
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -