Kaydet (Commit) 5d3ea0cd authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Establish mapping between original strings and upper strings.

This will be used to retrieve case insensitive string identifiers
later.

Change-Id: Ia34f57d0e8d0cb6bd4630f8d110853ed049770b5
üst 279ae511
......@@ -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;
};
}
......
......@@ -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);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment