summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svl/stringpool.hxx37
-rw-r--r--svl/source/misc/stringpool.cxx51
2 files changed, 83 insertions, 5 deletions
diff --git a/include/svl/stringpool.hxx b/include/svl/stringpool.hxx
index 643c8466c0bc..25415684c9fd 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 f8ddda9b0acd..46462d1e7a59 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);
}
}