From 344701e9e5b1b962881d571b7aeeaf45039bcfa5 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Fri, 23 Oct 2009 13:57:42 -0500 Subject: [PATCH 3/3] 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. --- dlls/ole32/storage32.c | 181 ++++++++++++++++++------------------------------ 1 files changed, 68 insertions(+), 113 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 819f20b..ca2287f 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -198,6 +198,11 @@ static LONG propertyNameCmp( const OLECHAR *newProperty, const OLECHAR *currentProperty); +static ULONG findElement( + StorageImpl *storage, + ULONG storageEntry, + const OLECHAR *name, + StgProperty *data); /*********************************************************************** * Declaration of miscellaneous functions... @@ -244,8 +249,6 @@ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageImpl* This, ULONG fir static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This); static void IEnumSTATSTGImpl_PushSearchNode(IEnumSTATSTGImpl* This, ULONG nodeToPush); 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, StgProperty *currentProperty, ULONG *propertyId); @@ -387,7 +390,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( IStream** ppstm) /* [out] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - IEnumSTATSTGImpl* propertyEnumeration; StgStreamImpl* newStream; StgProperty currentProperty; ULONG foundPropertyIndex; @@ -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->rootPropertySetIndex); - - /* - * Search the enumeration for the property with the given name - */ - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty( - propertyEnumeration, + This->rootPropertySetIndex, pwcsName, ¤tProperty); /* - * 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 ( (foundPropertyIndex!=PROPERTY_NULL) && @@ -502,7 +493,6 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( { StorageBaseImpl *This = (StorageBaseImpl *)iface; StorageInternalImpl* newStorage; - IEnumSTATSTGImpl* propertyEnumeration; StgProperty currentProperty; ULONG foundPropertyIndex; HRESULT res = STG_E_UNKNOWN; @@ -555,17 +545,12 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( *ppstg = NULL; - propertyEnumeration = IEnumSTATSTGImpl_Construct( - This->ancestorStorage, - This->rootPropertySetIndex); - - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty( - propertyEnumeration, + foundPropertyIndex = findElement( + This->ancestorStorage, + This->rootPropertySetIndex, pwcsName, ¤tProperty); - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - if ( (foundPropertyIndex!=PROPERTY_NULL) && (currentProperty.propertyType==PROPTYPE_STORAGE) ) { @@ -708,39 +693,32 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement( const OLECHAR* pwcsNewName) /* [in] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - IEnumSTATSTGImpl* propertyEnumeration; StgProperty currentProperty; ULONG foundPropertyIndex; TRACE("(%p, %s, %s)\n", iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName)); - propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, - This->rootPropertySetIndex); - - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsNewName, - ¤tProperty); + foundPropertyIndex = findElement(This->ancestorStorage, + This->rootPropertySetIndex, + pwcsNewName, + ¤tProperty); if (foundPropertyIndex != PROPERTY_NULL) { /* * There is already a property with the new name */ - IEnumSTATSTGImpl_Destroy(propertyEnumeration); 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, - pwcsOldName, - ¤tProperty); - - IEnumSTATSTGImpl_Destroy(propertyEnumeration); + foundPropertyIndex = findElement(This->ancestorStorage, + This->rootPropertySetIndex, + pwcsOldName, + ¤tProperty); if (foundPropertyIndex != PROPERTY_NULL) { @@ -855,7 +833,6 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( IStream** ppstm) /* [out] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - IEnumSTATSTGImpl* propertyEnumeration; StgStreamImpl* newStream; StgProperty currentProperty, newStreamProperty; ULONG foundPropertyIndex, newPropertyIndex; @@ -904,14 +881,10 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( *ppstm = 0; - propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, - This->rootPropertySetIndex); - - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsName, - ¤tProperty); - - IEnumSTATSTGImpl_Destroy(propertyEnumeration); + foundPropertyIndex = findElement(This->ancestorStorage, + This->rootPropertySetIndex, + pwcsName, + ¤tProperty); if (foundPropertyIndex != PROPERTY_NULL) { @@ -1068,7 +1041,6 @@ static HRESULT WINAPI StorageImpl_CreateStorage( { StorageImpl* const This=(StorageImpl*)iface; - IEnumSTATSTGImpl *propertyEnumeration; StgProperty currentProperty; StgProperty newProperty; ULONG foundPropertyIndex; @@ -1103,16 +1075,10 @@ static HRESULT WINAPI StorageImpl_CreateStorage( return STG_E_ACCESSDENIED; } - /* - * Create a property enumeration and search the properties - */ - propertyEnumeration = IEnumSTATSTGImpl_Construct( This->base.ancestorStorage, - This->base.rootPropertySetIndex); - - foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, - pwcsName, - ¤tProperty); - IEnumSTATSTGImpl_Destroy(propertyEnumeration); + foundPropertyIndex = findElement(This->base.ancestorStorage, + This->base.rootPropertySetIndex, + pwcsName, + ¤tProperty); if (foundPropertyIndex != PROPERTY_NULL) { @@ -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) @@ -1697,7 +1701,6 @@ static HRESULT WINAPI StorageImpl_DestroyElement( { StorageImpl* const This=(StorageImpl*)iface; - IEnumSTATSTGImpl* propertyEnumeration; HRESULT hr = S_OK; BOOL res; StgProperty propertyToDelete; @@ -1715,17 +1718,12 @@ static HRESULT WINAPI StorageImpl_DestroyElement( if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ ) return STG_E_ACCESSDENIED; - propertyEnumeration = IEnumSTATSTGImpl_Construct( + foundPropertyIndexToDelete = findElement( This->base.ancestorStorage, - This->base.rootPropertySetIndex); - - foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty( - propertyEnumeration, + This->base.rootPropertySetIndex, pwcsName, &propertyToDelete); - IEnumSTATSTGImpl_Destroy(propertyEnumeration); - if ( foundPropertyIndexToDelete == PROPERTY_NULL ) { return STG_E_FILENOTFOUND; @@ -3973,49 +3971,6 @@ static INT IEnumSTATSTGImpl_FindParentProperty( 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( IEnumSTATSTGImpl* This, ULONG nodeToPush) -- 1.6.3.3