[3/5] comctl32/dpa: Implement DPA_SaveStream() with tests

Nikolay Sivov bunglehead at gmail.com
Sun Sep 13 13:37:27 CDT 2009


Changelog:
    - Implement DPA_SaveStream() with tests

>From cd725abcf742f687b84a287f8671efc225b353b8 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Sun, 13 Sep 2009 02:54:50 +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..beab967 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;// + 1;
+
+    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..b8499d9 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);
+#endif
+
+    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