comctl32/dpa: Implement DPA_SaveStream() with tests.

This commit is contained in:
Nikolay Sivov 2009-09-14 11:16:06 +04:00 committed by Alexandre Julliard
parent c8f8e5da11
commit c1513c6bde
2 changed files with 136 additions and 27 deletions

View File

@ -73,8 +73,8 @@ typedef struct _STREAMDATA
* pData [I] pointer to callback data
*
* RETURNS
* Success: TRUE
* Failure: FALSE
* Success: S_OK, S_FALSE - partial success
* Failure: HRESULT error code
*
* NOTES
* No more information available yet!
@ -91,7 +91,7 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc,
HDPA hDpa;
PVOID *ptr;
FIXME ("phDpa=%p loadProc=%p pStream=%p pData=%p\n",
TRACE ("phDpa=%p loadProc=%p pStream=%p pData=%p\n",
phDpa, loadProc, pStream, pData);
if (!phDpa || !loadProc || !pStream)
@ -110,7 +110,7 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc,
if (errCode != S_OK)
return errCode;
FIXME ("dwSize=%u dwData2=%u dwItems=%u\n",
TRACE ("dwSize=%u dwData2=%u dwItems=%u\n",
streamData.dwSize, streamData.dwData2, streamData.dwItems);
if (ulRead < sizeof(STREAMDATA) ||
@ -150,7 +150,7 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc,
/* store the handle to the dpa */
*phDpa = hDpa;
FIXME ("new hDpa=%p, errorcode=%x\n", hDpa, errCode);
TRACE ("new hDpa=%p, errorcode=%x\n", hDpa, errCode);
return errCode;
}
@ -163,25 +163,80 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc,
*
* PARAMS
* hDpa [I] handle to a dynamic pointer array
* loadProc [I] pointer to a callback function
* saveProc [I] pointer to a callback function
* pStream [I] pointer to a stream
* pData [I] pointer to callback data
*
* RETURNS
* Success: TRUE
* Failure: FALSE
* Success: S_OK, S_FALSE - partial success
* Failure: HRESULT error code
*
* NOTES
* No more information available yet!
*/
HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, PFNDPASTREAM loadProc,
HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, PFNDPASTREAM saveProc,
IStream *pStream, LPVOID pData)
{
LARGE_INTEGER position;
ULARGE_INTEGER initial_pos, curr_pos;
STREAMDATA streamData;
DPASTREAMINFO streamInfo;
HRESULT hr;
PVOID *ptr;
FIXME ("hDpa=%p loadProc=%p pStream=%p pData=%p\n",
hDpa, loadProc, pStream, pData);
TRACE ("hDpa=%p saveProc=%p pStream=%p pData=%p\n",
hDpa, saveProc, pStream, pData);
return E_FAIL;
if (!hDpa || !saveProc || !pStream) return E_INVALIDARG;
/* save initial position to write header after completion */
position.QuadPart = 0;
hr = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &initial_pos);
if (hr != S_OK)
return hr;
/* write empty header */
streamData.dwSize = sizeof(streamData);
streamData.dwData2 = 1;
streamData.dwItems = 0;
hr = IStream_Write (pStream, &streamData, sizeof(streamData), NULL);
if (hr != S_OK) {
position.QuadPart = initial_pos.QuadPart;
IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL);
return hr;
}
/* no items - we're done */
if (hDpa->nItemCount == 0) return S_OK;
ptr = hDpa->ptrs;
for (streamInfo.iPos = 0; streamInfo.iPos < hDpa->nItemCount; streamInfo.iPos++) {
streamInfo.pvItem = *ptr;
hr = (saveProc)(&streamInfo, pStream, pData);
if (hr != S_OK) {
hr = S_FALSE;
break;
}
ptr++;
}
/* write updated header */
position.QuadPart = 0;
IStream_Seek (pStream, position, STREAM_SEEK_CUR, &curr_pos);
streamData.dwSize = curr_pos.QuadPart - initial_pos.QuadPart;
streamData.dwData2 = 1;
streamData.dwItems = streamInfo.iPos;
position.QuadPart = initial_pos.QuadPart;
IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL);
IStream_Write (pStream, &streamData, sizeof(streamData), NULL);
position.QuadPart = curr_pos.QuadPart;
IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL);
return hr;
}

