windows-nt/Source/XPSP1/NT/multimedia/directx/dxvb/dx8vb/dplaybufhelp.cpp
2020-09-26 16:20:57 +08:00

269 lines
6.6 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
//
// File: DplayBufHelp.cpp
// Content: Helper functions for DPlay Buffers (Byte arrays)
//
//////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Direct.h"
#define SAFE_FREE(p) { if(p) { free (p); p=NULL; } }
#define SAFE_DELETE(p) { if(p) { delete (p); p=NULL; } }
#define INITIAL_BUFFER_SIZE 20
HRESULT WINAPI VB_GrowBuffer(SAFEARRAY **Buffer, DWORD dwGrowSize);
HRESULT WINAPI VB_NewBuffer(SAFEARRAY **Buffer, long *lOffSet);
HRESULT WINAPI VB_AddDataToBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet);
HRESULT WINAPI VB_AddStringToBuffer(SAFEARRAY **Buffer, BSTR StringData, long *lOffSet);
HRESULT WINAPI VB_GetDataFromBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet);
HRESULT WINAPI VB_GetStringFromBuffer(SAFEARRAY **Buffer, long *lOffSet, BSTR *sData);
// Functions for writing a buffer
HRESULT WINAPI VB_AddStringToBuffer(SAFEARRAY **Buffer, BSTR StringData, long *lOffSet)
{
HRESULT hr;
// For strings we will first write out a DWORD
// containging the length of the string. Then we
// will write the actual data to the string.
DWORD dwStrLen= (((DWORD*)StringData)[-1]);
DWORD dwDataSize = sizeof(DWORD) + dwStrLen;
if (!StringData)
return E_INVALIDARG;
if (!((SAFEARRAY*)*Buffer))
{
// We need to create this buffer, it doesn't exist
SAFEARRAY *lpData = NULL;
SAFEARRAYBOUND rgsabound[1];
// Let's create our SafeArray
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
rgsabound[0].cElements = dwDataSize; //Set the initial size
// Create this data
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
if (!lpData)
return E_OUTOFMEMORY;
(SAFEARRAY*)*Buffer = lpData;
}
if (!((SAFEARRAY*)*Buffer)->pvData)
return E_INVALIDARG;
// Do we have enough memory for this string right now?
if (*lOffSet + dwDataSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
if (FAILED( hr = VB_GrowBuffer(Buffer, dwDataSize) ) )
return hr;
// Ok, now we' ve got our memory, copy it over
// First the length
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
__try {
memcpy(lPtr + *lOffSet, &dwStrLen, sizeof(DWORD));
*lOffSet += sizeof(DWORD);
// Now the actual string
memcpy(lPtr + *lOffSet, StringData, dwStrLen);
*lOffSet += dwStrLen;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_INVALIDARG;
}
return S_OK;
}
HRESULT WINAPI VB_AddDataToBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet)
{
HRESULT hr;
if (!lData)
return E_INVALIDARG;
if (!lSize)
return E_INVALIDARG;
if (!((SAFEARRAY*)*Buffer))
{
// We need to create this buffer, it doesn't exist
SAFEARRAY *lpData = NULL;
SAFEARRAYBOUND rgsabound[1];
// Let's create our SafeArray
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
rgsabound[0].cElements = lSize; //Set the initial size
// Create this data
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
if (!lpData)
return E_OUTOFMEMORY;
(SAFEARRAY*)*Buffer = lpData;
}
if (!((SAFEARRAY*)*Buffer)->pvData)
return E_INVALIDARG;
// Do we have enough memory for this string right now?
if (*lOffSet + lSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
if (FAILED( hr = VB_GrowBuffer(Buffer, lSize) ) )
return hr;
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
__try {
memcpy(lPtr + *lOffSet, lData, lSize);
*lOffSet += lSize;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_INVALIDARG;
}
return S_OK;
}
HRESULT WINAPI VB_NewBuffer(SAFEARRAY **Buffer, long *lOffSet)
{
// Set up with a 20 byte msg at first
SAFEARRAY *lpData = NULL;
SAFEARRAYBOUND rgsabound[1];
// Let's create our SafeArray
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
rgsabound[0].cElements = INITIAL_BUFFER_SIZE; //Set the initial size
// Create this data
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
if (!lpData)
return E_OUTOFMEMORY;
(SAFEARRAY*)*Buffer = lpData;
*lOffSet = 0;
return S_OK;
}
HRESULT WINAPI VB_GrowBuffer(SAFEARRAY **Buffer, DWORD dwGrowSize)
{
SAFEARRAY *lpData = NULL;
SAFEARRAYBOUND rgsabound[1];
DWORD dwCurSize = 0;
if (!dwGrowSize)
return E_INVALIDARG;
if (!((SAFEARRAY*)*Buffer))
return E_INVALIDARG;
if (!((SAFEARRAY*)*Buffer)->pvData)
return E_INVALIDARG;
dwCurSize = ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements;
// Let's create a new SafeArray
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
rgsabound[0].cElements = dwCurSize + dwGrowSize; //Set the size
// Create this data
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
if (!lpData)
return E_OUTOFMEMORY;
__try {
memcpy(lpData->pvData, ((SAFEARRAY*)*Buffer)->pvData, dwCurSize);
SafeArrayDestroy((SAFEARRAY*)*Buffer);
(SAFEARRAY*)*Buffer = lpData;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_FAIL;
}
return S_OK;
}
HRESULT WINAPI VB_GetDataFromBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet)
{
// Simply copy the memory from the offset to the new data
if (!lData)
return E_INVALIDARG;
if (!lSize)
return E_INVALIDARG;
if (!(SAFEARRAY*)*Buffer)
return E_INVALIDARG;
if (!((SAFEARRAY*)*Buffer)->pvData)
return E_INVALIDARG;
if (*lOffSet + lSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
return E_INVALIDARG;
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
__try {
memcpy(lData, lPtr + *lOffSet, lSize);
*lOffSet += lSize;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_INVALIDARG;
}
return S_OK;
}
HRESULT WINAPI VB_GetStringFromBuffer(SAFEARRAY **Buffer, long *lOffSet, BSTR *sData)
{
DWORD dwStrLen = 0;
WCHAR *sNewString = NULL;
// Simply copy the memory from the offset to the new data
if (!(SAFEARRAY*)*Buffer)
return E_INVALIDARG;
if (!((SAFEARRAY*)*Buffer)->pvData)
return E_INVALIDARG;
if (*lOffSet + sizeof(DWORD) > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
return E_INVALIDARG;
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
__try {
// First read the size of the string
dwStrLen = *(DWORD*)(lPtr + *lOffSet);
*lOffSet += sizeof(DWORD);
if (*lOffSet + dwStrLen > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
return E_INVALIDARG;
sNewString = (WCHAR*)new BYTE[dwStrLen+2];
if (!sNewString)
return E_OUTOFMEMORY;
ZeroMemory(sNewString, dwStrLen+2);
memcpy(sNewString, lPtr + *lOffSet, dwStrLen);
*sData = SysAllocString(sNewString);
*lOffSet += (dwStrLen);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_INVALIDARG;
}
return S_OK;
}