⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pckunpck.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		CHXString* pTemp = va_arg(vargs, CHXString*);
		HX_ASSERT(pTemp);
		if (!pTemp)
		    return nRead; // invalid CHXString*?
		pTemp->Empty();

		// read the begin quote
		if (*pBufStr != '"')
		    return nRead;
		pBufStr++;

		// read till we run out of buffer OR hit the end quote
		BOOL bEscaped = FALSE;
		while (*pBufStr && (bEscaped || *pBufStr != '"'))
		{
		    if (bEscaped)
		    {
			const char* pScary = strchr(kUnScaryChars, *pBufStr);
			HX_ASSERT(pScary);
			if (pScary)
			{
			    *pTemp += kScaryChars[pScary - kUnScaryChars];
			}
		    }
		    else
		    {
			if (*pBufStr == '\\')
			{
			    bEscaped = TRUE;
			}
			else
			{
			    *pTemp += *pBufStr;
			}
		    }
		    pBufStr++;
		}

		// read the end quote!
		if (*pBufStr != '"')
		    return nRead;
		pBufStr++;
	    }
	    break;

	    case 'b':
	    {
		IHXBuffer** ppBuf = va_arg(vargs, IHXBuffer**);
		HX_ASSERT(ppBuf);
		if (!ppBuf)
		    return nRead;

		CHXBuffer* pCHXBuffer = new CHXBuffer;
		if (!pCHXBuffer)
		    return nRead;
		
		pCHXBuffer->AddRef();
		*ppBuf = (IHXBuffer*)pCHXBuffer;

		HX_RESULT res = HXR_FAIL;
		const char* pEnd = strchr(pBufStr, ';');
		if (pEnd)
		{
		    UINT32 uSize = pEnd - pBufStr;
		    CHXString sTemp(pBufStr, uSize);
		    uSize = (uSize * 3) / 4; // we need 75% the space
		    
		    res = (*ppBuf)->SetSize(uSize);
		    if (SUCCEEDED(res))
		    {
			
			UCHAR* pDecodeBuf = (*ppBuf)->GetBuffer();
			HX_ASSERT(pDecodeBuf);
			
			UINT32 nLen = BinFrom64(sTemp,
                                                sTemp.GetLength()+1,
                                                pDecodeBuf);
			HX_ASSERT(nLen <= uSize);
			(*ppBuf)->SetSize(nLen);
			
				// go the the end of the buffer
			pBufStr = pEnd;
		    }
		}
		
		if (FAILED(res))
		{
		    HX_RELEASE(*ppBuf);
		    return nRead;
		}
	    }
	    break;

	    case 'p':
	    {
		IUnknown** ppUnk = va_arg(vargs, IUnknown**);
		HX_ASSERT(ppUnk);
		if (!ppUnk)
		    return nRead;

                // XXXSAB untested...
                char* pEnd = NULL;
                char tmpBuf[9];
                SafeStrCpy(tmpBuf, pBufStr, 8);
                tmpBuf[9] = 0;
                unsigned long val = strtoul(tmpBuf, &pEnd, 16);

		// if (sscanf(pBufStr, "%08x", ppUnk) != 1)
                if (pEnd && pEnd > tmpBuf)
		{
		    *ppUnk = NULL;
		    return nRead;
		}
		pBufStr = strchr(pBufStr, ';');
	    }
	    break;

	    case 'v':
	    {
		IHXValues** ppValues = va_arg(vargs, IHXValues**);
		if (!ppValues)
		{
		    HX_ASSERT(FALSE);
		    return nRead;
		}

		if (FAILED(UnpackValues(pBufStr, *ppValues)))
		{
		    HX_RELEASE(*ppValues);
		    return nRead;
		}
	    }
	    break;
	}

	// mark another param read
	nRead++;

	// find the next delimiter
	if (!pBufStr || *pBufStr != ';')
	    return nRead;
	pBufStr++;
	
	pTemp++;
    }
    
    return nRead;
}


