[3/5] comctl32/dpa: Implement DPA_SaveStream() with tests (try2)
Nikolay Sivov
bunglehead at gmail.com
Mon Sep 14 02:22:33 CDT 2009
Please use this patch, next patches (4,5) still apply cleanly on top
of this one.
Changelog:
- try2: cpp comments removed, if (0) used to comment tests
- Implement DPA_SaveStream() with tests
>From dc8b5eb77dd8466ef0ddabe63c096da7d7a4325f Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Mon, 14 Sep 2009 11:16:06 +0400
Subject: Implement DPA_SaveStream() with tests
---
dlls/comctl32/dpa.c | 79 +++++++++++++++++++++++++++++++++++------
dlls/comctl32/tests/dpa.c | 84 +++++++++++++++++++++++++++++++++++++--------
2 files changed, 136 insertions(+), 27 deletions(-)
diff --git a/dlls/comctl32/dpa.c b/dlls/comctl32/dpa.c
index ca28282..722e2fa 100644
--- a/dlls/comctl32/dpa.c
+++ b/dlls/comctl32/dpa.c
@@ -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;
+
+ TRACE ("hDpa=%p saveProc=%p pStream=%p pData=%p\n",
+ hDpa, saveProc, pStream, pData);
+
+ 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);
- FIXME ("hDpa=%p loadProc=%p pStream=%p pData=%p\n",
- hDpa, loadProc, pStream, pData);
+ position.QuadPart = curr_pos.QuadPart;
+ IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL);
- return E_FAIL;
+ return hr;
}
diff --git a/dlls/comctl32/tests/dpa.c b/dlls/comctl32/tests/dpa.c
index 54e8d0e..1ba4c67 100644
--- a/dlls/comctl32/tests/dpa.c
+++ b/dlls/comctl32/tests/dpa.c
@@ -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();
}
--
1.5.6.5
More information about the wine-patches
mailing list