Rob Shearman : ole32: Add handling of the dirty state to the data cache and fix InitNew to not call Load .

Alexandre Julliard julliard at wine.codeweavers.com
Mon Dec 4 07:16:54 CST 2006


Module: wine
Branch: master
Commit: e5c82d3aa4f8f945eedefddecbdc3bbc3cd585e9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e5c82d3aa4f8f945eedefddecbdc3bbc3cd585e9

Author: Rob Shearman <rob at codeweavers.com>
Date:   Fri Dec  1 15:03:19 2006 +0000

ole32: Add handling of the dirty state to the data cache and fix InitNew to not call Load.

---

 dlls/ole32/datacache.c  |   89 ++++++++++++++++++++++++++++++++++-------------
 dlls/ole32/tests/ole2.c |    2 -
 2 files changed, 65 insertions(+), 26 deletions(-)

diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index 1d7a765..dba012c 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -88,21 +88,20 @@ typedef struct PresentationDataHeader
 typedef struct DataCacheEntry
 {
   struct list entry;
-
   /* format of this entry */
   FORMATETC fmtetc;
-
   /* cached data */
   STGMEDIUM stgmedium;
-
   /*
    * This storage pointer is set through a call to
    * IPersistStorage_Load. This is where the visual
    * representation of the object is stored.
    */
   IStorage *storage;
-
+  /* connection ID */
   DWORD id;
+  /* dirty flag */
+  BOOL dirty;
 } DataCacheEntry;
 
 /****************************************************************************
@@ -140,10 +139,12 @@ struct DataCache
   IAdviseSink* sinkInterface;
   IStorage *presentationStorage;
 
+  /* list of cache entries */
   struct list cache_list;
-
   /* last id assigned to an entry */
   DWORD last_cache_id;
+  /* dirty flag */
+  BOOL dirty;
 };
 
 typedef struct DataCache DataCache;
@@ -257,6 +258,7 @@ static HRESULT DataCache_CreateEntry(Dat
     (*cache_entry)->stgmedium.pUnkForRelease = NULL;
     (*cache_entry)->storage = NULL;
     (*cache_entry)->id = This->last_cache_id++;
+    (*cache_entry)->dirty = TRUE;
     list_add_tail(&This->cache_list, &(*cache_entry)->entry);
     return S_OK;
 }
@@ -557,6 +559,7 @@ static HRESULT copy_stg_medium(CLIPFORMA
 static HRESULT DataCacheEntry_SetData(DataCacheEntry *This,
                                       STGMEDIUM *stgmedium, BOOL fRelease)
 {
+    This->dirty = TRUE;
     ReleaseStgMedium(&This->stgmedium);
     if (fRelease)
     {
@@ -1052,17 +1055,24 @@ static HRESULT WINAPI DataCache_GetClass
 /************************************************************************
  * DataCache_IsDirty (IPersistStorage)
  *
- * Until we actually connect to a running object and retrieve new
- * information to it, we never get dirty.
- *
  * See Windows documentation for more details on IPersistStorage methods.
  */
 static HRESULT WINAPI DataCache_IsDirty(
             IPersistStorage* iface)
 {
-  TRACE("(%p)\n", iface);
+    DataCache *This = impl_from_IPersistStorage(iface);
+    DataCacheEntry *cache_entry;
+
+    TRACE("(%p)\n", iface);
 
-  return S_FALSE;
+    if (This->dirty)
+        return S_OK;
+
+    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
+        if (cache_entry->dirty)
+            return S_OK;
+
+    return S_FALSE;
 }
 
 /************************************************************************
@@ -1077,9 +1087,19 @@ static HRESULT WINAPI DataCache_InitNew(
             IPersistStorage* iface,
 	    IStorage*        pStg)
 {
-  TRACE("(%p, %p)\n", iface, pStg);
+    DataCache *This = impl_from_IPersistStorage(iface);
+
+    TRACE("(%p, %p)\n", iface, pStg);
+
+    if (This->presentationStorage != NULL)
+        IStorage_Release(This->presentationStorage);
+
+    This->presentationStorage = pStg;
 
-  return IPersistStorage_Load(iface, pStg);
+    IStorage_AddRef(This->presentationStorage);
+    This->dirty = TRUE;
+
+    return S_OK;
 }
 
 /************************************************************************
@@ -1148,6 +1168,7 @@ static HRESULT WINAPI DataCache_Load(
                         if (cache_entry->storage) IStorage_Release(cache_entry->storage);
                         cache_entry->storage = pStg;
                         IStorage_AddRef(pStg);
+                        cache_entry->dirty = FALSE;
                     }
 		}
 
@@ -1158,6 +1179,8 @@ static HRESULT WINAPI DataCache_Load(
 	CoTaskMemFree(elem.pwcsName);
     }
 
+    This->dirty = FALSE;
+
     IEnumSTATSTG_Release(pEnum);
 
     IStorage_AddRef(This->presentationStorage);
@@ -1179,21 +1202,37 @@ static HRESULT WINAPI DataCache_Save(
 	    IStorage*        pStg,
 	    BOOL             fSameAsLoad)
 {
-  DataCache *this = impl_from_IPersistStorage(iface);
+    DataCache *This = impl_from_IPersistStorage(iface);
+    DataCacheEntry *cache_entry;
+    BOOL dirty = FALSE;
 
-  TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
+    TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
 
-  if ( (!fSameAsLoad) &&
-       (this->presentationStorage!=NULL) )
-  {
-    return IStorage_CopyTo(this->presentationStorage,
-			   0,
-			   NULL,
-			   NULL,
-			   pStg);
-  }
+    dirty = This->dirty;
+    if (!dirty)
+    {
+        LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
+        {
+            dirty = cache_entry->dirty;
+            if (dirty)
+                break;
+        }
+    }
 
-  return S_OK;
+    /* this is a shortcut if nothing changed */
+    if (!dirty && !fSameAsLoad && This->presentationStorage)
+    {
+        return IStorage_CopyTo(This->presentationStorage, 0, NULL, NULL, pStg);
+    }
+
+    LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
+    {
+        /* FIXME: actually do the save here */
+        cache_entry->dirty = FALSE;
+    }
+
+    This->dirty = FALSE;
+    return S_OK;
 }
 
 /************************************************************************
@@ -2060,6 +2099,8 @@ static DataCache* DataCache_Construct(
   newObject->sinkInterface = 0;
   newObject->presentationStorage = NULL;
   list_init(&newObject->cache_list);
+  newObject->last_cache_id = 1;
+  newObject->dirty = FALSE;
 
   return newObject;
 }
diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c
index 8c9a8b0..18a5a46 100644
--- a/dlls/ole32/tests/ole2.c
+++ b/dlls/ole32/tests/ole2.c
@@ -1105,9 +1105,7 @@ static void test_data_cache(void)
     ok_ole_success(hr, "IPersistStorage_InitNew");
 
     hr = IPersistStorage_IsDirty(pPS);
-    todo_wine {
     ok_ole_success(hr, "IPersistStorage_IsDirty");
-    }
 
     hr = IPersistStorage_GetClassID(pPS, &clsid);
     ok_ole_success(hr, "IPersistStorage_GetClassID");




More information about the wine-cvs mailing list