HX_RESULT
PackValues(REF(CHXString) sBuffer, IHXValues* pValues)
{
    if (!pValues)
	return HXR_FAIL;
    
    sBuffer = '[';
    
    ULONG32 uVal = 0;
    const char* pName = NULL;
    HX_RESULT res = pValues->GetFirstPropertyULONG32(pName, uVal);
    while (SUCCEEDED(res))
    {
	sBuffer += pName;
	sBuffer += '=';
	sBuffer.AppendULONG(uVal);
	sBuffer += ',';
	
	res = pValues->GetNextPropertyULONG32(pName, uVal);
    }

    IHXBuffer* pValBuf = NULL;
    res = pValues->GetFirstPropertyCString(pName, pValBuf);
    while (SUCCEEDED(res))
    {
	sBuffer += pName;
	sBuffer += "=\"";

	const char* pStr = (const char*)pValBuf->GetBuffer();
	while (*pStr)
	{
	    // double-count chars we'll have to escape
	    const char* pScary = strchr(kScaryChars, *pStr);
	    if (pScary)
	    {
		sBuffer += '\\';
		sBuffer += kUnScaryChars[pScary - kScaryChars];
	    }
	    else
	    {
		sBuffer += *pStr;
	    }
	    pStr++;
	}
	sBuffer += "\",";

	HX_RELEASE(pValBuf);
	res = pValues->GetNextPropertyCString(pName, pValBuf);
    }

    res = pValues->GetFirstPropertyBuffer(pName, pValBuf);
    while (SUCCEEDED(res))
    {
	sBuffer += pName;
	sBuffer += '=';

	CHXString sTemp;
	UINT32 uSize = (pValBuf->GetSize() * 4) / 3 + 10;
	char* pTemp = (char*)sTemp.GetBuffer(uSize);
	if (pTemp)
	{
//	    int nLen = BinTo64(pValBuf->GetBuffer(), uSize, pTemp);
	    int nLen = BinTo64(pValBuf->GetBuffer(), pValBuf->GetSize(), pTemp);
	    sTemp.ReleaseBuffer();
	    
	    HX_ASSERT(nLen >= 0);
	}
	
	HX_RELEASE(pValBuf);
	
	sBuffer += sTemp;
	sBuffer += ',';

	res = pValues->GetNextPropertyBuffer(pName, pValBuf);
    }

    UINT32 uSize = sBuffer.GetLength();
    sBuffer.SetAt(uSize-1, ']');

    return HXR_OK;
}



HX_RESULT
Bufferize(REF(IHXBuffer*) pBuffer, void* pData, UINT32 uSize)
{
    CHXBuffer* pCHXBuffer = new CHXBuffer;
    if (!pCHXBuffer)
	return HXR_OUTOFMEMORY;

    pCHXBuffer->AddRef();
    HX_RESULT res = pCHXBuffer->Set((UCHAR*)pData, uSize);
    if (SUCCEEDED(res))
    {
	pBuffer = (IHXBuffer*)pCHXBuffer;
    }
    else
    {
	HX_RELEASE(pCHXBuffer);
    }
    
    return res;
}


HX_RESULT
UnpackValues(REF(const char*) pBuffer, REF(IHXValues*) pValues,
             BOOL bCreateValues)
{
    HX_ASSERT(pBuffer);
    if (!pBuffer)
	return HXR_POINTER;
    
    if (*pBuffer != '[')
	return HXR_FAIL;

    if (bCreateValues)
    {
        CHXHeader* pCHXHeader = new CHXHeader;
        if (!pCHXHeader)
	    return HXR_OUTOFMEMORY;
        pCHXHeader->AddRef();
        pValues = (IHXValues*)pCHXHeader;
    }
    else
    {
        // The input said to NOT create the IHXValues,
        // but use the passed-in one, so if we don't
        // *have* a passed-in one, then that's an error.
        if (!pValues)
        {
            return HXR_FAIL;
        }
    }

    // eat the '['
    pBuffer++;

    HX_RESULT res = HXR_FAIL;
    while (*pBuffer)
    {
	res = HXR_FAIL;
	
	// find the end of the property name
	const char* pEnd = strchr(pBuffer, '=');
	HX_ASSERT(pEnd);
	if (!pEnd)
	    break;

	// parse the name
	CHXString sName(pBuffer, pEnd - pBuffer);
	pBuffer = pEnd+1;

	if (*pBuffer == '"')
	{
	    pBuffer++;
	    // looks like a string
	    CHXString sValue;
	    
	    BOOL bEscaped = FALSE;
	    while (*pBuffer != '"' && !bEscaped && *pBuffer)
	    {
		if (bEscaped)
		{
		    const char* pScary = strchr(kUnScaryChars, *pBuffer);
		    HX_ASSERT(pScary);
		    if (pScary)
		    {
			sValue += kScaryChars[pScary - kUnScaryChars];
		    }
		}
		else
		{
		    if (*pBuffer == '\\')
		    {
			bEscaped = TRUE;
		    }
		    else
		    {
			sValue += *pBuffer;
		    }
		}
		pBuffer++;
	    }
	    
	    // read the end quote!
	    if (*pBuffer == '"')
	    {
		pBuffer++;
		
		IHXBuffer* pStrBuf = NULL;
		res = Bufferize(pStrBuf,
				(void*)(const char*)sValue,
				sValue.GetLength()+1);
		if (SUCCEEDED(res))
		{
		    res = pValues->SetPropertyCString(sName, pStrBuf);
		    HX_RELEASE(pStrBuf);
		}
	    }
	}
	else
	{
	    // is it an int or base64 buffer?

	    // how many digits do we have?
	    size_t sz = strspn(pBuffer, kDecimals);
	    
	    // where does the next property begin?
	    pEnd = strpbrk(pBuffer, ",]");
	    HX_ASSERT(pEnd);
	    if (!pEnd)
		break;

	    // so were there *only* decimal digits?
	    if (pBuffer + sz == pEnd)
	    {
		CHXString sNumber(pBuffer, sz);
                ULONG32 uValue = strtoul((const char*) sNumber, NULL, 10);

		res = pValues->SetPropertyULONG32(sName, uValue);
	    }
	    else
	    {
		// nope-- looks like a base64 buffer
		UINT32 uSize = pEnd - pBuffer;
		UINT32 uBinSize = (uSize * 3) / 4 + 10;

		res = HXR_OUTOFMEMORY;
		CHXBuffer* pTempBuf = new CHXBuffer;
		if (!pTempBuf)
		    break;
		pTempBuf->AddRef();
		res = pTempBuf->SetSize(uBinSize);
		if (SUCCEEDED(res))
		{
		    UCHAR* pTemp = pTempBuf->GetBuffer();
		    UINT32 nLen = BinFrom64(pBuffer, uSize, pTemp);
		    HX_ASSERT(nLen <= uBinSize && nLen > 0);
		    pTempBuf->SetSize(nLen);
		    res = pValues->SetPropertyBuffer(sName, pTempBuf);
		}
		HX_RELEASE(pTempBuf);
	    }

	    // advance to the end
	    pBuffer = pEnd;
	}

	// did we fail during the property parsing?
	if (FAILED(res))
	    break;
	
	// are we done?
	if (*pBuffer == ']')
	{
	    pBuffer++;
	    break;
	}

	// ready for next?
	if (*pBuffer != ',')
	{
	    res = HXR_FAIL;
	    break;
	}
	pBuffer++;
    }

    if (FAILED(res))
	HX_RELEASE(pValues);

    return res;
}

