[Libreoffice-commits] core.git: unoidl/source

Stephan Bergmann sbergman at redhat.com
Thu Oct 24 00:57:40 PDT 2013


 unoidl/source/unoidl.cxx |  112 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 78 insertions(+), 34 deletions(-)

New commits:
commit bdd55e28fc7788c2968daaf87b782f8e6189ee2d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Oct 24 09:48:13 2013 +0200

    fdo#67725 unoidl::AggregatingCursor must wrap modules for aggregation, too
    
    Otherwise cppuhelper::TypeManager::createTypeDescriptionEnumeration, sitting on
    top such an AggregatingCursor, will miss any entities from provider P' in module
    M if any previous provider P contains the same module M.
    
    That happened when climaker generates cli_oootypes.dll, where the enumeration
    missed everything from offapi in top-level module "com" because it had already
    seen udkapi's "com", and only reported the handful of entities under offapi's
    other top-level module "org" (which does not appear in udkapi).
    
    Change-Id: If538391bde22bcc346417b5988cf12023f0d4172

diff --git a/unoidl/source/unoidl.cxx b/unoidl/source/unoidl.cxx
index 7c3e2e5..6d716d4 100644
--- a/unoidl/source/unoidl.cxx
+++ b/unoidl/source/unoidl.cxx
@@ -28,41 +28,101 @@ namespace unoidl {
 
 namespace {
 
+class AggregatingModule: public ModuleEntity {
+public:
+    AggregatingModule(
+        std::vector< rtl::Reference< Provider > > const & providers,
+        OUString const & name):
+        providers_(providers), name_(name)
+    {}
+
+private:
+    virtual ~AggregatingModule() throw () {}
+
+    virtual std::vector< OUString > getMemberNames() const;
+
+    virtual rtl::Reference< MapCursor > createCursor() const;
+
+    std::vector< rtl::Reference< Provider > > providers_;
+    OUString name_;
+};
+
+std::vector< OUString > AggregatingModule::getMemberNames() const {
+    std::set< OUString > names;
+    for (std::vector< rtl::Reference< Provider > >::const_iterator i(
+             providers_.begin());
+         i != providers_.end(); ++i)
+    {
+        rtl::Reference< Entity > ent((*i)->findEntity(name_));
+        if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
+            std::vector< OUString > ns(
+                static_cast< ModuleEntity * >(ent.get())->getMemberNames());
+            names.insert(ns.begin(), ns.end());
+        }
+    }
+    return std::vector< OUString >(names.begin(), names.end());
+}
+
 class AggregatingCursor: public MapCursor {
 public:
     AggregatingCursor(
-        std::vector< rtl::Reference< MapCursor > > const & cursors):
-        cursors_(cursors), iterator_(cursors_.begin())
-    {}
+        std::vector< rtl::Reference< Provider > > const & providers,
+        OUString const & name):
+        providers_(providers), name_(name), iterator_(providers_.begin())
+    { findCursor(); }
 
 private:
     virtual ~AggregatingCursor() throw () {}
 
-    virtual rtl::Reference< Entity > getNext(rtl::OUString * name);
+    virtual rtl::Reference< Entity > getNext(OUString * name);
 
-    std::vector< rtl::Reference< MapCursor > > cursors_;
-    std::vector< rtl::Reference< MapCursor > >::iterator iterator_;
-    std::set< rtl::OUString > seenMembers;
+    void findCursor();
+
+    std::vector< rtl::Reference< Provider > > providers_;
+    OUString name_;
+    std::vector< rtl::Reference< Provider > >::iterator iterator_;
+    rtl::Reference< MapCursor > cursor_;
+    std::set< OUString > seen_;
 };
 
-rtl::Reference< Entity > AggregatingCursor::getNext(rtl::OUString * name) {
-    for (;;) {
-        if (iterator_ == cursors_.end()) {
-            return rtl::Reference< Entity >();
-        }
-        rtl::OUString n;
-        rtl::Reference< Entity > ent((*iterator_)->getNext(&n));
+rtl::Reference< Entity > AggregatingCursor::getNext(OUString * name) {
+    while (cursor_.is()) {
+        OUString n;
+        rtl::Reference< Entity > ent(cursor_->getNext(&n));
         if (ent.is()) {
-            if (seenMembers.insert(n).second) {
+            if (seen_.insert(n).second) {
                 if (name != 0) {
                     *name = n;
                 }
-                return ent;
+                return ent->getSort() == Entity::SORT_MODULE
+                    ? new AggregatingModule(
+                        providers_, (name_.isEmpty() ? name_ : name_ + ".") + n)
+                    : ent;
             }
         } else {
-            ++iterator_;
+            cursor_.clear();
+            findCursor();
         }
     }
+    return rtl::Reference< Entity >();
+}
+
+void AggregatingCursor::findCursor() {
+    for (; !cursor_.is() && iterator_ != providers_.end(); ++iterator_) {
+        if (name_.isEmpty()) {
+            cursor_ = (*iterator_)->createRootCursor();
+        } else {
+            rtl::Reference< Entity > ent((*iterator_)->findEntity(name_));
+            if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
+                cursor_ = static_cast< ModuleEntity * >(ent.get())->
+                    createCursor();
+            }
+        }
+    }
+}
+
+rtl::Reference< MapCursor > AggregatingModule::createCursor() const {
+    return new AggregatingCursor(providers_, name_);
 }
 
 }
@@ -156,23 +216,7 @@ rtl::Reference< Entity > Manager::findEntity(rtl::OUString const & name) const {
 rtl::Reference< MapCursor > Manager::createCursor(rtl::OUString const & name)
     const
 {
-    std::vector< rtl::Reference< MapCursor > > curs;
-    for (std::vector< rtl::Reference< Provider > >::const_iterator i(
-             providers_.begin());
-         i != providers_.end(); ++i)
-    {
-        if (name.isEmpty()) {
-            curs.push_back((*i)->createRootCursor());
-        } else {
-            rtl::Reference< Entity > ent((*i)->findEntity(name));
-            if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
-                curs.push_back(
-                    static_cast< ModuleEntity * >(ent.get())->createCursor());
-            }
-        }
-    }
-    return curs.empty()
-        ? rtl::Reference< MapCursor >() : new AggregatingCursor(curs);
+    return new AggregatingCursor(providers_, name);
 }
 
 Manager::~Manager() throw () {}


More information about the Libreoffice-commits mailing list