Commit ee6856d8 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

ole32: Don't use IEnumSTATSTG to search for elements of storages.

We use it to do a linear search of a binary tree, which is overkill. Replace it with a simple binary search.
parent dce1ec06
...@@ -198,6 +198,11 @@ static LONG propertyNameCmp( ...@@ -198,6 +198,11 @@ static LONG propertyNameCmp(
const OLECHAR *newProperty, const OLECHAR *newProperty,
const OLECHAR *currentProperty); const OLECHAR *currentProperty);
static ULONG findElement(
StorageImpl *storage,
ULONG storageEntry,
const OLECHAR *name,
StgProperty *data);
/*********************************************************************** /***********************************************************************
* Declaration of miscellaneous functions... * Declaration of miscellaneous functions...
...@@ -244,8 +249,6 @@ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageImpl* This, ULONG fir ...@@ -244,8 +249,6 @@ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageImpl* This, ULONG fir
static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This); static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This);
static void IEnumSTATSTGImpl_PushSearchNode(IEnumSTATSTGImpl* This, ULONG nodeToPush); static void IEnumSTATSTGImpl_PushSearchNode(IEnumSTATSTGImpl* This, ULONG nodeToPush);
static ULONG IEnumSTATSTGImpl_PopSearchNode(IEnumSTATSTGImpl* This, BOOL remove); static ULONG IEnumSTATSTGImpl_PopSearchNode(IEnumSTATSTGImpl* This, BOOL remove);
static ULONG IEnumSTATSTGImpl_FindProperty(IEnumSTATSTGImpl* This, const OLECHAR* lpszPropName,
StgProperty* buffer);
static INT IEnumSTATSTGImpl_FindParentProperty(IEnumSTATSTGImpl *This, ULONG childProperty, static INT IEnumSTATSTGImpl_FindParentProperty(IEnumSTATSTGImpl *This, ULONG childProperty,
StgProperty *currentProperty, ULONG *propertyId); StgProperty *currentProperty, ULONG *propertyId);
...@@ -387,7 +390,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( ...@@ -387,7 +390,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream(
IStream** ppstm) /* [out] */ IStream** ppstm) /* [out] */
{ {
StorageBaseImpl *This = (StorageBaseImpl *)iface; StorageBaseImpl *This = (StorageBaseImpl *)iface;
IEnumSTATSTGImpl* propertyEnumeration;
StgStreamImpl* newStream; StgStreamImpl* newStream;
StgProperty currentProperty; StgProperty currentProperty;
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
...@@ -433,26 +435,15 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( ...@@ -433,26 +435,15 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream(
} }
/* /*
* Create a property enumeration to search the properties * Search for the element with the given name
*/ */
propertyEnumeration = IEnumSTATSTGImpl_Construct( foundPropertyIndex = findElement(
This->ancestorStorage, This->ancestorStorage,
This->rootPropertySetIndex); This->rootPropertySetIndex,
/*
* Search the enumeration for the property with the given name
*/
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(
propertyEnumeration,
pwcsName, pwcsName,
&currentProperty); &currentProperty);
/* /*
* Delete the property enumeration since we don't need it anymore
*/
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
/*
* If it was found, construct the stream object and return a pointer to it. * If it was found, construct the stream object and return a pointer to it.
*/ */
if ( (foundPropertyIndex!=PROPERTY_NULL) && if ( (foundPropertyIndex!=PROPERTY_NULL) &&
...@@ -502,7 +493,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( ...@@ -502,7 +493,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage(
{ {
StorageBaseImpl *This = (StorageBaseImpl *)iface; StorageBaseImpl *This = (StorageBaseImpl *)iface;
StorageInternalImpl* newStorage; StorageInternalImpl* newStorage;
IEnumSTATSTGImpl* propertyEnumeration;
StgProperty currentProperty; StgProperty currentProperty;
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
HRESULT res = STG_E_UNKNOWN; HRESULT res = STG_E_UNKNOWN;
...@@ -555,17 +545,12 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( ...@@ -555,17 +545,12 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage(
*ppstg = NULL; *ppstg = NULL;
propertyEnumeration = IEnumSTATSTGImpl_Construct( foundPropertyIndex = findElement(
This->ancestorStorage, This->ancestorStorage,
This->rootPropertySetIndex); This->rootPropertySetIndex,
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(
propertyEnumeration,
pwcsName, pwcsName,
&currentProperty); &currentProperty);
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
if ( (foundPropertyIndex!=PROPERTY_NULL) && if ( (foundPropertyIndex!=PROPERTY_NULL) &&
(currentProperty.propertyType==PROPTYPE_STORAGE) ) (currentProperty.propertyType==PROPTYPE_STORAGE) )
{ {
...@@ -708,39 +693,32 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement( ...@@ -708,39 +693,32 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement(
const OLECHAR* pwcsNewName) /* [in] */ const OLECHAR* pwcsNewName) /* [in] */
{ {
StorageBaseImpl *This = (StorageBaseImpl *)iface; StorageBaseImpl *This = (StorageBaseImpl *)iface;
IEnumSTATSTGImpl* propertyEnumeration;
StgProperty currentProperty; StgProperty currentProperty;
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
TRACE("(%p, %s, %s)\n", TRACE("(%p, %s, %s)\n",
iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName)); iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName));
propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, foundPropertyIndex = findElement(This->ancestorStorage,
This->rootPropertySetIndex); This->rootPropertySetIndex,
pwcsNewName,
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, &currentProperty);
pwcsNewName,
&currentProperty);
if (foundPropertyIndex != PROPERTY_NULL) if (foundPropertyIndex != PROPERTY_NULL)
{ {
/* /*
* There is already a property with the new name * There is already a property with the new name
*/ */
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
return STG_E_FILEALREADYEXISTS; return STG_E_FILEALREADYEXISTS;
} }
IEnumSTATSTG_Reset((IEnumSTATSTG*)propertyEnumeration);
/* /*
* Search the enumeration for the old property name * Search for the old element name
*/ */
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, foundPropertyIndex = findElement(This->ancestorStorage,
pwcsOldName, This->rootPropertySetIndex,
&currentProperty); pwcsOldName,
&currentProperty);
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
if (foundPropertyIndex != PROPERTY_NULL) if (foundPropertyIndex != PROPERTY_NULL)
{ {
...@@ -855,7 +833,6 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( ...@@ -855,7 +833,6 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream(
IStream** ppstm) /* [out] */ IStream** ppstm) /* [out] */
{ {
StorageBaseImpl *This = (StorageBaseImpl *)iface; StorageBaseImpl *This = (StorageBaseImpl *)iface;
IEnumSTATSTGImpl* propertyEnumeration;
StgStreamImpl* newStream; StgStreamImpl* newStream;
StgProperty currentProperty, newStreamProperty; StgProperty currentProperty, newStreamProperty;
ULONG foundPropertyIndex, newPropertyIndex; ULONG foundPropertyIndex, newPropertyIndex;
...@@ -904,14 +881,10 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( ...@@ -904,14 +881,10 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream(
*ppstm = 0; *ppstm = 0;
propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, foundPropertyIndex = findElement(This->ancestorStorage,
This->rootPropertySetIndex); This->rootPropertySetIndex,
pwcsName,
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, &currentProperty);
pwcsName,
&currentProperty);
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
if (foundPropertyIndex != PROPERTY_NULL) if (foundPropertyIndex != PROPERTY_NULL)
{ {
...@@ -1068,7 +1041,6 @@ static HRESULT WINAPI StorageImpl_CreateStorage( ...@@ -1068,7 +1041,6 @@ static HRESULT WINAPI StorageImpl_CreateStorage(
{ {
StorageImpl* const This=(StorageImpl*)iface; StorageImpl* const This=(StorageImpl*)iface;
IEnumSTATSTGImpl *propertyEnumeration;
StgProperty currentProperty; StgProperty currentProperty;
StgProperty newProperty; StgProperty newProperty;
ULONG foundPropertyIndex; ULONG foundPropertyIndex;
...@@ -1103,16 +1075,10 @@ static HRESULT WINAPI StorageImpl_CreateStorage( ...@@ -1103,16 +1075,10 @@ static HRESULT WINAPI StorageImpl_CreateStorage(
return STG_E_ACCESSDENIED; return STG_E_ACCESSDENIED;
} }
/* foundPropertyIndex = findElement(This->base.ancestorStorage,
* Create a property enumeration and search the properties This->base.rootPropertySetIndex,
*/ pwcsName,
propertyEnumeration = IEnumSTATSTGImpl_Construct( This->base.ancestorStorage, &currentProperty);
This->base.rootPropertySetIndex);
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,
pwcsName,
&currentProperty);
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
if (foundPropertyIndex != PROPERTY_NULL) if (foundPropertyIndex != PROPERTY_NULL)
{ {
...@@ -1440,6 +1406,44 @@ static void updatePropertyChain( ...@@ -1440,6 +1406,44 @@ static void updatePropertyChain(
} }
} }
/****************************************************************************
*
* Internal Method
*
* Find and read the element of a storage with the given name.
*/
static ULONG findElement(StorageImpl *storage, ULONG storageEntry,
const OLECHAR *name, StgProperty *data)
{
ULONG currentEntry;
/* Read the storage entry to find the root of the tree. */
StorageImpl_ReadProperty(storage, storageEntry, data);
currentEntry = data->dirProperty;
while (currentEntry != PROPERTY_NULL)
{
LONG cmp;
StorageImpl_ReadProperty(storage, currentEntry, data);
cmp = propertyNameCmp(name, data->name);
if (cmp == 0)
/* found it */
break;
else if (cmp < 0)
currentEntry = data->leftChild;
else if (cmp > 0)
currentEntry = data->rightChild;
}
return currentEntry;
}
/************************************************************************* /*************************************************************************
* CopyTo (IStorage) * CopyTo (IStorage)
...@@ -1697,7 +1701,6 @@ static HRESULT WINAPI StorageImpl_DestroyElement( ...@@ -1697,7 +1701,6 @@ static HRESULT WINAPI StorageImpl_DestroyElement(
{ {
StorageImpl* const This=(StorageImpl*)iface; StorageImpl* const This=(StorageImpl*)iface;
IEnumSTATSTGImpl* propertyEnumeration;
HRESULT hr = S_OK; HRESULT hr = S_OK;
BOOL res; BOOL res;
StgProperty propertyToDelete; StgProperty propertyToDelete;
...@@ -1715,17 +1718,12 @@ static HRESULT WINAPI StorageImpl_DestroyElement( ...@@ -1715,17 +1718,12 @@ static HRESULT WINAPI StorageImpl_DestroyElement(
if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ ) if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ )
return STG_E_ACCESSDENIED; return STG_E_ACCESSDENIED;
propertyEnumeration = IEnumSTATSTGImpl_Construct( foundPropertyIndexToDelete = findElement(
This->base.ancestorStorage, This->base.ancestorStorage,
This->base.rootPropertySetIndex); This->base.rootPropertySetIndex,
foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty(
propertyEnumeration,
pwcsName, pwcsName,
&propertyToDelete); &propertyToDelete);
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
if ( foundPropertyIndexToDelete == PROPERTY_NULL ) if ( foundPropertyIndexToDelete == PROPERTY_NULL )
{ {
return STG_E_FILENOTFOUND; return STG_E_FILENOTFOUND;
...@@ -3973,49 +3971,6 @@ static INT IEnumSTATSTGImpl_FindParentProperty( ...@@ -3973,49 +3971,6 @@ static INT IEnumSTATSTGImpl_FindParentProperty(
return PROPERTY_NULL; return PROPERTY_NULL;
} }
static ULONG IEnumSTATSTGImpl_FindProperty(
IEnumSTATSTGImpl* This,
const OLECHAR* lpszPropName,
StgProperty* currentProperty)
{
ULONG currentSearchNode;
/*
* Start with the node at the top of the stack.
*/
currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE);
while (currentSearchNode!=PROPERTY_NULL)
{
/*
* Remove the top node from the stack
*/
IEnumSTATSTGImpl_PopSearchNode(This, TRUE);
/*
* Read the property from the storage.
*/
StorageImpl_ReadProperty(This->parentStorage,
currentSearchNode,
currentProperty);
if (propertyNameCmp(currentProperty->name, lpszPropName) == 0)
return currentSearchNode;
/*
* Push the next search node in the search stack.
*/
IEnumSTATSTGImpl_PushSearchNode(This, currentProperty->rightChild);
/*
* continue the iteration.
*/
currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE);
}
return PROPERTY_NULL;
}
static void IEnumSTATSTGImpl_PushSearchNode( static void IEnumSTATSTGImpl_PushSearchNode(
IEnumSTATSTGImpl* This, IEnumSTATSTGImpl* This,
ULONG nodeToPush) ULONG nodeToPush)
......
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