#ifdef _DEBUG

void
TestBufferPacking()
{
    IHXBuffer* pParams = NULL;
    HX_RESULT res = PackBuffer(pParams, "uuuuuu", 0, 1, 2, 3, 4, 5);
    HX_ASSERT(SUCCEEDED(res));
    if (SUCCEEDED(res))
    {
	int nums[6];
	const char* pTemp = (const char*)pParams->GetBuffer();
	int nCount = UnpackBuffer(pTemp, "uuuuuu", nums, nums+1, nums+2, nums+3, nums+4, nums+5);
	HX_ASSERT(nCount == 6);
	HX_ASSERT(*pTemp == '\0');

	for (int i = 0; i < 6; i++)
	{
	    HX_ASSERT(nums[i] == i);
	}

	HX_RELEASE(pParams);
    }

    res = PackBuffer(pParams, "uauau", 10, "foo", 20, "bar", 50);
    HX_ASSERT(SUCCEEDED(res));
    if (SUCCEEDED(res))
    {
	CHXString sArg2, sArg4;
	UINT32 nArg1, nArg3, nArg5;
	const char* pTemp = (const char*)pParams->GetBuffer();
	int nCount = UnpackBuffer(pTemp, "uauau", &nArg1, &sArg2, &nArg3, &sArg4, &nArg5);
	HX_ASSERT(nCount == 5);
	HX_ASSERT(*pTemp == '\0');

	HX_ASSERT(nArg1 == 10 && nArg3 == 20 && nArg5 == 50);
	HX_ASSERT(sArg2 == "foo" && sArg4 == "bar");

	HX_RELEASE(pParams);
    }

    res = PackBuffer(pParams, "fuda", TRUE, 666, 12.3456789, "foobar");
    HX_ASSERT(SUCCEEDED(res));
    if (SUCCEEDED(res))
    {
	BOOL bArg1;
	UINT32 nArg2;
	double dArg3;
	CHXString sArg4;
	
	const char* pTemp = (const char*)pParams->GetBuffer();
	int nCount = UnpackBuffer(pTemp, "fuda", &bArg1, &nArg2, &dArg3, &sArg4);
	HX_ASSERT(nCount == 4);
	HX_ASSERT(*pTemp == '\0');

	HX_ASSERT(bArg1 == TRUE && nArg2 == 666 && dArg3 == 12.3456789);
	HX_ASSERT(sArg4 == "foobar");
	
	HX_RELEASE(pParams);
    }

    CHXBuffer* pTempBuf = new CHXBuffer;
    HX_ASSERT(pTempBuf);
    if (pTempBuf)
    {
	HX_ADDREF(pTempBuf);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -