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