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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to