[Libreoffice-commits] core.git: Branch 'private/kohei/calc-shared-string' - 2 commits - include/svl svl/qa svl/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Oct 2 08:28:57 PDT 2013


 include/svl/stringpool.hxx     |   39 ++++++++++++++++++++++++++
 svl/qa/unit/svl.cxx            |   40 ++++++++++++++++++++++++++
 svl/source/misc/stringpool.cxx |   61 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 135 insertions(+), 5 deletions(-)

New commits:
commit 9f4dd5493dcf7b697896a1bf6fb078e76b081246
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Oct 2 11:29:42 2013 -0400

    Write some rudimentary tests for the new shared string pool class.
    
    Change-Id: Ie66de46d69f664839aa0a2d056cd3b8df4d4989b

diff --git a/include/svl/stringpool.hxx b/include/svl/stringpool.hxx
index 2541568..26785e3 100644
--- a/include/svl/stringpool.hxx
+++ b/include/svl/stringpool.hxx
@@ -34,11 +34,11 @@ class SVL_DLLPUBLIC StringPool
     StrHashType maStrPool;
     StrHashType maStrPoolUpper;
     StrIdMapType maToUpperMap;
-    CharClass* mpCharClass;
+    const CharClass* mpCharClass;
 
 public:
     StringPool();
-    StringPool( CharClass* pCharClass );
+    StringPool( const CharClass* pCharClass );
 
     /**
      * Intern a string object into the shared string pool.
@@ -60,6 +60,8 @@ public:
      */
     const rtl_uString* getIdentifier( const OUString& rStr ) const;
 
+    const rtl_uString* getIdentifierIgnoreCase( const OUString& rStr ) const;
+
 private:
     InsertResultType findOrInsert( StrHashType& rPool, const OUString& rStr ) const;
 };
diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx
index 8d46ecf..f41ab73 100644
--- a/svl/qa/unit/svl.cxx
+++ b/svl/qa/unit/svl.cxx
@@ -33,6 +33,8 @@
 
 #include "svl/zforlist.hxx"
 #include "svl/zformat.hxx"
+#include "svl/stringpool.hxx"
+#include "unotools/syslocale.hxx"
 
 #define DEBUG_UNIT_TEST 0
 
@@ -65,11 +67,13 @@ public:
     virtual void tearDown();
 
     void testNumberFormat();
+    void testStringPool();
     void testFdo60915();
     void testI116701();
 
     CPPUNIT_TEST_SUITE(Test);
     CPPUNIT_TEST(testNumberFormat);
+    CPPUNIT_TEST(testStringPool);
     CPPUNIT_TEST(testFdo60915);
     CPPUNIT_TEST(testI116701);
     CPPUNIT_TEST_SUITE_END();
@@ -288,6 +292,42 @@ void Test::testNumberFormat()
     }
 }
 
