You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@apache.org on 2002/08/12 05:54:44 UTC

cvs commit: xml-xalan/c/src/ICUBridge FunctionICUFormatNumber.cpp FunctionICUFormatNumber.hpp ICUBridge.cpp ICUBridge.hpp ICUBridgeCollationCompareFunctor.cpp ICUBridgeCollationCompareFunctor.hpp ICUBridgeCollationCompareFunctorImpl.cpp ICUBridgeCollationCompareFunctorImpl.hpp

dbertoni    2002/08/11 20:54:44

  Modified:    c/src/ICUBridge FunctionICUFormatNumber.cpp
                        FunctionICUFormatNumber.hpp ICUBridge.cpp
                        ICUBridge.hpp ICUBridgeCollationCompareFunctor.cpp
                        ICUBridgeCollationCompareFunctor.hpp
                        ICUBridgeCollationCompareFunctorImpl.cpp
                        ICUBridgeCollationCompareFunctorImpl.hpp
  Log:
  Implemented caching of collators and better creation of default collator.  Removed unused code.  Make sure double warning is not emitted when using FunctionICUFormatNumber.
  
  Revision  Changes    Path
  1.9       +5 -3      xml-xalan/c/src/ICUBridge/FunctionICUFormatNumber.cpp
  
  Index: FunctionICUFormatNumber.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/FunctionICUFormatNumber.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- FunctionICUFormatNumber.cpp	9 Jul 2002 01:03:13 -0000	1.8
  +++ FunctionICUFormatNumber.cpp	12 Aug 2002 03:54:43 -0000	1.9
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 2000 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -124,7 +124,8 @@
   			const XalanDOMString&				thePattern,
   			const XalanDecimalFormatSymbols*	theDFS,
   			XalanDOMString&						theResult,
  -			const Locator*						locator) const
  +			const Locator*						locator,
  +			bool								/* fWarn */) const
   {
   	unsigned long	theResultCode =
   		ICUBridge::FormatNumber(
  @@ -149,6 +150,7 @@
   						thePattern,
   						theDFS,
   						theResult,
  -						locator);
  +						locator,
  +						false);
   	}
   }
  
  
  
  1.4       +3 -2      xml-xalan/c/src/ICUBridge/FunctionICUFormatNumber.hpp
  
  Index: FunctionICUFormatNumber.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/FunctionICUFormatNumber.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- FunctionICUFormatNumber.hpp	14 Sep 2001 20:56:46 -0000	1.3
  +++ FunctionICUFormatNumber.hpp	12 Aug 2002 03:54:43 -0000	1.4
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 2000 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -107,7 +107,8 @@
   			const XalanDOMString&				thePattern,
   			const XalanDecimalFormatSymbols*	theDFS,
   			XalanDOMString&						theResult,
  -			const Locator*						locator) const;
  +			const Locator*						locator,
  +			bool								fWarn = true) const;
   
   private:
   
  
  
  
  1.17      +21 -49    xml-xalan/c/src/ICUBridge/ICUBridge.cpp
  
  Index: ICUBridge.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/ICUBridge.cpp,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- ICUBridge.cpp	5 Jan 2002 00:58:52 -0000	1.16
  +++ ICUBridge.cpp	12 Aug 2002 03:54:43 -0000	1.17
  @@ -122,9 +122,26 @@
   	}
   	else
   	{
  -#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
  +		return XalanDOMCharStringToUnicodeString(theString, length(theString));
  +	}
  +}
   
  -		const unsigned int	theLength = length(theString);
  +
  +
  +const UnicodeString
  +ICUBridge::XalanDOMCharStringToUnicodeString(
  +			const XalanDOMChar*			theString,
  +			XalanDOMString::size_type	theLength)
  +{
  +	assert(theString != 0);
  +
  +	if (theLength == 0)
  +	{
  +		return UnicodeString();
  +	}
  +	else
  +	{
  +#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
   
   		if (theStackBufferSize > theLength)
   		{
  @@ -168,7 +185,7 @@
   ICUBridge::XalanDOMStringToUnicodeString(const XalanDOMString&	theString)
   {
   	// Just call up to the XalanDOMChar* version...
  -	return XalanDOMCharStringToUnicodeString(c_wstr(theString));
  +	return XalanDOMCharStringToUnicodeString(c_wstr(theString), length(theString));
   }
   
   
  @@ -313,8 +330,7 @@
   		// DecimalFormat will adopt the DecimalFormatSymbols instance.
   		DecimalFormat	theFormatter(ICUBridge::XalanDOMStringToUnicodeString(thePattern), theDFS.release(), theStatus);
   
  -		if (theStatus == U_ZERO_ERROR ||
  -		    (theStatus >= U_ERROR_INFO_START && theStatus < U_ERROR_INFO_LIMIT))
  +		if (U_SUCCESS(theStatus))
   		{
   			// Do the format...
   			theFormatter.format(theNumber, theUnicodeResult);
  @@ -359,48 +375,4 @@
   	}
   
   	return theStatus;
  -}
  -
  -
  -
  -int
  -ICUBridge::collationCompare(
  -			const XalanDOMString&	theLHS,
  -			const XalanDOMString&	theRHS)
  -{
  -	// Just call to the XalanDOMChar* version...
  -	return collationCompare(c_wstr(theLHS), c_wstr(theRHS));
  -}
  -
  -
  -
  -int
  -ICUBridge::collationCompare(
  -			const XalanDOMChar*		theLHS,
  -			const XalanDOMChar*		theRHS)
  -{
  -	UErrorCode				theStatus = U_ZERO_ERROR;
  -
  -	// Create a collator, and keep it in an XalanAutoPtr...
  -	const XalanAutoPtr<Collator>	theCollator(Collator::createInstance(theStatus));
  -
  -	if (theStatus == U_ZERO_ERROR || theStatus == U_USING_DEFAULT_ERROR)
  -	{
  -		// OK, do the compare...
  -		return theCollator->compare(
  -#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
  -					ICUBridge::XalanDOMCharStringToUnicodeString(theLHS),
  -					ICUBridge::XalanDOMCharStringToUnicodeString(theRHS));
  -#else
  -					theLHS,
  -					length(theLHS),
  -					theRHS,
  -					length(theRHS));
  -#endif
  -	}
  -	else
  -	{
  -		// If creating the ICU Collator failed, fall back to the default...
  -		return collationCompare(theLHS, theRHS);
  -	}
   }
  
  
  
  1.6       +5 -10     xml-xalan/c/src/ICUBridge/ICUBridge.hpp
  
  Index: ICUBridge.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/ICUBridge.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ICUBridge.hpp	4 Jan 2002 19:12:43 -0000	1.5
  +++ ICUBridge.hpp	12 Aug 2002 03:54:43 -0000	1.6
  @@ -85,6 +85,11 @@
   	XalanDOMCharStringToUnicodeString(const XalanDOMChar*	theString);
   
   	static const UnicodeString
  +	XalanDOMCharStringToUnicodeString(
  +			const XalanDOMChar*			theString,
  +			XalanDOMString::size_type	theLHSLength);
  +
  +	static const UnicodeString
   	XalanDOMStringToUnicodeString(const XalanDOMString&		theString);
   
   	static const XalanDOMString
  @@ -101,16 +106,6 @@
   			double								theNumber,
   			const XalanDecimalFormatSymbols*	theXalanDFS,
   			XalanDOMString&						theResult);
  -
  -	static int
  -	collationCompare(
  -			const XalanDOMString&	theLHS,
  -			const XalanDOMString&	theRHS);
  -
  -	static int
  -	collationCompare(
  -			const XalanDOMChar*		theLHS,
  -			const XalanDOMChar*		theRHS);
   };
   
   
  
  
  
  1.22      +2 -2      xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctor.cpp
  
  Index: ICUBridgeCollationCompareFunctor.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctor.cpp,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- ICUBridgeCollationCompareFunctor.cpp	29 May 2002 18:22:02 -0000	1.21
  +++ ICUBridgeCollationCompareFunctor.cpp	12 Aug 2002 03:54:43 -0000	1.22
  @@ -64,8 +64,8 @@
   
   
   
  -ICUBridgeCollationCompareFunctor::ICUBridgeCollationCompareFunctor() :
  -	m_impl(new ICUBridgeCollationCompareFunctorImpl)
  +ICUBridgeCollationCompareFunctor::ICUBridgeCollationCompareFunctor(bool	fCacheCollators) :
  +	m_impl(new ICUBridgeCollationCompareFunctorImpl(fCacheCollators))
   {
   }
   
  
  
  
  1.10      +6 -1      xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctor.hpp
  
  Index: ICUBridgeCollationCompareFunctor.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctor.hpp,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ICUBridgeCollationCompareFunctor.hpp	29 May 2002 18:22:02 -0000	1.9
  +++ ICUBridgeCollationCompareFunctor.hpp	12 Aug 2002 03:54:43 -0000	1.10
  @@ -79,7 +79,12 @@
   	typedef StylesheetExecutionContextDefault::eCaseOrder	eCaseOrder;
   
   
  -	ICUBridgeCollationCompareFunctor();
  +	/**
  +	 * Constructor.
  +	 * 
  +	 * @param fCacheCollators If true, the instance will cache collators.  This is not thread-safe, so each thread must have its own instance.
  +	 */
  +	ICUBridgeCollationCompareFunctor(bool	fCacheCollators = false);
   
   	virtual
   	~ICUBridgeCollationCompareFunctor();
  
  
  
  1.3       +302 -63   xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctorImpl.cpp
  
  Index: ICUBridgeCollationCompareFunctorImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctorImpl.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ICUBridgeCollationCompareFunctorImpl.cpp	29 May 2002 18:22:02 -0000	1.2
  +++ ICUBridgeCollationCompareFunctorImpl.cpp	12 Aug 2002 03:54:43 -0000	1.3
  @@ -60,45 +60,90 @@
   
   
   
  +#include <algorithm>
  +#include <cstdlib>
  +
  +
  +
   #include <Include/XalanAutoPtr.hpp>
   
   
   
   #include <PlatformSupport/DOMStringHelper.hpp>
  +#include <PlatformSupport/XalanUnicode.hpp>
   
   
   
  -// this is the ICU's macro for using namespace ...
  -U_NAMESPACE_USE
  +const StylesheetExecutionContextDefault::DefaultCollationCompareFunctor		ICUBridgeCollationCompareFunctorImpl::s_defaultFunctor;
   
   
   
  -const StylesheetExecutionContextDefault::DefaultCollationCompareFunctor		ICUBridgeCollationCompareFunctorImpl::s_defaultFunctor;
  +inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
  +createCollator(
  +			UErrorCode&			theStatus,
  +			const Locale&		theLocale,
  +			XalanDOMString*		theLocaleName = 0)
  +{
  +	typedef ICUBridgeCollationCompareFunctorImpl::CollatorType	CollatorType;
   
  +	if (theLocaleName != 0)
  +	{
  +		*theLocaleName = theLocale.getName();
  +
  +		// Replace _ with -, since that's what xml:lang specifies...
  +		XalanDOMString::size_type	theIndex;
   
  +		while((theIndex = indexOf(*theLocaleName, XalanUnicode::charLowLine)) != theLocaleName->length())
  +		{
  +			(*theLocaleName)[theIndex] = XalanUnicode::charHyphenMinus;
  +		}
  +	}
   
  -inline Collator*
  -createCollator(UErrorCode&	theStatus)
  +	return CollatorType::createInstance(theLocale, theStatus);
  +}
  +
  +
  +
  +inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
  +createCollator(
  +			UErrorCode&			theStatus,
  +			XalanDOMString*		theLocaleName = 0)
   {
  +	const char*		theLang =
  +#if defined(XALAN_STRICT_ANSI_HEADERS)
  +			std::getenv("LANG");
  +#else
  +			getenv("LANG");
  +#endif
  +
  +	if (theLang == 0)
  +	{
   #if defined(XALAN_ICU_DEFAULT_LOCALE_PROBLEM)
  -	return Collator::createInstance(Locale::US, theStatus);
  +		return createCollator(theStatus, Locale::US, theLocaleName);
   #else
  -	return Collator::createInstance(theStatus);
  +		return createCollator(theStatus, Locale::getDefault(), theLocaleName);
   #endif
  +	}
  +	else
  +	{
  +		return createCollator(theStatus, Locale(theLang), theLocaleName);
  +	}
   }
   
   
   
  -ICUBridgeCollationCompareFunctorImpl::ICUBridgeCollationCompareFunctorImpl() :
  +ICUBridgeCollationCompareFunctorImpl::ICUBridgeCollationCompareFunctorImpl(bool		fCacheCollators) :
   	m_isValid(false),
  -	m_defaultCollator(0)
  +	m_defaultCollator(0),
  +	m_defaultCollatorLocaleName(),
  +	m_cacheCollators(fCacheCollators),
  +	m_collatorCache()
   {
   	UErrorCode	theStatus = U_ZERO_ERROR;
   
  -	m_defaultCollator = createCollator(theStatus);
  +	m_defaultCollator = createCollator(theStatus, &m_defaultCollatorLocaleName);
   
  -	if (theStatus == U_ZERO_ERROR ||
  -	    (theStatus >= U_ERROR_INFO_START && theStatus < U_ERROR_INFO_LIMIT))
  +	if (U_SUCCESS(theStatus))
   	{
   		m_isValid = true;
   	}
  @@ -108,16 +153,25 @@
   
   ICUBridgeCollationCompareFunctorImpl::~ICUBridgeCollationCompareFunctorImpl()
   {
  +#if !defined(XALAN_NO_NAMESPACES)
  +	using std::for_each;
  +#endif
  +
   	delete m_defaultCollator;
  +
  +	for_each(
  +			m_collatorCache.begin(),
  +			m_collatorCache.end(),
  +			CollationCacheStruct::CollatorDeleteFunctor());
   }
   
   
   
  -inline int
  -doCompare(
  -			const Collator&			theCollator,
  +int
  +ICUBridgeCollationCompareFunctorImpl::doCompare(
  +			const CollatorType&		theCollator,
   			const XalanDOMChar*		theLHS,
  -			const XalanDOMChar*		theRHS)
  +			const XalanDOMChar*		theRHS) const
   {
   #if defined(XALAN_USE_WCHAR_CAST_HACK)
   	return theCollator.compare(
  @@ -165,60 +219,29 @@
   int
   ICUBridgeCollationCompareFunctorImpl::doDefaultCompare(
   			const XalanDOMChar*		theLHS,
  -			const XalanDOMChar*		theRHS,
  -			eCaseOrder				theCaseOrder) const
  +			const XalanDOMChar*		theRHS) const
   {
   	if (isValid() == false)
   	{
  -		return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
  +		return s_defaultFunctor(theLHS, theRHS, StylesheetExecutionContext::eDefault);
   	}
  -	else if (theCaseOrder == StylesheetExecutionContext::eDefault)
  +	else
   	{
   		assert(m_defaultCollator != 0);
   
   		return doCompare(*m_defaultCollator, theLHS, theRHS);
   	}
  -	else
  -	{
  -		UErrorCode	theStatus = U_ZERO_ERROR;
  -
  -		XalanAutoPtr<Collator>	theCollator(createCollator(theStatus));
  -
  -		if (theStatus == U_ZERO_ERROR ||
  -			(theStatus >= U_ERROR_INFO_START && theStatus < U_ERROR_INFO_LIMIT))
  -		{
  -			theCollator->setAttribute(
  -					UCOL_CASE_FIRST,
  -					caseOrderConvert(theCaseOrder),
  -					theStatus);
  -
  -			return doCompare(*theCollator.get(), theLHS, theRHS);
  -		}
  -		else
  -		{
  -			return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
  -		}
  -	}
   }
   
   
   
  -int
  -ICUBridgeCollationCompareFunctorImpl::operator()(
  -			const XalanDOMChar*		theLHS,
  -			const XalanDOMChar*		theRHS,
  -			eCaseOrder				theCaseOrder) const
  -{
  -	return doDefaultCompare(theLHS, theRHS, theCaseOrder);
  -}
  -
  -
  -
  -inline Collator*
  -getCollator(
  +inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
  +createCollator(
   			const XalanDOMChar*		theLocale,
   			UErrorCode&				theStatus)
   {
  +	assert(theLocale != 0);
  +
   	const XalanDOMString::size_type		theLength = length(theLocale);
   
   	if (theLength >= ULOC_FULLNAME_CAPACITY)
  @@ -245,7 +268,7 @@
   			theBuffer[i] = char(theLocale[i]);
   		}
   #endif
  -		return Collator::createInstance(
  +		return ICUBridgeCollationCompareFunctorImpl::CollatorType::createInstance(
   					Locale::createFromName(theBuffer),
   					theStatus);
   	}
  @@ -254,7 +277,7 @@
   
   
   int
  -ICUBridgeCollationCompareFunctorImpl::operator()(
  +ICUBridgeCollationCompareFunctorImpl::doCompare(
   			const XalanDOMChar*		theLHS,
   			const XalanDOMChar*		theRHS,
   			const XalanDOMChar*		theLocale,
  @@ -262,34 +285,250 @@
   {
   	UErrorCode	theStatus = U_ZERO_ERROR;
   
  -	XalanAutoPtr<Collator>	theCollator(getCollator(theLocale, theStatus));
  +	XalanAutoPtr<CollatorType>	theCollator(createCollator(theLocale, theStatus));
   
  -	if (theStatus == U_ZERO_ERROR ||
  -	    (theStatus >= U_ERROR_INFO_START && theStatus < U_ERROR_INFO_LIMIT))
  +	if (U_SUCCESS(theStatus))
   	{
   		assert(theCollator.get() != 0);
   
  -		theCollator->setAttribute(
  +		return doCompare(
  +				*theCollator.get(),
  +				theLHS,
  +				theRHS,
  +				theCaseOrder);
  +	}
  +	else
  +	{
  +		return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
  +	}
  +}
  +
  +
  +
  +int
  +ICUBridgeCollationCompareFunctorImpl::doCompareCached(
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS,
  +			const XalanDOMChar*		theLocale,
  +			eCaseOrder				theCaseOrder) const
  +{
  +	CollatorType*	theCollator = getCachedCollator(theLocale);
  +
  +	if (theCollator != 0)
  +	{
  +		return doCompare(*theCollator, theLHS, theRHS, theCaseOrder);
  +	}
  +	else
  +	{
  +		UErrorCode	theStatus = U_ZERO_ERROR;
  +
  +		XalanAutoPtr<CollatorType>	theCollatorGuard(createCollator(theLocale, theStatus));
  +
  +		if (U_SUCCESS(theStatus))
  +		{
  +			assert(theCollatorGuard.get() != 0);
  +
  +			// OK, there was no error, so cache the instance...
  +			cacheCollator(theCollatorGuard.get(), theLocale);
  +
  +			// Release the collator, since it's in the cache and
  +			// will be controlled by the cache...
  +			theCollator = theCollatorGuard.release();
  +
  +			return doCompare(
  +					*theCollator,
  +					theLHS,
  +					theRHS,
  +					theCaseOrder);
  +		}
  +		else
  +		{
  +			return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
  +		}
  +	}
  +}
  +
  +
  +
  +int
  +ICUBridgeCollationCompareFunctorImpl::doCompare(
  +			CollatorType&			theCollator,
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS,
  +			eCaseOrder				theCaseOrder) const
  +{
  +	UErrorCode	theStatus = U_ZERO_ERROR;
  +
  +	theCollator.setAttribute(
   				UCOL_CASE_FIRST,
   				caseOrderConvert(theCaseOrder),
   				theStatus);
   
   #if defined(XALAN_USE_WCHAR_CAST_HACK)
  -		return theCollator->compare(
  +	return theCollator.compare(
   					(const wchar_t*)theLHS,
   					length(theLHS),
   					(const wchar_t*)theRHS,
   					length(theRHS));
   #else
  -		return theCollator->compare(
  +	return theCollator.compare(
   					theLHS,
   					length(theLHS),
   					theRHS,
   					length(theRHS));
   #endif
  +}
  +
  +
  +
  +int
  +ICUBridgeCollationCompareFunctorImpl::operator()(
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS,
  +			eCaseOrder				theCaseOrder) const
  +{
  +	if (theCaseOrder == StylesheetExecutionContext::eDefault)
  +	{
  +		return doDefaultCompare(theLHS, theRHS);
   	}
   	else
   	{
  -		return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
  +		return doCompare(
  +				theLHS,
  +				theRHS,
  +				c_wstr(m_defaultCollatorLocaleName),
  +				theCaseOrder);
  +	}
  +}
  +
  +
  +
  +int
  +ICUBridgeCollationCompareFunctorImpl::operator()(
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS,
  +			const XalanDOMChar*		theLocale,
  +			eCaseOrder				theCaseOrder) const
  +{
  +	if (theCaseOrder == StylesheetExecutionContext::eDefault &&
  +		XalanDOMString::equals(m_defaultCollatorLocaleName, theLocale) == true)
  +	{
  +		return doDefaultCompare(theLHS, theRHS);
  +	}
  +	else if (m_cacheCollators == true)
  +	{
  +		return doCompareCached(theLHS, theRHS, theLocale, theCaseOrder);
  +	}
  +	else
  +	{
  +		return doCompare(theLHS, theRHS, theLocale, theCaseOrder);
  +	};
  +}
  +
  +
  +
  +ICUBridgeCollationCompareFunctorImpl::CollatorType*
  +ICUBridgeCollationCompareFunctorImpl::getCachedCollator(const XalanDOMChar*		theLocale) const
  +{
  +#if !defined(XALAN_NO_NAMESPACES)
  +	using std::find_if;
  +#endif
  +
  +	CollatorCacheDequeType&		theNonConstCache =
  +#if defined(XALAN_NO_MUTABLE)
  +		(CollatorCacheDequeType*)m_collatorCache;
  +#else
  +		m_collatorCache;
  +#endif
  +
  +	CollatorCacheDequeType::iterator	i =
  +		find_if(
  +			theNonConstCache.begin(),
  +			theNonConstCache.end(),
  +			CollationCacheStruct::CollatorFindFunctor(theLocale));
  +
  +	if (i == theNonConstCache.end())
  +	{
  +		return 0;
  +	}
  +	else
  +	{
  +		// Let's do a quick check to see if we found the first entry.
  +		// If so, we don't have to update the cache, so just return the
  +		// appropriate value...
  +		const CollatorCacheDequeType::iterator	theBegin =
  +			theNonConstCache.begin();
  +
  +		if (i == theBegin)
  +		{
  +			return (*i).m_collator;
  +		}
  +		else
  +		{
  +			// Make a new instance for the cache, then swap it with
  +			// the one we found.
  +			CollatorCacheDequeType::value_type	theEntry;
  +
  +			theEntry.swap(*i);
  +
  +			// Protect the collator instance, since what we're doing
  +			// might throw an exception...
  +			XalanAutoPtr<CollatorType>	theCollator(theEntry.m_collator);
  +
  +			// OK, now swap everything from i down to begin()...
  +			
  +			CollatorCacheDequeType::iterator	theOther(i);
  +
  +			do
  +			{
  +				--theOther;
  +
  +				(*i).swap(*theOther);
  +
  +				--i;
  +			}
  +			while(i != theBegin);
  +
  +			// Now, swap the latest one into the front...
  +			theEntry.swap(*theBegin);
  +			
  +			// Everything's OK, so release to return the value...
  +			return theCollator.release();
  +		}
  +	}
  +}
  +
  +
  +
  +void
  +ICUBridgeCollationCompareFunctorImpl::cacheCollator(
  +			CollatorType*			theCollator,
  +			const XalanDOMChar*		theLocale) const
  +{
  +	assert(theCollator != 0);
  +	assert(theLocale != 0);
  +
  +	CollatorCacheDequeType&		theNonConstCache =
  +#if defined(XALAN_NO_MUTABLE)
  +		(CollatorCacheDequeType*)m_collatorCache;
  +#else
  +		m_collatorCache;
  +#endif
  +
  +	if (theNonConstCache.size() == eCacheMax)
  +	{
  +		delete theNonConstCache.back().m_collator;
  +
  +		theNonConstCache.pop_back();
   	}
  +
  +	theNonConstCache.push_front(CollatorCacheDequeType::value_type());
  +
  +	CollatorCacheDequeType::value_type&		theEntry = 
  +		theNonConstCache.front();
  +
  +	// Set the locale first, since that might throw an exception...
  +	theEntry.m_locale = theLocale;
  +
  +	theEntry.m_collator = theCollator;
   }
  
  
  
  1.3       +127 -8    xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctorImpl.hpp
  
  Index: ICUBridgeCollationCompareFunctorImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/ICUBridge/ICUBridgeCollationCompareFunctorImpl.hpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ICUBridgeCollationCompareFunctorImpl.hpp	29 May 2002 18:22:02 -0000	1.2
  +++ ICUBridgeCollationCompareFunctorImpl.hpp	12 Aug 2002 03:54:43 -0000	1.3
  @@ -64,6 +64,10 @@
   
   
   
  +#include <deque>
  +
  +
  +
   #include <XSLT/StylesheetExecutionContextDefault.hpp>
   
   
  @@ -80,7 +84,12 @@
   	typedef StylesheetExecutionContextDefault::eCaseOrder	eCaseOrder;
   
   
  -	ICUBridgeCollationCompareFunctorImpl();
  +	/**
  +	 * Constructor.
  +	 * 
  +	 * @param fCacheCollators If true, the instance will cache collators.  This is not thread-safe, so each thread must have its own instance.
  +	 */
  +	ICUBridgeCollationCompareFunctorImpl(bool	fCacheCollators = false);
   
   	~ICUBridgeCollationCompareFunctorImpl();
   
  @@ -103,23 +112,133 @@
   		return m_isValid;
   	}
   
  +#if defined(XALAN_NO_NAMESPACES)
  +	typedef Collator	CollatorType;
  +#else
  +	typedef icu_2_0::Collator	CollatorType;
  +#endif
  +
  +	struct CollationCacheStruct
  +	{
  +		CollationCacheStruct(
  +				const XalanDOMString&	theLocale,
  +				CollatorType*			theCollator) :
  +			m_locale(theLocale),
  +			m_collator(theCollator)
  +		{
  +		}
  +
  +		CollationCacheStruct() :
  +			m_locale(),
  +			m_collator(0)
  +		{
  +		}
  +
  +		void
  +		swap(CollationCacheStruct&	theOther)
  +		{
  +			m_locale.swap(theOther.m_locale);
  +
  +			CollatorType* const		theTemp = m_collator;
  +
  +			m_collator = theOther.m_collator;
  +
  +			theOther.m_collator = theTemp;
  +		}
  +
  +		XalanDOMString	m_locale;
  +
  +		CollatorType*	m_collator;
  +
  +		struct CollatorDeleteFunctor
  +		{
  +			void
  +			operator()(CollationCacheStruct&	theStruct) const
  +			{
  +				delete theStruct.m_collator;
  +			}
  +		};
  +
  +		struct CollatorFindFunctor
  +		{
  +			CollatorFindFunctor(const XalanDOMChar*	theLocale) :
  +				m_locale(theLocale)
  +			{
  +			}
  +
  +			bool
  +			operator()(CollationCacheStruct&	theStruct) const
  +			{
  +				return XalanDOMString::equals(theStruct.m_locale ,m_locale);
  +			}
  +
  +			const XalanDOMChar* const	m_locale;
  +		};
  +	};
  +
  +#if defined(XALAN_NO_NAMESPACES)
  +	typedef deque<CollationCacheStruct>			CollatorCacheDequeType;
  +#else
  +	typedef std::deque<CollationCacheStruct>	CollatorCacheDequeType;
  +#endif
  +
  +	enum { eCacheMax = 10 };
  +
   private:
   
   	int
   	doDefaultCompare(
   			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS) const;
  +
  +	int
  +	doCompare(
  +			const XalanDOMChar*		theLHS,
   			const XalanDOMChar*		theRHS,
  +			const XalanDOMChar*		theLocale,
   			eCaseOrder				theCaseOrder) const;
   
  -	bool	m_isValid;
  +	int
  +	doCompareCached(
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS,
  +			const XalanDOMChar*		theLocale,
  +			eCaseOrder				theCaseOrder) const;
   
  -#if defined(XALAN_NO_NAMESPACES)
  -	Collator*			m_defaultCollator;
  -#else
  -	icu_2_0::Collator*	m_defaultCollator;
  -#endif
  +	int
  +	doCompare(
  +			const CollatorType&		theCollator,
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS) const;
  +
  +	int
  +	doCompare(
  +			CollatorType&			theCollator,
  +			const XalanDOMChar*		theLHS,
  +			const XalanDOMChar*		theRHS,
  +			eCaseOrder				theCaseOrder) const;
  +
  +	CollatorType*
  +	getCachedCollator(const XalanDOMChar*	theLocale) const;
  +
  +	void
  +	cacheCollator(
  +			CollatorType*			theCollator,
  +			const XalanDOMChar*		theLocale) const;
  +
  +
  +	// Data members...
  +	bool							m_isValid;
  +
  +	CollatorType*					m_defaultCollator;
  +
  +	XalanDOMString					m_defaultCollatorLocaleName;
  +
  +	bool							m_cacheCollators;
  +
  +	mutable CollatorCacheDequeType	m_collatorCache;
   
  -	const static StylesheetExecutionContextDefault::DefaultCollationCompareFunctor		s_defaultFunctor;
  +	const static StylesheetExecutionContextDefault::DefaultCollationCompareFunctor	s_defaultFunctor;
   };
   
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org