📄 pckunpck.cpp
字号:
// Skip the 'c' 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; // Save the beginning of the value string const char* pszValue = (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) { // Skip the NULL terminator ++rpBuf; // We know now that pszValue is a valid string, so // make an IHXBuffer out of it IHXBuffer* pValue = NULL; retVal = CreateStringBuffer(pValue, pszValue, pContext); if (SUCCEEDED(retVal)) { // Set the property retVal = pValues->SetPropertyCString(pszName, pValue); } HX_RELEASE(pValue); } } } return retVal;}HX_RESULT UnpackPropertyBuffer(IHXValues* pValues, REF(BYTE*) rpBuf, BYTE* pLimit, IUnknown* pContext){ HX_RESULT retVal = HXR_FAIL; if (pValues && rpBuf && pLimit && rpBuf < pLimit && rpBuf[0] == 'b') { // Skip the 'b' 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; // Do we have enough bytes to get the buffer length? if (rpBuf + 4 <= pLimit) { // Unpack the buffer length in big-endian form UINT32 ulLen = ((rpBuf[0] << 24) & 0xFF000000) | ((rpBuf[1] << 16) & 0x00FF0000) | ((rpBuf[2] << 8) & 0x0000FF00) | ( rpBuf[3] & 0x000000FF); // Skip the buffer length rpBuf += 4; // Do we have enough bytes to get the buffer? if (rpBuf + ulLen <= pLimit) { // Create a buffer IHXBuffer* pValue = NULL; retVal = CreateBuffer(pValue, pContext); if (SUCCEEDED(retVal)) { // Set the buffer retVal = pValue->Set(rpBuf, ulLen); if (SUCCEEDED(retVal)) { // Skip the buffer bytes rpBuf += ulLen; // Set the property retVal = pValues->SetPropertyBuffer(pszName, pValue); } } HX_RELEASE(pValue); } } } } return retVal;}HX_RESULT UnpackValuesBinary(IHXValues* pValues, IHXBuffer* pBuffer, IUnknown* pContext){ HX_RESULT retVal = HXR_FAIL; if (pValues && pBuffer) { retVal = UnpackValuesBinary(pValues, pBuffer->GetBuffer(), pBuffer->GetSize(), pContext); } return retVal;}HX_RESULT UnpackValuesBinary(IHXValues* pValues, BYTE* pBuf, UINT32 ulLen, IUnknown* pContext){ HX_RESULT retVal = HXR_FAIL; if (pBuf && ulLen) { // Get the pointer limit BYTE* pLimit = pBuf + ulLen; // Make sure this is not string format if (pBuf[0] != '[') { // Clear the return value retVal = HXR_OK; // Loop through the buffer, unpacking name/value pairs while (pBuf < pLimit && SUCCEEDED(retVal)) { // Get a property type code char c = (char) pBuf[0]; // Save the buffer pointer BYTE* pCur = pBuf; // Switch based on type switch (c) { case 'u': retVal = UnpackPropertyULONG32(pValues, pBuf, pLimit, pContext); break; case 'c': retVal = UnpackPropertyCString(pValues, pBuf, pLimit, pContext); break; case 'b': retVal = UnpackPropertyBuffer(pValues, pBuf, pLimit, pContext); break; default: retVal = HXR_FAIL; break; } // Do a sanity check: if we succeeded, // then we must have advanced the pointer. // This will prevent an infinite loop. if (SUCCEEDED(retVal) && pCur == pBuf) { retVal = HXR_FAIL; } } } } return retVal;}HX_RESULT PackValues(REF(IHXBuffer*) rpBuffer, IHXValues* pValues, BOOL bPackBinary, IUnknown* pContext){ HX_RESULT retVal = HXR_FAIL; if (pValues) { // Create an output IHXBuffer IHXBuffer* pBuffer = NULL; retVal = CreateBuffer(pBuffer, pContext); if (SUCCEEDED(retVal)) { // Are we supposed to pack this in binary form? if (bPackBinary) { // Pack in binary form // // First get the size necessary to pack it in binary form UINT32 ulBinPackSize = GetBinaryPackedSize(pValues); if (ulBinPackSize) { // Make the buffer this size retVal = pBuffer->SetSize(ulBinPackSize); if (SUCCEEDED(retVal)) { // Binary pack the buffer retVal = PackValuesBinary(pBuffer, pValues); if (SUCCEEDED(retVal)) { // Copy the out parameter HX_RELEASE(rpBuffer); rpBuffer = pBuffer; rpBuffer->AddRef(); } } } else { retVal = HXR_FAIL; } } else { // Pack in a string CHXString cTmp; retVal = PackValues(cTmp, pValues); if (SUCCEEDED(retVal)) { // Now just copy the string into the IHXBuffer retVal = pBuffer->Set((const UCHAR*) (const char*) cTmp, cTmp.GetLength() + 1); if (SUCCEEDED(retVal)) { // Set the out parameter HX_RELEASE(rpBuffer); rpBuffer = pBuffer; rpBuffer->AddRef(); } } } } HX_RELEASE(pBuffer); } return retVal;}HX_RESULT UnpackValues(REF(IHXValues*) rpValues, IHXBuffer* pBuffer, IUnknown* pContext){ HX_RESULT retVal = HXR_FAIL; if (pBuffer) { retVal = UnpackValues(rpValues, pBuffer->GetBuffer(), pBuffer->GetSize(), pContext); } return retVal;}HX_RESULT UnpackValues(REF(IHXValues*) rpValues, BYTE* pBuf, UINT32 ulLen, IUnknown* pContext){ HX_RESULT retVal = HXR_FAIL; if (pBuf && ulLen) { // Create an output IHXValues IHXValues* pValues = NULL; retVal = CreateValues(pValues, pContext); if (SUCCEEDED(retVal)) { // Get the string const char* pszBuffer = (const char*) pBuf; // Is this packed in binary or text? If it's in text // form, then it will have a '[' as the first character if (pszBuffer[0] != '[') { // The buffer is binary packed retVal = UnpackValuesBinary(pValues, pBuf, ulLen, pContext); } else { // The buffer is text packed retVal = UnpackValues(pszBuffer, pValues, FALSE); } if (SUCCEEDED(retVal)) { // Assign the out parameter HX_RELEASE(rpValues); rpValues = pValues; rpValues->AddRef(); } } HX_RELEASE(pValues); } return retVal;}// This method checks to see if all the properties// in pValues1 are in pValues2 and that the value// of these properties is indentical. pValues2,// however, could still have properties that pValues1// doesn't have. AreValuesIdentical() calls// AreValuesInclusiveIdentical() in both directions,// which establishes absolute equality if both// are true.BOOL AreValuesInclusiveIdentical(IHXValues* pValues1, IHXValues* pValues2){ BOOL bRet = FALSE; if (pValues1 && pValues2) { // Assume that they are equal, and breakout // at the first inequality bRet = TRUE; // Check the ULONG32 properties const char* pszName = NULL; UINT32 ulValue1 = 0; HX_RESULT rv = pValues1->GetFirstPropertyULONG32(pszName, ulValue1); while (SUCCEEDED(rv) && bRet) { // Lookup this property in pValues2 UINT32 ulValue2 = 0; HX_RESULT rv2 = pValues2->GetPropertyULONG32(pszName, ulValue2); // Check for a match if (FAILED(rv2) || ulValue1 != ulValue2) { bRet = FALSE; } // Get next ULONG32 property rv = pValues1->GetNextPropertyULONG32(pszName, ulValue1); } if (bRet) { // Check the CString properties IHXBuffer* pValue1 = NULL; rv = pValues1->GetFirstPropertyCString(pszName, pValue1); while (SUCCEEDED(rv) && bRet) { // Lookup this property in pValues2 IHXBuffer* pValue2 = NULL; HX_RESULT rv2 = pValues2->GetPropertyCString(pszName, pValue2); if (FAILED(rv2) || strcmp((const char*) pValue1->GetBuffer(), (const char*) pValue2->GetBuffer()) != 0) { bRet = FALSE; } HX_RELEASE(pValue2); // Get next CString prop HX_RELEASE(pValue1); rv = pValues1->GetNextPropertyCString(pszName, pValue1); } if (bRet) { // Check the buffer properties rv = pValues1->GetFirstPropertyBuffer(pszName, pValue1); while (SUCCEEDED(rv) && bRet) { // Lookup this property in pValues2 IHXBuffer* pValue2 = NULL; HX_RESULT rv2 = pValues2->GetPropertyBuffer(pszName, pValue2); if (FAILED(rv2) || pValue1->GetSize() != pValue2->GetSize() || memcmp((const void*) pValue1->GetBuffer(), (const void*) pValue2->GetBuffer(), pValue1->GetSize()) != 0) { bRet = FALSE; } HX_RELEASE(pValue2); // Get next Buffer prop HX_RELEASE(pValue1); rv = pValues1->GetNextPropertyBuffer(pszName, pValue1); } } } } return bRet;}BOOL AreValuesIdentical(IHXValues* pValues1, IHXValues* pValues2){ BOOL bRet = FALSE; // Check if all the properties in pValues1 are // in pValues2 and are identical bRet = AreValuesInclusiveIdentical(pValues1, pValues2); if (bRet) { // Check if all the properties in pValues2 are // in pValues1 and are identical bRet = AreValuesInclusiveIdentical(pValues2, pValues1); } return bRet;}#ifdef _DEBUGHX_RESULT TestValuesPacking(IUnknown* pContext){ HX_RESULT retVal = HXR_OK; // Create an IHXValues IHXValues* pValues = NULL; retVal = CreateValues(pValues, pContext); if (SUCCEEDED(retVal)) { // Populate this IHXValues pValues->SetPropertyULONG32("ulong1", 42); pValues->SetPropertyULONG32("ulong2", 0xbaadf00d); SetCStringProperty(pValues, "cstring1", "Rock the Casbah", pContext); SetCStringProperty(pValues, "cstring2", "Sandinista", pContext); UINT32 ulBuf1Len = 128; BYTE* pBuf1 = new BYTE [ulBuf1Len]; if (pBuf1) { // Fill the buffer with random byte values srand(time(NULL)); for (UINT32 i = 0; i < ulBuf1Len; i++) { UINT32 ulVal = (UINT32) rand(); pBuf1[i] = (BYTE) (ulVal & 0x000000FF); } SetBufferProperty(pValues, "buffer1", pBuf1, ulBuf1Len, pContext); // Pack it as text IHXBuffer* pBufferText = NULL; retVal = PackValues(pBufferText, pValues, FALSE, pContext); if (SUCCEEDED(retVal)) { // Now unpack it IHXValues* pValuesTextOut = NULL; retVal = UnpackValues(pValuesTextOut, pBufferText, pContext); if (SUCCEEDED(retVal)) { // Compare them if (AreValuesIdentical(pValues, pValuesTextOut)) { // Now pack as binary IHXBuffer* pBufferBinary = NULL; retVal = PackValues(pBufferBinary, pValues, TRUE, pContext); if (SUCCEEDED(retVal)) { // Now unpack it IHXValues* pValuesBinaryOut = NULL; retVal = UnpackValues(pValuesBinaryOut, pBufferBinary, pContext); if (SUCCEEDED(retVal)) { // Compare them if (!AreValuesIdentical(pValues, pValuesBinaryOut)) { // Oops - they are not the same retVal = HXR_FAIL; } } HX_RELEASE(pValuesBinaryOut); } HX_RELEASE(pBufferBinary); } else { // Oops - they are not the same retVal = HXR_FAIL; } } HX_RELEASE(pValuesTextOut); } HX_RELEASE(pBufferText); } HX_VECTOR_DELETE(pBuf1); } HX_RELEASE(pValues); return retVal;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -