📄 pckunpck.cpp
字号:
res = pTempBuf->SetSize(4096);
HX_ASSERT(SUCCEEDED(res));
if (SUCCEEDED(res))
{
// fill up the buffer
UCHAR* pData = pTempBuf->GetBuffer();
int i;
for (i = 0; i < 4096; i++)
{
pData[i] = i & 0xff;
}
res = PackBuffer(pParams, "ufbau", 69, FALSE, pTempBuf, "foobar", 666);
HX_ASSERT(SUCCEEDED(res));
if (SUCCEEDED(res))
{
UINT32 nArg1, nArg5;
BOOL bArg2;
IHXBuffer* pArg3;
CHXString sArg4;
const char* pTemp = (const char*)pParams->GetBuffer();
int nCount = UnpackBuffer(pTemp, "ufbau", &nArg1, &bArg2, &pArg3, &sArg4, &nArg5);
HX_ASSERT(nCount == 5);
HX_ASSERT(*pTemp == '\0');
HX_ASSERT(nArg1 == 69 && bArg2 == FALSE && nArg5 == 666);
HX_ASSERT(sArg4 == "foobar");
HX_ASSERT(pArg3 && pArg3->GetSize() == 4096);
if (pArg3 && pArg3->GetSize() == 4096)
{
pData = pArg3->GetBuffer();
for (i = 0; i < 4096; i++)
{
HX_ASSERT(pData[i] == (i & 0xff));
}
}
HX_RELEASE(pArg3);
}
}
HX_RELEASE(pTempBuf);
}
}
#endif
UINT32 GetBinaryPackedSize(IHXValues* pValues)
{
UINT32 ulRet = 0;
if (pValues)
{
// Run through the ULONG32 properties
const char* pszName = NULL;
UINT32 ulValue = 0;
HX_RESULT rv = pValues->GetFirstPropertyULONG32(pszName, ulValue);
while (SUCCEEDED(rv))
{
// Add size of name/value type character: 'u'
ulRet += 1;
// Add size of name string plus NULL terminator
ulRet += (UINT32) strlen(pszName) + 1;
// Add 4 bytes for packing ULONG32
ulRet += 4;
// Get next ULONG32 prop
rv = pValues->GetNextPropertyULONG32(pszName, ulValue);
}
// Run through the CString properties
IHXBuffer* pValue = NULL;
rv = pValues->GetFirstPropertyCString(pszName, pValue);
while (SUCCEEDED(rv))
{
// Add size of name/value type character: 'c'
ulRet += 1;
// Add size of name string plus NULL terminator
ulRet += (UINT32) strlen(pszName) + 1;
// Add size of value string plus NULL terminator
ulRet += strlen((const char*) pValue->GetBuffer()) + 1;
// Get next CString prop
HX_RELEASE(pValue);
rv = pValues->GetNextPropertyCString(pszName, pValue);
}
// Run through the Buffer properties
rv = pValues->GetFirstPropertyBuffer(pszName, pValue);
while (SUCCEEDED(rv))
{
// Add size of name/value type character: 'b'
ulRet += 1;
// Add size of name string plus NULL terminator
ulRet += (UINT32) strlen(pszName) + 1;
// Add size of value buffer size (4 bytes)
ulRet += 4;
// Add size of value buffer
ulRet += pValue->GetSize();
// Get next Buffer prop
HX_RELEASE(pValue);
rv = pValues->GetNextPropertyBuffer(pszName, pValue);
}
}
return ulRet;
}
HX_RESULT PackValuesBinary(IHXBuffer* pBuffer,
IHXValues* pValues)
{
HX_RESULT retVal = HXR_FAIL;
if (pValues && pBuffer)
{
// Make sure the buffer is big enough
UINT32 ulMinSize = GetBinaryPackedSize(pValues);
// Is our buffer big enough?
if (ulMinSize && pBuffer->GetSize() >= ulMinSize)
{
// Ok, pack that puppy
BYTE* pBuf = pBuffer->GetBuffer();
if (pBuf)
{
// Clear the return value
retVal = HXR_OK;
// Run through the ULONG32 properties
const char* pszName = NULL;
UINT32 ulValue = 0;
HX_RESULT rv = pValues->GetFirstPropertyULONG32(pszName, ulValue);
while (SUCCEEDED(rv))
{
// Copy name/value type character: 'u'
*pBuf++ = (BYTE) 'u';
// Copy name string plus NULL terminator
UINT32 ulBytes = (UINT32) strlen(pszName) + 1;
memcpy(pBuf, pszName, ulBytes);
pBuf += ulBytes;
// Copy ULONG32 in big-endian format (high byte first)
*pBuf++ = (BYTE) ((ulValue >> 24) & 0x000000FF);
*pBuf++ = (BYTE) ((ulValue >> 16) & 0x000000FF);
*pBuf++ = (BYTE) ((ulValue >> 8) & 0x000000FF);
*pBuf++ = (BYTE) ( ulValue & 0x000000FF);
// Get next ULONG32 prop
rv = pValues->GetNextPropertyULONG32(pszName, ulValue);
}
// Run through the CString properties
IHXBuffer* pValue = NULL;
rv = pValues->GetFirstPropertyCString(pszName, pValue);
while (SUCCEEDED(rv))
{
// Copy name/value type character: 'c'
*pBuf++ = (BYTE) 'c';
// Copy name string plus NULL terminator
UINT32 ulBytes = (UINT32) strlen(pszName) + 1;
memcpy(pBuf, pszName, ulBytes);
pBuf += ulBytes;
// Copy value string plus NULL terminator
const char* pszValue = (const char*) pValue->GetBuffer();
ulBytes = (UINT32) strlen(pszValue) + 1;
memcpy(pBuf, pszValue, ulBytes);
pBuf += ulBytes;
// Get next CString prop
HX_RELEASE(pValue);
rv = pValues->GetNextPropertyCString(pszName, pValue);
}
// Run through the Buffer properties
rv = pValues->GetFirstPropertyBuffer(pszName, pValue);
while (SUCCEEDED(rv))
{
// Copy name/value type character: 'b'
*pBuf++ = (BYTE) 'b';
// Copy name string plus NULL terminator
UINT32 ulBytes = (UINT32) strlen(pszName) + 1;
memcpy(pBuf, pszName, ulBytes);
pBuf += ulBytes;
// Copy value buffer size in big-endian format
UINT32 ulSize = pValue->GetSize();
*pBuf++ = (BYTE) ((ulSize >> 24) & 0x000000FF);
*pBuf++ = (BYTE) ((ulSize >> 16) & 0x000000FF);
*pBuf++ = (BYTE) ((ulSize >> 8) & 0x000000FF);
*pBuf++ = (BYTE) ( ulSize & 0x000000FF);
// Copy value buffer
memcpy(pBuf, pValue->GetBuffer(), ulSize);
pBuf += ulSize;
// Get next Buffer prop
HX_RELEASE(pValue);
rv = pValues->GetNextPropertyBuffer(pszName, pValue);
}
}
}
}
return retVal;
}
HX_RESULT CreateBuffer(REF(IHXBuffer*) rpBuffer,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
// Were we given a context?
if (pContext)
{
// Yes, we have a context, use it to create the buffer
//
// Get the CCF
IHXCommonClassFactory* pCCF = NULL;
retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**) &pCCF);
if (SUCCEEDED(retVal))
{
// Create a buffer
HX_RELEASE(rpBuffer);
retVal = pCCF->CreateInstance(CLSID_IHXBuffer,
(void**) &rpBuffer);
}
HX_RELEASE(pCCF);
}
else
{
// No, we don't have a context, so use CHXBuffer
CHXBuffer* pBuffer = new CHXBuffer();
if (pBuffer)
{
// Assign the out parameter
HX_RELEASE(rpBuffer);
rpBuffer = (IHXBuffer*) pBuffer;
rpBuffer->AddRef();
// Clear the return value
retVal = HXR_OK;
}
}
return retVal;
}
HX_RESULT CreateValues(REF(IHXValues*) rpValues,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
// Were we given a context?
if (pContext)
{
// Yes, we have a context, use it to create the IHXValues
//
// Get the CCF
IHXCommonClassFactory* pCCF = NULL;
retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**) &pCCF);
if (SUCCEEDED(retVal))
{
// Create an IHXValues
HX_RELEASE(rpValues);
retVal = pCCF->CreateInstance(CLSID_IHXValues,
(void**) &rpValues);
}
HX_RELEASE(pCCF);
}
else
{
// No, we don't have a context, so use CHXBuffer
CHXHeader* pValues = new CHXHeader();
if (pValues)
{
// Assign the out parameter
HX_RELEASE(rpValues);
rpValues = (IHXValues*) pValues;
rpValues->AddRef();
// Clear the return value
retVal = HXR_OK;
}
}
return retVal;
}
HX_RESULT CreateStringBuffer(REF(IHXBuffer*) rpBuffer,
const char* pszStr,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
if (pszStr)
{
// Create a buffer
IHXBuffer* pBuffer = NULL;
retVal = CreateBuffer(pBuffer, pContext);
if (SUCCEEDED(retVal))
{
// Set the string into the buffer
retVal = pBuffer->Set((const UCHAR*) pszStr, strlen(pszStr) + 1);
if (SUCCEEDED(retVal))
{
// Assign the out parameters
HX_RELEASE(rpBuffer);
rpBuffer = pBuffer;
rpBuffer->AddRef();
}
}
HX_RELEASE(pBuffer);
}
return retVal;
}
HX_RESULT SetCStringProperty(IHXValues* pValues,
const char* pszName,
const char* pszValue,
IUnknown* pContext,
BOOL bSetAsBufferProp)
{
HX_RESULT retVal = HXR_FAIL;
if (pValues && pszName && pszValue)
{
// Create value buffer
IHXBuffer* pValue = NULL;
retVal = CreateStringBuffer(pValue, pszValue, pContext);
if (SUCCEEDED(retVal))
{
// Set the property
if (bSetAsBufferProp)
{
retVal = pValues->SetPropertyBuffer(pszName, pValue);
}
else
{
retVal = pValues->SetPropertyCString(pszName, pValue);
}
}
HX_RELEASE(pValue);
}
return retVal;
}
HX_RESULT SetCStringPropertyWithNullTerm(IHXValues* pValues,
const char* pszName,
BYTE* pBuf,
UINT32 ulLen,
IUnknown* pContext,
BOOL bSetAsBufferProp)
{
HX_RESULT retVal = HXR_FAIL;
if (pValues && pszName && pBuf && ulLen)
{
// Create value buffer
IHXBuffer* pValue = NULL;
retVal = CreateBuffer(pValue, pContext);
if (SUCCEEDED(retVal))
{
// Set the buffer size
retVal = pValue->SetSize(ulLen + 1);
if (SUCCEEDED(retVal))
{
// Get the buffer pointer
BYTE* pValBuf = pValue->GetBuffer();
if (pValBuf)
{
// memcpy the buffer
memcpy(pValBuf, pBuf, ulLen); /* Flawfinder: ignore */
// Add the NULL-terminator
pValBuf[ulLen] = (BYTE) '\0';
// Are we setting as a buffer property?
if (bSetAsBufferProp)
{
retVal = pValues->SetPropertyBuffer(pszName, pValue);
}
else
{
retVal = pValues->SetPropertyCString(pszName, pValue);
}
}
else
{
retVal = HXR_OUTOFMEMORY;
}
}
}
HX_RELEASE(pValue);
}
return retVal;
}
HX_RESULT CreateNullTermBuffer(BYTE* pBuf,
UINT32 ulLen,
char** ppNTBuf)
{
HX_RESULT retVal = HXR_FAIL;
if (pBuf && ulLen && ppNTBuf)
{
char* pTmp = new char [ulLen+1];
if (pTmp)
{
// Copy pBuf into the new buf
memcpy(pTmp, pBuf, ulLen); /* Flawfinder: ignore */
// NULL-terminate the new buf
pTmp[ulLen] = '\0';
// Set the out parameter
*ppNTBuf = pTmp;
// Clear the return value
retVal = HXR_OK;
}
}
return retVal;
}
HX_RESULT SetBufferProperty(IHXValues* pValues,
const char* pszName,
BYTE* pBuf,
UINT32 ulLen,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
if (pValues && pszName && pBuf && ulLen)
{
// Create value buffer
IHXBuffer* pValue = NULL;
retVal = CreateBuffer(pValue, pContext);
if (SUCCEEDED(retVal))
{
// Set the buffer
retVal = pValue->Set(pBuf, ulLen);
if (SUCCEEDED(retVal))
{
// Set the property
retVal = pValues->SetPropertyBuffer(pszName, pValue);
}
}
HX_RELEASE(pValue);
}
return retVal;
}
HX_RESULT UnpackPropertyULONG32(IHXValues* pValues,
REF(BYTE*) rpBuf,
BYTE* pLimit,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
if (pValues && rpBuf && pLimit &&
rpBuf < pLimit && rpBuf[0] == 'u')
{
// Skip the 'u' type character
rpBuf++;
// Save the beginning of the string
const char* pszName = (const char*) rpBuf;
// Search until we find either a NULL or
// the end of the buffer
while (rpBuf < pLimit && *rpBuf != 0) ++rpBuf;
// Did we get a NULL terminator?
if (rpBuf < pLimit && *rpBuf == 0)
{
// We know now that pszName is a valid string
//
// Skip the NULL terminator
++rpBuf;
// Now get the ULONG32
if (rpBuf + 4 <= pLimit)
{
// Unpack in big-endian form
UINT32 ulValue = ((rpBuf[0] << 24) & 0xFF000000) |
((rpBuf[1] << 16) & 0x00FF0000) |
((rpBuf[2] << 8) & 0x0000FF00) |
( rpBuf[3] & 0x000000FF);
// Skip the ULONG32
rpBuf += 4;
// Set the property
retVal = pValues->SetPropertyULONG32(pszName, ulValue);
}
}
}
return retVal;
}
HX_RESULT UnpackPropertyCString(IHXValues* pValues,
REF(BYTE*) rpBuf,
BYTE* pLimit,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
if (pValues && rpBuf && pLimit &&
rpBuf < pLimit && rpBuf[0] == 'c')
{
// Skip the 'c' type character
rpBuf++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -