Commit e5c82d3a authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

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

parent e9cc0744
...@@ -88,21 +88,20 @@ typedef struct PresentationDataHeader ...@@ -88,21 +88,20 @@ typedef struct PresentationDataHeader
typedef struct DataCacheEntry typedef struct DataCacheEntry
{ {
struct list entry; struct list entry;
/* format of this entry */ /* format of this entry */
FORMATETC fmtetc; FORMATETC fmtetc;
/* cached data */ /* cached data */
STGMEDIUM stgmedium; STGMEDIUM stgmedium;
/* /*
* This storage pointer is set through a call to * This storage pointer is set through a call to
* IPersistStorage_Load. This is where the visual * IPersistStorage_Load. This is where the visual
* representation of the object is stored. * representation of the object is stored.
*/ */
IStorage *storage; IStorage *storage;
/* connection ID */
DWORD id; DWORD id;
/* dirty flag */
BOOL dirty;
} DataCacheEntry; } DataCacheEntry;
/**************************************************************************** /****************************************************************************
...@@ -140,10 +139,12 @@ struct DataCache ...@@ -140,10 +139,12 @@ struct DataCache
IAdviseSink* sinkInterface; IAdviseSink* sinkInterface;
IStorage *presentationStorage; IStorage *presentationStorage;
/* list of cache entries */
struct list cache_list; struct list cache_list;
/* last id assigned to an entry */ /* last id assigned to an entry */
DWORD last_cache_id; DWORD last_cache_id;
/* dirty flag */
BOOL dirty;
}; };
typedef struct DataCache DataCache; typedef struct DataCache DataCache;
...@@ -257,6 +258,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc ...@@ -257,6 +258,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
(*cache_entry)->stgmedium.pUnkForRelease = NULL; (*cache_entry)->stgmedium.pUnkForRelease = NULL;
(*cache_entry)->storage = NULL; (*cache_entry)->storage = NULL;
(*cache_entry)->id = This->last_cache_id++; (*cache_entry)->id = This->last_cache_id++;
(*cache_entry)->dirty = TRUE;
list_add_tail(&This->cache_list, &(*cache_entry)->entry); list_add_tail(&This->cache_list, &(*cache_entry)->entry);
return S_OK; return S_OK;
} }
...@@ -557,6 +559,7 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm, ...@@ -557,6 +559,7 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
static HRESULT DataCacheEntry_SetData(DataCacheEntry *This, static HRESULT DataCacheEntry_SetData(DataCacheEntry *This,
STGMEDIUM *stgmedium, BOOL fRelease) STGMEDIUM *stgmedium, BOOL fRelease)
{ {
This->dirty = TRUE;
ReleaseStgMedium(&This->stgmedium); ReleaseStgMedium(&This->stgmedium);
if (fRelease) if (fRelease)
{ {
...@@ -1052,17 +1055,24 @@ static HRESULT WINAPI DataCache_GetClassID( ...@@ -1052,17 +1055,24 @@ static HRESULT WINAPI DataCache_GetClassID(
/************************************************************************ /************************************************************************
* DataCache_IsDirty (IPersistStorage) * 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. * See Windows documentation for more details on IPersistStorage methods.
*/ */
static HRESULT WINAPI DataCache_IsDirty( static HRESULT WINAPI DataCache_IsDirty(
IPersistStorage* iface) 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( ...@@ -1077,9 +1087,19 @@ static HRESULT WINAPI DataCache_InitNew(
IPersistStorage* iface, IPersistStorage* iface,
IStorage* pStg) 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( ...@@ -1148,6 +1168,7 @@ static HRESULT WINAPI DataCache_Load(
if (cache_entry->storage) IStorage_Release(cache_entry->storage); if (cache_entry->storage) IStorage_Release(cache_entry->storage);
cache_entry->storage = pStg; cache_entry->storage = pStg;
IStorage_AddRef(pStg); IStorage_AddRef(pStg);
cache_entry->dirty = FALSE;
} }
} }
...@@ -1158,6 +1179,8 @@ static HRESULT WINAPI DataCache_Load( ...@@ -1158,6 +1179,8 @@ static HRESULT WINAPI DataCache_Load(
CoTaskMemFree(elem.pwcsName); CoTaskMemFree(elem.pwcsName);
} }
This->dirty = FALSE;
IEnumSTATSTG_Release(pEnum); IEnumSTATSTG_Release(pEnum);
IStorage_AddRef(This->presentationStorage); IStorage_AddRef(This->presentationStorage);
...@@ -1179,21 +1202,37 @@ static HRESULT WINAPI DataCache_Save( ...@@ -1179,21 +1202,37 @@ static HRESULT WINAPI DataCache_Save(
IStorage* pStg, IStorage* pStg,
BOOL fSameAsLoad) 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) && dirty = This->dirty;
(this->presentationStorage!=NULL) ) if (!dirty)
{ {
return IStorage_CopyTo(this->presentationStorage, LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
0, {
NULL, dirty = cache_entry->dirty;
NULL, if (dirty)
pStg); 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( ...@@ -2060,6 +2099,8 @@ static DataCache* DataCache_Construct(
newObject->sinkInterface = 0; newObject->sinkInterface = 0;
newObject->presentationStorage = NULL; newObject->presentationStorage = NULL;
list_init(&newObject->cache_list); list_init(&newObject->cache_list);
newObject->last_cache_id = 1;
newObject->dirty = FALSE;
return newObject; return newObject;
} }
...@@ -1105,9 +1105,7 @@ static void test_data_cache(void) ...@@ -1105,9 +1105,7 @@ static void test_data_cache(void)
ok_ole_success(hr, "IPersistStorage_InitNew"); ok_ole_success(hr, "IPersistStorage_InitNew");
hr = IPersistStorage_IsDirty(pPS); hr = IPersistStorage_IsDirty(pPS);
todo_wine {
ok_ole_success(hr, "IPersistStorage_IsDirty"); ok_ole_success(hr, "IPersistStorage_IsDirty");
}
hr = IPersistStorage_GetClassID(pPS, &clsid); hr = IPersistStorage_GetClassID(pPS, &clsid);
ok_ole_success(hr, "IPersistStorage_GetClassID"); ok_ole_success(hr, "IPersistStorage_GetClassID");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment