os/textandloc/fontservices/textshaperplugin/IcuSource/common/servloc.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /**
     2  *******************************************************************************
     3  * Copyright (C) 2001-2005, International Business Machines Corporation and    *
     4  * others. All Rights Reserved.                                                *
     5  *******************************************************************************
     6  *
     7  *******************************************************************************
     8  */
     9 #ifndef ICULSERV_H
    10 #define ICULSERV_H
    11 
    12 #include "unicode/utypes.h"
    13 
    14 #if UCONFIG_NO_SERVICE
    15 
    16 U_NAMESPACE_BEGIN
    17 
    18 /*
    19  * Allow the declaration of APIs with pointers to ICUService
    20  * even when service is removed from the build.
    21  */
    22 class ICULocaleService;
    23 
    24 U_NAMESPACE_END
    25 
    26 #else
    27 
    28 #include "unicode/unistr.h"
    29 #include "unicode/locid.h"
    30 #include "unicode/strenum.h"
    31 
    32 #include "hash.h"
    33 #include "uvector.h"
    34 
    35 #include "serv.h"
    36 #include "locutil.h"
    37 
    38 U_NAMESPACE_BEGIN
    39 
    40 class ICULocaleService;
    41 
    42 class LocaleKey;
    43 class LocaleKeyFactory;
    44 class SimpleLocaleKeyFactory;
    45 class ServiceListener;
    46 
    47 /*
    48  ******************************************************************
    49  */
    50 
    51 /**
    52  * A subclass of Key that implements a locale fallback mechanism.
    53  * The first locale to search for is the locale provided by the
    54  * client, and the fallback locale to search for is the current
    55  * default locale.  If a prefix is present, the currentDescriptor
    56  * includes it before the locale proper, separated by "/".  This
    57  * is the default key instantiated by ICULocaleService.</p>
    58  *
    59  * <p>Canonicalization adjusts the locale string so that the
    60  * section before the first understore is in lower case, and the rest
    61  * is in upper case, with no trailing underscores.</p> 
    62  */
    63 
    64 class U_COMMON_API LocaleKey : public ICUServiceKey {
    65   private: 
    66     int32_t _kind;
    67     UnicodeString _primaryID;
    68     UnicodeString _fallbackID;
    69     UnicodeString _currentID;
    70 
    71   public:
    72     enum {
    73         KIND_ANY = -1
    74     };
    75 
    76     /**
    77      * Create a LocaleKey with canonical primary and fallback IDs.
    78      */
    79     static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 
    80                                                   const UnicodeString* canonicalFallbackID,
    81                                                   UErrorCode& status);
    82 
    83     /**
    84      * Create a LocaleKey with canonical primary and fallback IDs.
    85      */
    86     static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 
    87                                                   const UnicodeString* canonicalFallbackID, 
    88                                                   int32_t kind,
    89                                                   UErrorCode& status);
    90 
    91   protected:
    92     /**
    93      * PrimaryID is the user's requested locale string,
    94      * canonicalPrimaryID is this string in canonical form,
    95      * fallbackID is the current default locale's string in
    96      * canonical form.
    97      */
    98     LocaleKey(const UnicodeString& primaryID, 
    99               const UnicodeString& canonicalPrimaryID, 
   100               const UnicodeString* canonicalFallbackID, 
   101               int32_t kind);
   102 
   103  public:
   104     /**
   105      * Append the prefix associated with the kind, or nothing if the kind is KIND_ANY.
   106      */
   107     virtual UnicodeString& prefix(UnicodeString& result) const;
   108 
   109     /**
   110      * Return the kind code associated with this key.
   111      */
   112     virtual int32_t kind() const;
   113 
   114     /**
   115      * Return the canonicalID.
   116      */
   117     virtual UnicodeString& canonicalID(UnicodeString& result) const;
   118 
   119     /**
   120      * Return the currentID.
   121      */
   122     virtual UnicodeString& currentID(UnicodeString& result) const;
   123 
   124     /**
   125      * Return the (canonical) current descriptor, or null if no current id.
   126      */
   127     virtual UnicodeString& currentDescriptor(UnicodeString& result) const;
   128 
   129     /**
   130      * Convenience method to return the locale corresponding to the (canonical) original ID.
   131      */
   132     virtual Locale& canonicalLocale(Locale& result) const;
   133 
   134     /**
   135      * Convenience method to return the locale corresponding to the (canonical) current ID.
   136      */
   137     virtual Locale& currentLocale(Locale& result) const;
   138 
   139     /**
   140      * If the key has a fallback, modify the key and return true,
   141      * otherwise return false.</p>
   142      *
   143      * <p>First falls back through the primary ID, then through
   144      * the fallbackID.  The final fallback is the empty string,
   145      * unless the primary id was the empty string, in which case
   146      * there is no fallback.  
   147      */
   148     virtual UBool fallback();
   149 
   150     /**
   151      * Return true if a key created from id matches, or would eventually
   152      * fallback to match, the canonical ID of this key.  
   153      */
   154     virtual UBool isFallbackOf(const UnicodeString& id) const;
   155     
   156  public:
   157     /**
   158      * UObject boilerplate.
   159      */
   160     static UClassID U_EXPORT2 getStaticClassID();
   161 
   162     virtual UClassID getDynamicClassID() const;
   163 
   164     /**
   165      * Destructor.
   166      */
   167     virtual ~LocaleKey();
   168 
   169 #ifdef SERVICE_DEBUG
   170  public:
   171     virtual UnicodeString& debug(UnicodeString& result) const;
   172     virtual UnicodeString& debugClass(UnicodeString& result) const;
   173 #endif
   174 
   175 };
   176 
   177 /*
   178  ******************************************************************
   179  */
   180 
   181 /**
   182  * A subclass of ICUServiceFactory that uses LocaleKeys, and is able to
   183  * 'cover' more specific locales with more general locales that it
   184  * supports.  
   185  *
   186  * <p>Coverage may be either of the values VISIBLE or INVISIBLE.
   187  *
   188  * <p>'Visible' indicates that the specific locale(s) supported by
   189  * the factory are registered in getSupportedIDs, 'Invisible'
   190  * indicates that they are not.
   191  *
   192  * <p>Localization of visible ids is handled
   193  * by the handling factory, regardless of kind.
   194  */
   195 class U_COMMON_API LocaleKeyFactory : public ICUServiceFactory {
   196 protected:
   197     const UnicodeString _name;
   198     const int32_t _coverage;
   199 
   200 public:
   201     enum {
   202         /**
   203          * Coverage value indicating that the factory makes
   204          * its locales visible, and does not cover more specific 
   205          * locales.
   206          */
   207         VISIBLE = 0,
   208 
   209         /**
   210          * Coverage value indicating that the factory does not make
   211          * its locales visible, and does not cover more specific
   212          * locales.
   213          */
   214         INVISIBLE = 1
   215     };
   216 
   217     /**
   218      * Destructor.
   219      */
   220     virtual ~LocaleKeyFactory();
   221 
   222 protected:
   223     /**
   224      * Constructor used by subclasses.
   225      */
   226     LocaleKeyFactory(int32_t coverage);
   227 
   228     /**
   229      * Constructor used by subclasses.
   230      */
   231     LocaleKeyFactory(int32_t coverage, const UnicodeString& name);
   232 
   233     /**
   234      * Implement superclass abstract method.  This checks the currentID of
   235      * the key against the supported IDs, and passes the canonicalLocale and
   236      * kind off to handleCreate (which subclasses must implement).
   237      */
   238 public:
   239     virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
   240 
   241 protected:
   242     virtual UBool handlesKey(const ICUServiceKey& key, UErrorCode& status) const;
   243 
   244 public:
   245     /**
   246      * Override of superclass method.  This adjusts the result based
   247      * on the coverage rule for this factory.
   248      */
   249     virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
   250 
   251     /**
   252      * Return a localized name for the locale represented by id.
   253      */
   254     virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;
   255 
   256 protected:
   257     /**
   258      * Utility method used by create(ICUServiceKey, ICUService).  Subclasses can implement
   259      * this instead of create.  The default returns NULL.
   260      */
   261     virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const;
   262 
   263    /**
   264      * Return true if this id is one the factory supports (visible or 
   265      * otherwise).
   266      */
   267  //   virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const;
   268 
   269    /**
   270      * Return the set of ids that this factory supports (visible or 
   271      * otherwise).  This can be called often and might need to be
   272      * cached if it is expensive to create.
   273      */
   274     virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;
   275 
   276 public:
   277     /**
   278      * UObject boilerplate.
   279      */
   280     static UClassID U_EXPORT2 getStaticClassID();
   281 
   282     virtual UClassID getDynamicClassID() const;
   283 
   284 #ifdef SERVICE_DEBUG
   285  public:
   286     virtual UnicodeString& debug(UnicodeString& result) const;
   287     virtual UnicodeString& debugClass(UnicodeString& result) const;
   288 #endif
   289 
   290 };
   291 
   292 /*
   293  ******************************************************************
   294  */
   295 
   296 /**
   297  * A LocaleKeyFactory that just returns a single object for a kind/locale.
   298  */
   299 
   300 class U_COMMON_API SimpleLocaleKeyFactory : public LocaleKeyFactory {
   301  private:
   302     UObject* _obj;
   303     UnicodeString _id;
   304     const int32_t _kind;
   305 
   306  public:
   307     SimpleLocaleKeyFactory(UObject* objToAdopt, 
   308                            const UnicodeString& locale, 
   309                            int32_t kind, 
   310                            int32_t coverage);
   311 
   312     SimpleLocaleKeyFactory(UObject* objToAdopt, 
   313                            const Locale& locale, 
   314                            int32_t kind, 
   315                            int32_t coverage);
   316 
   317     /**
   318      * Destructor.
   319      */
   320     virtual ~SimpleLocaleKeyFactory();
   321 
   322     /**
   323      * Override of superclass method.  Returns the service object if kind/locale match.  Service is not used.
   324      */
   325     virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
   326 
   327     /**
   328      * Override of superclass method.  This adjusts the result based
   329      * on the coverage rule for this factory.
   330      */
   331     virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
   332 
   333  protected:
   334     /**
   335      * Return true if this id is equal to the locale name.
   336      */
   337     //virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const;
   338 
   339 
   340 public:
   341     /**
   342      * UObject boilerplate.
   343      */
   344     static UClassID U_EXPORT2 getStaticClassID();
   345 
   346     virtual UClassID getDynamicClassID() const;
   347 
   348 #ifdef SERVICE_DEBUG
   349  public:
   350     virtual UnicodeString& debug(UnicodeString& result) const;
   351     virtual UnicodeString& debugClass(UnicodeString& result) const;
   352 #endif
   353 
   354 };
   355 
   356 /*
   357  ******************************************************************
   358  */
   359 
   360 /**
   361  * A LocaleKeyFactory that creates a service based on the ICU locale data.
   362  * This is a base class for most ICU factories.  Subclasses instantiate it
   363  * with a constructor that takes a bundle name, which determines the supported
   364  * IDs.  Subclasses then override handleCreate to create the actual service
   365  * object.  The default implementation returns a resource bundle.
   366  */
   367 class U_COMMON_API ICUResourceBundleFactory : public LocaleKeyFactory 
   368 {
   369  protected:
   370     UnicodeString _bundleName;
   371 
   372  public:
   373     /**
   374      * Convenience constructor that uses the main ICU bundle name.
   375      */
   376     ICUResourceBundleFactory();
   377 
   378     /**
   379      * A service factory based on ICU resource data in resources with
   380      * the given name.  This should be a 'path' that can be passed to
   381      * ures_openAvailableLocales, such as U_ICUDATA or U_ICUDATA_COLL.
   382      * The empty string is equivalent to U_ICUDATA.
   383      */
   384     ICUResourceBundleFactory(const UnicodeString& bundleName);
   385 
   386     /**
   387      * Destructor
   388      */
   389     virtual ~ICUResourceBundleFactory();
   390 
   391 protected:
   392     /**
   393      * Return the supported IDs.  This is the set of all locale names in ICULocaleData.
   394      */
   395     virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;
   396 
   397     /**
   398      * Create the service.  The default implementation returns the resource bundle
   399      * for the locale, ignoring kind, and service.
   400      */
   401     virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const;
   402 
   403 public:
   404     /**
   405      * UObject boilerplate.
   406      */
   407     static UClassID U_EXPORT2 getStaticClassID();
   408     virtual UClassID getDynamicClassID() const;
   409 
   410 
   411 #ifdef SERVICE_DEBUG
   412  public:
   413     virtual UnicodeString& debug(UnicodeString& result) const;
   414     virtual UnicodeString& debugClass(UnicodeString& result) const;
   415 #endif
   416 
   417 };
   418 
   419 /*
   420  ******************************************************************
   421  */
   422 
   423 class U_COMMON_API ICULocaleService : public ICUService 
   424 {
   425  private:
   426   Locale fallbackLocale;
   427   UnicodeString fallbackLocaleName;
   428   UMTX llock;
   429 
   430  public:
   431   /**
   432    * Construct an ICULocaleService.
   433    */
   434   ICULocaleService();
   435 
   436   /**
   437    * Construct an ICULocaleService with a name (useful for debugging).
   438    */
   439   ICULocaleService(const UnicodeString& name);
   440 
   441   /**
   442    * Destructor.
   443    */
   444   virtual ~ICULocaleService();
   445 
   446 #if 0
   447   // redeclare because of overload resolution rules?
   448   // no, causes ambiguities since both UnicodeString and Locale have constructors that take a const char*
   449   // need some compiler flag to remove warnings 
   450   UObject* get(const UnicodeString& descriptor, UErrorCode& status) const {
   451     return ICUService::get(descriptor, status);
   452   }
   453 
   454   UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const {
   455     return ICUService::get(descriptor, actualReturn, status);
   456   }
   457 #endif
   458 
   459   /**
   460    * Convenience override for callers using locales.  This calls
   461    * get(Locale, int, Locale[]) with KIND_ANY for kind and null for
   462    * actualReturn.
   463    */
   464   UObject* get(const Locale& locale, UErrorCode& status) const;
   465 
   466   /**
   467    * Convenience override for callers using locales.  This calls
   468    * get(Locale, int, Locale[]) with a null actualReturn.
   469    */
   470   UObject* get(const Locale& locale, int32_t kind, UErrorCode& status) const;
   471 
   472   /**
   473    * Convenience override for callers using locales. This calls
   474    * get(Locale, String, Locale[]) with a null kind.
   475    */
   476   UObject* get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const;
   477                    
   478   /**
   479    * Convenience override for callers using locales.  This uses
   480    * createKey(Locale.toString(), kind) to create a key, calls getKey, and then
   481    * if actualReturn is not null, returns the actualResult from
   482    * getKey (stripping any prefix) into a Locale.  
   483    */
   484   UObject* get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const;
   485 
   486   /**
   487    * Convenience override for callers using locales.  This calls
   488    * registerObject(Object, Locale, int32_t kind, int coverage)
   489    * passing KIND_ANY for the kind, and VISIBLE for the coverage.
   490    */
   491   virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status);
   492 
   493   /**
   494    * Convenience function for callers using locales.  This calls
   495    * registerObject(Object, Locale, int kind, int coverage)
   496    * passing VISIBLE for the coverage.
   497    */
   498   virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status);
   499 
   500   /**
   501    * Convenience function for callers using locales.  This  instantiates
   502    * a SimpleLocaleKeyFactory, and registers the factory.
   503    */
   504   virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status);
   505 
   506 
   507   /**
   508    * (Stop compiler from complaining about hidden overrides.)
   509    * Since both UnicodeString and Locale have constructors that take const char*, adding a public
   510    * method that takes UnicodeString causes ambiguity at call sites that use const char*.
   511    * We really need a flag that is understood by all compilers that will suppress the warning about
   512    * hidden overrides.
   513    */
   514   virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status);
   515 
   516   /**
   517    * Convenience method for callers using locales.  This returns the standard
   518    * service ID enumeration.
   519    */
   520   virtual StringEnumeration* getAvailableLocales(void) const;
   521 
   522  protected:
   523 
   524   /**
   525    * Return the name of the current fallback locale.  If it has changed since this was
   526    * last accessed, the service cache is cleared.
   527    */
   528   const UnicodeString& validateFallbackLocale() const;
   529 
   530   /**
   531    * Override superclass createKey method.
   532    */
   533   virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;
   534 
   535   /**
   536    * Additional createKey that takes a kind.
   537    */
   538   virtual ICUServiceKey* createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const;
   539 
   540   friend class ServiceEnumeration;
   541 };
   542 
   543 U_NAMESPACE_END
   544 
   545     /* UCONFIG_NO_SERVICE */
   546 #endif
   547 
   548     /* ICULSERV_H */
   549 #endif
   550