View File

@ -142,12 +142,12 @@ static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp)
static HRESULT CALLBACK CB_Save(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp)
{
HRESULT hRes;
ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp);
hRes = IStream_Write(pStm, &pInfo->iPos, sizeof(INT), NULL);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
hRes = IStream_Write(pStm, &pInfo->pvItem, sizeof(PVOID), NULL);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
return S_OK;
}
@ -159,10 +159,10 @@ static HRESULT CALLBACK CB_Load(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp)
iOldPos = pInfo->iPos;
ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp);
hRes = IStream_Read(pStm, &pInfo->iPos, sizeof(INT), NULL);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
ok(pInfo->iPos == iOldPos, "iPos=%d iOldPos=%d\n", pInfo->iPos, iOldPos);
hRes = IStream_Read(pStm, &pInfo->pvItem, sizeof(PVOID), NULL);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
return S_OK;
}
@ -643,6 +643,62 @@ static void test_DPA_LoadStream(void)
CoUninitialize();
}
static void test_DPA_SaveStream(void)
{
HDPA dpa;
static const WCHAR szStg[] = { 'S','t','g',0 };
IStorage* pStg = NULL;
IStream* pStm = NULL;
DWORD dwMode;
HRESULT hRes;
ULONG ret;
if(!pDPA_SaveStream)
{
win_skip("DPA_SaveStream() not available. Skipping stream tests.\n");
return;
}
hRes = CoInitialize(NULL);
if (hRes != S_OK)
{
ok(0, "hResult: %d\n", hRes);
return;
}
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
expect(S_OK, hRes);
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
expect(S_OK, hRes);
dpa = pDPA_Create(0);
/* simple parameter check */
hRes = pDPA_SaveStream(dpa, NULL, pStm, NULL);
ok(hRes == E_INVALIDARG ||
broken(hRes == S_OK) /* XP and below */, "Wrong result, %d\n", hRes);
if (0) {
/* crashes on XP */
hRes = pDPA_SaveStream(NULL, CB_Save, pStm, NULL);
expect(E_INVALIDARG, hRes);
hRes = pDPA_SaveStream(dpa, CB_Save, NULL, NULL);
expect(E_INVALIDARG, hRes);
}
pDPA_Destroy(dpa);
ret = IStream_Release(pStm);
ok(!ret, "ret=%d\n", ret);
ret = IStorage_Release(pStg);
ok(!ret, "ret=%d\n", ret);
CoUninitialize();
}
static void test_dpa_stream(void)
{
HDPA dpa;
@ -679,25 +735,22 @@ static void test_dpa_stream(void)
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
hRes = pDPA_SaveStream(dpa, CB_Save, pStm, (void*)0xdeadbeef);
todo_wine ok(hRes == S_OK, "hRes=0x%x\n", hRes);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
pDPA_Destroy(dpa);
liZero.QuadPart = 0;
hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
expect(S_OK, hRes);
hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef);
todo_wine
{
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
rc = CheckDPA(dpa, 0x123456, &dw);
ok(rc, "dw=0x%x\n", dw);
}
expect(S_OK, hRes);
rc = CheckDPA(dpa, 0x123456, &dw);
ok(rc, "dw=0x%x\n", dw);
pDPA_Destroy(dpa);
ret = IStream_Release(pStm);
@ -726,5 +779,6 @@ START_TEST(dpa)
test_DPA_EnumCallback();
test_DPA_DestroyCallback();
test_DPA_LoadStream();
test_DPA_SaveStream();
test_dpa_stream();
}