+void Test::testStringPool()
+{
+    SvtSysLocale aSysLocale;
+    svl::StringPool aPool(aSysLocale.GetCharClassPtr());
+
+    const rtl_uString* p1 = aPool.intern("Andy");
+    const rtl_uString* p2 = aPool.intern("Andy");
+    CPPUNIT_ASSERT_EQUAL(p1, p2);
+
+    p2 = aPool.intern("Bruce");
+    CPPUNIT_ASSERT_MESSAGE("They must differ.", p1 != p2);
+
+    OUString aAndy("Andy");
+    p2 = aPool.getIdentifier(aAndy);
+    CPPUNIT_ASSERT_EQUAL(p1, p2);
+
+    // Test case insensitive string ID's.
+    OUString aAndyLower("andy"), aAndyUpper("ANDY");
+    p1 = aPool.getIdentifier("Andy");
+    CPPUNIT_ASSERT_MESSAGE("This shouldn't be NULL.", p1);
+    p2 = aPool.intern(aAndyLower);
+    CPPUNIT_ASSERT_MESSAGE("They must differ.", p1 != p2);
+    p2 = aPool.intern(aAndyUpper);
+    CPPUNIT_ASSERT_MESSAGE("They must differ.", p1 != p2);
+
+    p1 = aPool.getIdentifierIgnoreCase("Andy");
+    CPPUNIT_ASSERT_MESSAGE("This shouldn't be NULL.", p1);
+    p2 = aPool.getIdentifierIgnoreCase("andy");
+    CPPUNIT_ASSERT_MESSAGE("This shouldn't be NULL.", p2);
+    CPPUNIT_ASSERT_EQUAL(p1, p2);
+
+    p2 = aPool.getIdentifierIgnoreCase("ANDY");
+    CPPUNIT_ASSERT_MESSAGE("This shouldn't be NULL.", p2);
+    CPPUNIT_ASSERT_EQUAL(p1, p2);
+}
+
 void Test::checkPreviewString(SvNumberFormatter& aFormatter,
                               const OUString& sCode,
                               double fPreviewNumber,
diff --git a/svl/source/misc/stringpool.cxx b/svl/source/misc/stringpool.cxx
index 46462d1..1181538 100644
--- a/svl/source/misc/stringpool.cxx
+++ b/svl/source/misc/stringpool.cxx
@@ -13,7 +13,7 @@
 namespace svl {
 
 StringPool::StringPool() : mpCharClass(NULL) {}
-StringPool::StringPool( CharClass* pCharClass ) : mpCharClass(pCharClass) {}
+StringPool::StringPool( const CharClass* pCharClass ) : mpCharClass(pCharClass) {}
 
 rtl_uString* StringPool::intern( const OUString& rStr )
 {
@@ -52,6 +52,16 @@ const rtl_uString* StringPool::getIdentifier( const OUString& rStr ) const
     return (it == maStrPool.end()) ? NULL : it->pData;
 }
 
+const rtl_uString* StringPool::getIdentifierIgnoreCase( const OUString& rStr ) const
+{
+    if (!mpCharClass)
+        return NULL;
+
+    OUString aUpper = mpCharClass->uppercase(rStr);
+    StrHashType::iterator it = maStrPoolUpper.find(aUpper);
+    return (it == maStrPool.end()) ? NULL : it->pData;
+}
+
 StringPool::InsertResultType StringPool::findOrInsert( StrHashType& rPool, const OUString& rStr ) const
 {
     StrHashType::iterator it = rPool.find(rStr);
commit 93d8f0172232a246e7b2a4d43ceddaf499837746
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Oct 2 10:47:28 2013 -0400

    Establish mapping between original strings and upper strings.
    
    This will be used to retrieve case insensitive string identifiers
    later.
    
    Change-Id: Ia34f57d0e8d0cb6bd4630f8d110853ed049770b5

diff --git a/include/svl/stringpool.hxx b/include/svl/stringpool.hxx
index 643c846..2541568 100644
--- a/include/svl/stringpool.hxx
+++ b/include/svl/stringpool.hxx
@@ -13,18 +13,55 @@
 #include "svl/svldllapi.h"
 #include "rtl/ustring.hxx"
 
+#include <boost/unordered_map.hpp>
 #include <boost/unordered_set.hpp>
 
+class CharClass;
+
 namespace svl {
 
+/**
+ * Storage for pool of shared strings.  It also provides mapping from
+ * original-cased strings to upper-cased strings for case insensitive
+ * operations.
+ */
 class SVL_DLLPUBLIC StringPool
 {
     typedef boost::unordered_set<OUString, OUStringHash> StrHashType;
+    typedef std::pair<StrHashType::iterator, bool> InsertResultType;
+    typedef boost::unordered_map<const rtl_uString*, const rtl_uString*> StrIdMapType;
+
     StrHashType maStrPool;
+    StrHashType maStrPoolUpper;
+    StrIdMapType maToUpperMap;
+    CharClass* mpCharClass;
+
 public:
     StringPool();
+    StringPool( CharClass* pCharClass );
 
+    /**
+     * Intern a string object into the shared string pool.
+     *
+     * @param rStr string object to intern.
+     *
+     * @return a pointer to the string object stored inside the pool, or NULL
+     *         if the insertion fails.
+     */
     rtl_uString* intern( const OUString& rStr );
+
+    /**
+     * Get a unique ID of string object that's expected to be in the shared
+     * string pool. If the string is not in the pool, NULL is returned.
+     *
+     * @param rStr string object to get the ID of.
+     *
+     * @return unique ID of the string object.
+     */
+    const rtl_uString* getIdentifier( const OUString& rStr ) const;
+
+private:
+    InsertResultType findOrInsert( StrHashType& rPool, const OUString& rStr ) const;
 };
 
 }
diff --git a/svl/source/misc/stringpool.cxx b/svl/source/misc/stringpool.cxx
index f8ddda9..46462d1 100644
--- a/svl/source/misc/stringpool.cxx
+++ b/svl/source/misc/stringpool.cxx
@@ -8,26 +8,67 @@
  */
 
 #include "svl/stringpool.hxx"
+#include "unotools/charclass.hxx"
 
 namespace svl {
 
-StringPool::StringPool() {}
+StringPool::StringPool() : mpCharClass(NULL) {}
+StringPool::StringPool( CharClass* pCharClass ) : mpCharClass(pCharClass) {}
 
 rtl_uString* StringPool::intern( const OUString& rStr )
 {
+    InsertResultType aRes = findOrInsert(maStrPool, rStr);
+    if (aRes.first == maStrPool.end())
+        // Insertion failed.
+        return NULL;
+
+    rtl_uString* pOrig = aRes.first->pData;
+
+    if (!aRes.second)
+        // No new string has been inserted. Return the existing string in the pool.
+        return pOrig;
+
+    if (!mpCharClass)
+        return pOrig;
+
+    // This is a new string insertion. Establish mapping to upper-case variant.
+
+    OUString aUpper = mpCharClass->uppercase(rStr);
+    aRes = findOrInsert(maStrPoolUpper, aUpper);
+    if (aRes.first == maStrPoolUpper.end())
+        // Failed to insert or fetch upper-case variant. Should never happen.
+        return pOrig;
+
+    // Set mapping.
+    rtl_uString* pUpper = aRes.first->pData;
+    maToUpperMap.insert(StrIdMapType::value_type(pOrig, pUpper));
+
+    return pOrig;
+}
+
+const rtl_uString* StringPool::getIdentifier( const OUString& rStr ) const
+{
     StrHashType::iterator it = maStrPool.find(rStr);
-    if (it == maStrPool.end())
+    return (it == maStrPool.end()) ? NULL : it->pData;
+}
+
+StringPool::InsertResultType StringPool::findOrInsert( StrHashType& rPool, const OUString& rStr ) const
+{
+    StrHashType::iterator it = rPool.find(rStr);
+    bool bInserted = false;
+    if (it == rPool.end())
     {
         // Not yet in the pool.
-        std::pair<StrHashType::iterator, bool> r = maStrPool.insert(rStr.intern());
+        std::pair<StrHashType::iterator, bool> r = rPool.insert(rStr.intern());
         if (!r.second)
             // Insertion failed.
-            return NULL;
+            return InsertResultType(rPool.end(), false);
 
         it = r.first;
+        bInserted = true;
     }
 
-    return it->pData;
+    return InsertResultType(it, bInserted);
 }
 
 }


More information about the Libreoffice-commits mailing list