[Wine-patches] [eter-2.1 3/4] ole32: Split the data loading into a couple of helpers. (eterbug #10620)

Dmitry Timoshkov dtimoshkov на etersoft.ru
Пн Июл 6 09:37:32 MSK 2015


(cherry picked from commit d864387aaa5cfc93eba39824fb22e574e7df6773)
---
 dlls/ole32/datacache.c | 157 +++++++++++++++++++++++++++----------------------
 1 file changed, 88 insertions(+), 69 deletions(-)

diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index 523c7ae..598ef43 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -88,6 +88,12 @@ typedef struct PresentationDataHeader
   DWORD dwSize;
 } PresentationDataHeader;
 
+enum stream_type
+{
+    no_stream,
+    pres_stream,
+};
+
 typedef struct DataCacheEntry
 {
   struct list entry;
@@ -103,6 +109,7 @@ typedef struct DataCacheEntry
    * representation of the object is stored.
    */
   IStream *stream;
+  enum stream_type stream_type;
   /* connection ID */
   DWORD id;
   /* dirty flag */
@@ -315,6 +322,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
     (*cache_entry)->stgmedium.tymed = TYMED_NULL;
     (*cache_entry)->stgmedium.pUnkForRelease = NULL;
     (*cache_entry)->stream = NULL;
+    (*cache_entry)->stream_type = no_stream;
     (*cache_entry)->id = This->last_cache_id++;
     (*cache_entry)->dirty = TRUE;
     (*cache_entry)->stream_number = -1;
@@ -1209,6 +1217,78 @@ static HRESULT WINAPI DataCache_InitNew(
     return S_OK;
 }
 
+
+static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, IStream *stm,
+                                enum stream_type type )
+{
+    DataCacheEntry *cache_entry;
+    HRESULT hr = S_OK;
+
+    TRACE( "loading entry with formatetc: %s\n", debugstr_formatetc( fmt ) );
+
+    cache_entry = DataCache_GetEntryForFormatEtc( This, fmt );
+    if (!cache_entry)
+        hr = DataCache_CreateEntry( This, fmt, &cache_entry );
+    if (SUCCEEDED( hr ))
+    {
+        DataCacheEntry_DiscardData( cache_entry );
+        if (cache_entry->stream) IStream_Release( cache_entry->stream );
+        cache_entry->stream = stm;
+        IStream_AddRef( stm );
+        cache_entry->stream_type = type;
+        cache_entry->dirty = FALSE;
+    }
+    return hr;
+}
+
+static HRESULT parse_pres_streams( DataCache *This, IStorage *stg )
+{
+    HRESULT hr;
+    IEnumSTATSTG *stat_enum;
+    STATSTG stat;
+    IStream *stm;
+    PresentationDataHeader header;
+    ULONG actual_read;
+    CLIPFORMAT clipformat;
+    FORMATETC fmtetc;
+
+    hr = IStorage_EnumElements( stg, 0, NULL, 0, &stat_enum );
+    if (FAILED( hr )) return hr;
+
+    while ((hr = IEnumSTATSTG_Next( stat_enum, 1, &stat, NULL )) == S_OK)
+    {
+        if (DataCache_IsPresentationStream( &stat ))
+        {
+            hr = IStorage_OpenStream( stg, stat.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
+                                      0, &stm );
+            if (SUCCEEDED( hr ))
+            {
+                hr = read_clipformat( stm, &clipformat );
+
+                if (hr == S_OK)
+                    hr = IStream_Read( stm, &header, sizeof(header), &actual_read );
+
+                if (hr == S_OK && actual_read == sizeof(header))
+                {
+                    fmtetc.cfFormat = clipformat;
+                    fmtetc.ptd = NULL; /* FIXME */
+                    fmtetc.dwAspect = header.dvAspect;
+                    fmtetc.lindex = header.lindex;
+                    fmtetc.tymed = header.tymed;
+
+                    add_cache_entry( This, &fmtetc, stm, pres_stream );
+                }
+                IStream_Release( stm );
+            }
+        }
+        CoTaskMemFree( stat.pwcsName );
+    }
+    IEnumSTATSTG_Release( stat_enum );
+
+    return S_OK;
+}
+
+
 /************************************************************************
  * DataCache_Load (IPersistStorage)
  *
@@ -1217,86 +1297,25 @@ static HRESULT WINAPI DataCache_InitNew(
  * and it will load the presentation information when the
  * IDataObject_GetData or IViewObject2_Draw methods are called.
  */
