cool#15956: keep insertion order in NameContainer's getElementNames
This is required to keep content of Basic/script-lc.xml and each
Basic/<lib>/script-lb.xml byte-identical on round-trip, which is
necessary for signatures to stay valid; this broke after commit
ea2a974386 (Simplify NameContainer,
2024-12-01).
Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com>
Change-Id: Ib30b701dce8bbcb919c88f5b66f5134150ded575
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5025
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit bfe67bc782cf89e944324042c8e53c42f4b6421b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207164
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
This commit is contained in:
committed by
Xisco Fauli
parent
fa878fa5e8
commit
6601fe8419
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||
#include <com/sun/star/lang/XInitialization.hpp>
|
||||
#include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
|
||||
@@ -58,6 +59,9 @@ class NameContainer final
|
||||
cppu::OWeakObject& rOwner;
|
||||
|
||||
std::unordered_map<OUString, css::uno::Any> maMap;
|
||||
// Enumeration must keep insertion order: it drives the on-disk order of the
|
||||
// library index file and module streams, which macro signatures sign over.
|
||||
std::vector<OUString> maNamesOrder;
|
||||
|
||||
css::uno::Type mType;
|
||||
css::uno::XInterface* mpxEventSource;
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
#include <comphelper/storagehelper.hxx>
|
||||
#include <cppuhelper/exc_hlp.hxx>
|
||||
#include <cppuhelper/supportsservice.hxx>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
@@ -93,6 +95,21 @@ using com::sun::star::uno::Reference;
|
||||
// #i34411: Flag for error handling during migration
|
||||
static bool GbMigrationSuppressErrors = false;
|
||||
|
||||
#ifndef NDEBUG
|
||||
namespace
|
||||
{
|
||||
// The name->value map and the insertion-order vector are redundant views of the
|
||||
// same set of names; verify they list exactly the same names, once each.
|
||||
bool mapAndOrderConsistent(const std::unordered_map<OUString, Any>& rMap,
|
||||
const std::vector<OUString>& rOrder)
|
||||
{
|
||||
if (rMap.size() != rOrder.size())
|
||||
return false;
|
||||
return std::all_of(rMap.begin(), rMap.end(), [&rOrder](const auto& rEntry)
|
||||
{ return std::find(rOrder.begin(), rOrder.end(), rEntry.first) != rOrder.end(); });
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Implementation class NameContainer
|
||||
|
||||
@@ -120,7 +137,8 @@ Any NameContainer::getByName( const OUString& aName )
|
||||
|
||||
Sequence< OUString > NameContainer::getElementNames()
|
||||
{
|
||||
return comphelper::mapKeysToSequence(maMap);
|
||||
// Return the names in insertion order.
|
||||
return comphelper::containerToSequence(maNamesOrder);
|
||||
}
|
||||
|
||||
sal_Bool NameContainer::hasByName( const OUString& aName )
|
||||
@@ -179,7 +197,10 @@ void NameContainer::insertNoCheck(const OUString& aName, const Any& aElement,
|
||||
throw IllegalArgumentException(u"types do not match"_ustr, rOwner, 2);
|
||||
}
|
||||
|
||||
assert(!maMap.contains(aName) && "insertNoCheck: name already present");
|
||||
maMap[aName] = aElement;
|
||||
maNamesOrder.push_back(aName);
|
||||
assert(mapAndOrderConsistent(maMap, maNamesOrder));
|
||||
|
||||
// Fire event
|
||||
if (maContainerListeners.getLength(guard) > 0)
|
||||
@@ -223,6 +244,8 @@ void NameContainer::removeByName(const OUString& aName, std::unique_lock<std::mu
|
||||
|
||||
Any aOldElement = aIt->second;
|
||||
maMap.erase(aIt);
|
||||
std::erase(maNamesOrder, aName);
|
||||
assert(mapAndOrderConsistent(maMap, maNamesOrder));
|
||||
|
||||
// Fire event
|
||||
if (maContainerListeners.getLength(guard) > 0)
|
||||
|
||||
Reference in New Issue
Block a user