-static HRESULT WINAPI DataCache_Load(
-            IPersistStorage* iface,
-	    IStorage*        pStg)
+static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
 {
     DataCache *This = impl_from_IPersistStorage(iface);
-    STATSTG elem;
-    IEnumSTATSTG *pEnum;
     HRESULT hr;
 
     TRACE("(%p, %p)\n", iface, pStg);
 
-    if (This->presentationStorage != NULL)
-      IStorage_Release(This->presentationStorage);
-
-    This->presentationStorage = pStg;
+    IPersistStorage_HandsOffStorage( iface );
 
-    hr = IStorage_EnumElements(pStg, 0, NULL, 0, &pEnum);
-    if (FAILED(hr)) return hr;
+    hr = parse_pres_streams( This, pStg );
 
-    while ((hr = IEnumSTATSTG_Next(pEnum, 1, &elem, NULL)) == S_OK)
+    if (SUCCEEDED( hr ))
     {
-	if (DataCache_IsPresentationStream(&elem))
-	{
-	    IStream *pStm;
-
-	    hr = IStorage_OpenStream(This->presentationStorage, elem.pwcsName,
-				     NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0,
-				     &pStm);
-	    if (SUCCEEDED(hr))
-	    {
-                PresentationDataHeader header;
-                ULONG actual_read;
-                CLIPFORMAT clipformat;
-
-                hr = read_clipformat(pStm, &clipformat);
-
-                if (hr == S_OK)
-                    hr = IStream_Read(pStm, &header, sizeof(header),
-                                      &actual_read);
-
-		/* can't use SUCCEEDED(hr): S_FALSE counts as an error */
-		if (hr == S_OK && actual_read == sizeof(header))
-		{
-		    DataCacheEntry *cache_entry;
-		    FORMATETC fmtetc;
-
-		    fmtetc.cfFormat = clipformat;
-		    fmtetc.ptd = NULL; /* FIXME */
-		    fmtetc.dwAspect = header.dvAspect;
-		    fmtetc.lindex = header.lindex;
-		    fmtetc.tymed = header.tymed;
-
-                    TRACE("loading entry with formatetc: %s\n", debugstr_formatetc(&fmtetc));
-
-                    cache_entry = DataCache_GetEntryForFormatEtc(This, &fmtetc);
-                    if (!cache_entry)
-                        hr = DataCache_CreateEntry(This, &fmtetc, &cache_entry);
-                    if (SUCCEEDED(hr))
-                    {
-                        DataCacheEntry_DiscardData(cache_entry);
-                        if (cache_entry->stream) IStream_Release(cache_entry->stream);
-                        cache_entry->stream = pStm;
-                        IStream_AddRef(pStm);
-                        cache_entry->dirty = FALSE;
-                    }
-		}
-
-		IStream_Release(pStm);
-	    }
-	}
-
-	CoTaskMemFree(elem.pwcsName);
+        This->dirty = FALSE;
+        This->presentationStorage = pStg;
+        IStorage_AddRef( This->presentationStorage );
     }
 
-    This->dirty = FALSE;
-
-    IEnumSTATSTG_Release(pEnum);
-
-    IStorage_AddRef(This->presentationStorage);
-    return S_OK;
+    return hr;
 }
 
 /************************************************************************
-- 
2.4.5

-- 
Dmitry.


Подробная информация о списке рассылки Wine-patches