/*
*******************************************************************************
*
*   Copyright (C) 1996-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*
* File resbund.h
*
*   CREATED BY
*       Richard Gillam
*
* Modification History:
*
*   Date        Name        Description
*   2/5/97      aliu        Added scanForLocaleInFile.  Added
*                           constructor which attempts to read resource bundle
*                           from a specific file, without searching other files.
*   2/11/97     aliu        Added UErrorCode return values to constructors.  Fixed
*                           infinite loops in scanForFile and scanForLocale.
*                           Modified getRawResourceData to not delete storage in
*                           localeData and resourceData which it doesn't own.
*                           Added Mac compatibility #ifdefs for tellp() and
*                           ios::nocreate.
*   2/18/97     helena      Updated with 100% documentation coverage.
*   3/13/97     aliu        Rewrote to load in entire resource bundle and store
*                           it as a Hashtable of ResourceBundleData objects.
*                           Added state table to govern parsing of files.
*                           Modified to load locale index out of new file distinct
*                           from default.txt.
*   3/25/97     aliu        Modified to support 2-d arrays, needed for timezone data.
*                           Added support for custom file suffixes.  Again, needed to
*                           support timezone data.
*   4/7/97      aliu        Cleaned up.
* 03/02/99      stephen     Removed dependency on FILE*.
* 03/29/99      helena      Merged Bertrand and Stephen's changes.
* 06/11/99      stephen     Removed parsing of .txt files.
*                           Reworked to use new binary format.
*                           Cleaned up.
* 06/14/99      stephen     Removed methods taking a filename suffix.
* 11/09/99		weiv		Added getLocale(), fRealLocale, removed fRealLocaleID
*******************************************************************************
*/

#ifndef RESBUND_H
#define RESBUND_H
  
#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "unicode/locid.h"
#include <wchar.h>


class RBHashtable;
class ResourceBundleData;
class ResourceBundleCache;
class VisitedFileCache;
#ifndef _FILESTRM
typedef struct _FileStream FileStream;
#endif

/* forward declarations */
class Locale;
class RuleBasedCollator;
class ResourceBundle;
extern int32_t T_ResourceBundle_countArrayItemsImplementation(
                const ResourceBundle* resourceBundle, 
                const char* resourceKey,
                UErrorCode& err);
extern const UnicodeString** listInstalledLocalesImplementation(
                const char* path,
                int32_t* numInstalledLocales);
extern void getTaggedArrayUCharsImplementation(
                const ResourceBundle*   bundle,
                const char           *resourceTag,
                UChar const**         itemTags,
                UChar const**         items,
                int32_t                    maxItems,
                int32_t&                numItems,
                UErrorCode&              err);

/**
 * A class representing a collection of resource information pertaining to a given
 * locale. A resource bundle provides a way of accessing locale- specfic information in
 * a data file. You create a resource bundle that manages the resources for a given
 * locale and then ask it for individual resources.
 * <P>
 * The resource bundle file is a text (ASCII or Unicode) file with the format:
 * <pre>
 * .   locale {
 * .      tag1 {...}
 * .      tag2 {...}
 * .   }
 * </pre>
 * The tags are used to retrieve the data later. You may not have multiple instances of
 * the same tag.
 * <P>
 * Four data types are supported. These are solitary strings, comma-delimited lists of
 * strings, 2-dimensional arrays of strings, and tagged lists of strings.
 * <P>
 * Note that all data is textual. Adjacent strings are merged by the low-level
 * tokenizer, so that the following effects occur: foo bar, baz // 2 elements, "foo
 * bar", and "baz" "foo" "bar", baz // 2 elements, "foobar", and "baz" Note that a
 * single intervening space is added between merged strings, unless they are both double
 * quoted. This extends to more than two strings in a row.
 * <P>
 * Whitespace is ignored, as in a C source file.
 * <P>
 * Solitary strings have the format:
 * <pre>
 * .   Tag { Data }
 * </pre>
 * This is indistinguishable from a comma-delimited list with only one element, and in
 * fact may be retrieved as such (as an array, or as element 0 or an array).
 * <P>
 * Comma-delimited lists have the format:
 * <pre>
 * .   Tag { Data, Data, Data }
 * </pre>
 * Parsing is lenient; a final string, after the last element, is allowed.
 * <P>
 * Tagged lists have the format:
 * <pre>
 * .   Tag { Subtag { Data } Subtag {Data} }
 * </pre>
 * Data is retrieved by specifying the subtag.
 * <P>
 * Two-dimensional arrays have the format:
 * <pre>
 * .   TwoD {
 * .       { r1c1, r1c2, ..., r1cm },
 * .       { r2c1, r2c2, ..., r2cm },
 * .       ...
 * .       { rnc1, rnc2, ..., rncm }
 * .   }
 * </pre>
 * where n is the number of rows, and m is the number of columns. Parsing is lenient (as
 * in other data types). A final comma is always allowed after the last element; either
 * the last string in a row, or the last row itself. Furthermore, since there is no
 * ambiguity, the commas between the rows are entirely optional. (However, if a comma is
 * present, there can only be one comma, no more.) It is possible to have zero columns,
 * as follows:
 * <pre>
 * .   Odd { {} {} {} } // 3 x 0 array
 * </pre>
 * But it is impossible to have zero rows. The smallest array is thus a 1 x 0 array,
 * which looks like this:
 * <pre>
 * .   Smallest { {} } // 1 x 0 array
 * </pre>
 * The array must be strictly rectangular; that is, each row must have the same number
 * of elements.
 * <P>
 * This is an example for using a possible custom resource:
 * <pre>
 * .    Locale currentLocale;
 * .    UErrorCode success = U_ZERO_ERROR;
 * .    ResourceBundle myResources("MyResources", currentLocale, success );
 * .
 * .    UnicodeString button1Title, button2Title;
 * .    myResources.getString("OkKey", button1Title, success );
 * .    myResources.getString("CancelKey", button2Title, success );
 * </pre>
 * @draft
 */
class U_COMMON_API ResourceBundle {
public:
    /**
     * Constructor
     *
     * @param path    This is a full pathname in the platform-specific format for the
     *                directory containing the resource data files we want to load
     *                resources from. We use locale IDs to generate filenames, and the
     *                filenames have this string prepended to them before being passed
     *                to the C++ I/O functions. Therefore, this string must always end
     *                with a directory delimiter (whatever that is for the target OS)
     *                for this class to work correctly.
     * @param locale  This is the locale this resource bundle is for. To get resources
     *                for the French locale, for example, you would create a
     *                ResourceBundle passing Locale::FRENCH for the "locale" parameter,
     *                and all subsequent calls to that resource bundle will return
     *                resources that pertain to the French locale. If the caller doesn't
     *                pass a locale parameter, the default locale for the system (as
     *                returned by Locale::getDefault()) will be used.
     * The UErrorCode& err parameter is used to return status information to the user. To
     * check whether the construction succeeded or not, you should check the value of
     * U_SUCCESS(err). If you wish more detailed information, you can check for
     * informational error results which still indicate success. U_USING_FALLBACK_ERROR
     * indicates that a fall back locale was used. For example, 'de_CH' was requested,
     * but nothing was found there, so 'de' was used. U_USING_DEFAULT_ERROR indicates that
     * the default locale data was used; neither the requested locale nor any of its
     * fall back locales could be found.
     * @draft
     */
                        ResourceBundle( const UnicodeString&    path,
                                        const Locale&           locale,
                                        UErrorCode&              err);
                        ResourceBundle( const UnicodeString&    path,
                                        UErrorCode&              err);
                        ResourceBundle( const wchar_t* path,
                                        const Locale& locale,
                                        UErrorCode& err);
                        ~ResourceBundle();

    /**
     * Returns the contents of a string resource. Resource data is undifferentiated
     * Unicode text. The resource file may contain quoted strings or escape sequences;
     * these will be parsed prior to the data's return.
     * [THIS FUNCTION IS DERECATED; USE THE OVERLOAD BELOW INSTEAD]
     *
     * @param resourceTag  The resource tag of the string resource the caller wants
     * @param theString    Receives the actual data in the resource
     * @param err          Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                     specified tag couldn't be found.
     * @draft
     */
    void                getString(  const char             *resourceTag,
                                    UnicodeString&          theString,
                                    UErrorCode&              err) const;

    /**
     * Returns the contents of a string resource. Resource data is undifferentiated
     * Unicode text. The resource file may contain quoted strings or escape sequences;
     * these will be parsed prior to the data's return.
     *
     * @param resourceTag  The resource tag of the string resource the caller wants
     * @param err          Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                     specified tag couldn't be found.
     * @return A pointer to the string from the resource bundle, or NULL if there was
     *           an error.
     * @draft
     */
    const UnicodeString*    getString(  const char                *resourceTag,
                                        UErrorCode&                err) const;

    /**
     * Returns the contents of a string-array resource. This will return the contents of
     * a string-array (comma-delimited-list) resource as a C++ array of UnicodeString
     * objects. The number of elements in the array is returned in numArrayItems.
     * Calling getStringArray on a resource of type string will return an array with one
     * element; calling it on a resource of type tagged-array results in a
     * U_MISSING_RESOURCE_ERROR error.
     *
     * @param resourceTag    The resource tag of the string-array resource the caller
     *                       wants
     * @param numArrayItems  Receives the number of items in the array the function
     *                       returns.
     * @param err            Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                       specified tag couldn't be found.
     * @return               The resource requested, as a pointer to an array of
     *                       UnicodeStrings. The caller does not own the storage and
     *                       must not delete it.
     * @draft
     */
    const UnicodeString*    getStringArray( const char             *resourceTag,
                                            int32_t&                numArrayItems,
                                            UErrorCode&              err) const;

    /**
     * Returns a single item from a string-array resource. This will return the contents
     * of a single item in a resource of string-array (comma-delimited-list) type. If
     * the resource is not an array, a U_MISSING_RESOURCE_ERROR will be returned in err.
     * [THIS FUNCTION IS DEPRECATED; USE THE OVERLOAD BELOW INSTEAD]
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param index         The index (zero-based) of the particular array item the user
     *                      wants to extract from the resource.
     * @param theArrayItem  Receives the actual text of the desired array item.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified tag couldn't be found, or if the index was out of range.
     * @draft
     */
    void                getArrayItem(   const char             *resourceTag,
                                        int32_t                 index,
                                        UnicodeString&          theArrayItem,
                                        UErrorCode&              err) const;

    /**
     * Returns a single item from a string-array resource. This will return the contents
     * of a single item in a resource of string-array (comma-delimited-list) type. If
     * the resource is not an array, a U_MISSING_RESOURCE_ERROR will be returned in err.
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param index         The index (zero-based) of the particular array item the user
     *                      wants to extract from the resource.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified tag couldn't be found, or if the index was out of range.
     * @return A pointer to the text of the array item, or NULL is there was an error.
     * @draft
     */
    const UnicodeString*    getArrayItem(   const char                *resourceTag,
                                            int32_t                    index,
                                            UErrorCode&                err) const;

    /**
     * Return the contents of a 2-dimensional array resource. The return value will be a
     * UnicodeString** array. (This is really an array of pointers; each pointer is a
     * ROW of the data.) The number of rows and columns is returned. If the resource is
     * of the wrong type, or not present, U_MISSING_RESOURCE_ERROR is placed in err.
     *
     * @param resourceTag  The resource tag of the string-array resource the caller
     *                     wants
     * @param rowCount     Receives the number of rows in the array the function
     *                     returns.
     * @param columnCount  Receives the number of columns in the array the function
     *                     returns.
     * @param err          Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                     specified tag couldn't be found.
     * @return             The resource requested, as a UnicodeStrings**. The caller
     *                     does not own the storage and must not delete it.
     * @draft
     */
    const UnicodeString**   get2dArray(const char          *resourceTag,
                                       int32_t&             rowCount,
                                       int32_t&             columnCount,
                                       UErrorCode&           err) const;

    /**
     * Return a single string from a 2-dimensional array resource. If the resource does
     * not exists, or if it is not a 2-d array, or if the row or column indices are out
     * of bounds, err is set to U_MISSING_RESOURCE_ERROR.
     * [THIS FUNCTION IS DEPRECATED; USE THE OVERLOAD BELOW INSTEAD]
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param rowIndex      The row index (zero-based) of the array item the user wants
     *                      to extract from the resource.
     * @param columnIndex   The column index (zero-based) of the array item the user
     *                      wants to extract from the resource.
     * @param theArrayItem  Receives the actual text of the desired array item.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified tag couldn't be found, if the resource data was in
     *                      the wrong format, or if either index is out of bounds.
     * @draft
     */
    void                get2dArrayItem(const char          *resourceTag,
                                       int32_t              rowIndex,
                                       int32_t              columnIndex,
                                       UnicodeString&       theArrayItem,
                                       UErrorCode&           err) const;

    /**
     * Return a single string from a 2-dimensional array resource. If the resource does
     * not exists, or if it is not a 2-d array, or if the row or column indices are out
     * of bounds, err is set to U_MISSING_RESOURCE_ERROR.
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param rowIndex      The row index (zero-based) of the array item the user wants
     *                      to extract from the resource.
     * @param columnIndex   The column index (zero-based) of the array item the user
     *                      wants to extract from the resource.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified tag couldn't be found, if the resource data was in
     *                      the wrong format, or if either index is out of bounds.
     * @return A pointer to the text of the array item, or NULL is there was an error.
     * @draft
     */
    const UnicodeString*    get2dArrayItem( const char                *resourceTag,
                                            int32_t                    rowIndex,
                                            int32_t                    columnIndex,
                                            UErrorCode&                err) const;

    /**
     * Returns a single item from a tagged-array resource This will return the contents
     * of a single item in a resource of type tagged-array. If this function is called
     * for a resource that is not of type tagged-array, it will set err to
     * MISSING_RESOUCE_ERROR.
     * [THIS FUNCTION IS DEPRECATED; USE THE OVERLOAD BELOW INSTEAD]
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param itemTag       The item tag for the item the caller wants to extract.
     * @param theArrayItem  Receives the text of the desired array item.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified resource tag couldn't be found, or if an item
     *                      with the specified item tag couldn't be found in the resource.
     * @draft
     */
    void                getTaggedArrayItem( const char             *resourceTag,
                                            const UnicodeString&    itemTag,
                                            UnicodeString&          theArrayItem,
                                            UErrorCode&              err) const;

    /**
     * Returns a single item from a tagged-array resource This will return the contents
     * of a single item in a resource of type tagged-array. If this function is called
     * for a resource that is not of type tagged-array, it will set err to
     * MISSING_RESOUCE_ERROR.
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param itemTag       The item tag for the item the caller wants to extract.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified resource tag couldn't be found, or if an item
     *                      with the specified item tag coldn't be found in the resource.
     * @return A pointer to the text of the array item, or NULL is there was an error.
     * @draft
     */
    const UnicodeString*    getTaggedArrayItem( const char             *resourceTag,
                                                const UnicodeString&    itemTag,
                                                UErrorCode&                err) const;

    /**
     * Returns a tagged-array resource.  The contents of the resource is returned as two
     * separate arrays of UnicodeStrings, the addresses of which are placed in "itemTags"
     * and "items".  After calling this function, the items in the resource will be in the
     * list pointed to by "items", and for each items[i], itemTags[i] will be the tag that
     * corresponds to it.  The total number of entries in both arrays is returned in
     * numItems.
     *
     * @param resourceTag   The resource tag of the resource the caller wants to extract
     *                      an item from.
     * @param itemTags      Set to point to an array of UnicodeStrings representing the
     *                      tags in the specified resource.  The caller DOES own this array,
     *                      and must delete it.
     * @param items         Set to point to an array of UnicodeStrings containing the
     *                      individual resource items themselves.  itemTags[i] will
     *                      contain the tag corresponding to items[i].  The caller DOES
     *                      own this array, and must delete it.
     * @param numItems      Receives the number of items in the arrays pointed to by
     *                      items and itemTags.
     * @param err           Set to U_MISSING_RESOURCE_ERROR if a resource with the
     *                      specified tag couldn't be found.
     * @draft
     */
    void                getTaggedArray( const char             *resourceTag,
                                        UnicodeString*&         itemTags,
                                        UnicodeString*&         items,
                                        int32_t&                numItems,
                                        UErrorCode&              err) const;
    
    /**
     * Return the version number associated with this ResourceBundle. This version
     * number is a string of the form MAJOR.MINOR, where MAJOR is the version number of
     * the current analytic code package, and MINOR is the version number contained in
     * the resource file as the value of the tag "Version". A change in the MINOR
     * version indicated an updated data file. A change in the MAJOR version indicates a
     * new version of the code which is not binary-compatible with the previous version.
     * If no "Version" tag is present in a resource file, the MINOR version "0" is assigned.
     *
     * For example, if the Collation sort key algorithm changes, the MAJOR version
     * increments. If the collation data in a resource file changes, the MINOR version
     * for that file increments.
     *
     * @return  A string of the form N.n, where N is the major version number,
     *          representing the code version, and n is the minor version number,
     *          representing the resource data file. The caller does not own this
     *          string.
     * @draft
     */
    const char*         getVersionNumber(void) const;

	/**
	 * Return the Locale associated with this ResourceBundle. 
	 *
	 * @return a Locale object
     * @draft
	 */
	const Locale &getLocale(void) const ;

private:
    class U_COMMON_API PathInfo {
    public:
        PathInfo();
        PathInfo(const PathInfo& source);
        PathInfo(const UnicodeString& path);
        PathInfo(const UnicodeString& path, const UnicodeString& suffix);
        PathInfo(const wchar_t* path, const wchar_t* suffix);
        ~PathInfo();

        PathInfo& operator=(const PathInfo& source);

        bool_t fileExists(const UnicodeString& localeName) const;
        UnicodeString makeCacheKey(const UnicodeString& localeName) const;
        UnicodeString makeHashkey(const UnicodeString& localeName) const;
        FileStream* openFile(const UnicodeString& localeName) const;

    private:
        static const UChar        kSeparator;
        UnicodeString                fPrefix;
        UnicodeString                fSuffix;
        wchar_t*                    fWPrefix;
        wchar_t*                    fWSuffix;
    };

private:
    friend class Locale;
    friend class RuleBasedCollator;
    friend int32_t T_ResourceBundle_countArrayItemsImplementation(const ResourceBundle* resourceBundle, 
                                  const char* resourceKey,
                                  UErrorCode& err) ;
    friend const UnicodeString** listInstalledLocalesImplementation(const char* path,
                                   int32_t* numInstalledLocales);
    friend void getTaggedArrayUCharsImplementation(
                             const ResourceBundle*   bundle,
                             const char           *resourceTag,
                             UChar const**         itemTags,
                             UChar const**         items,
                             int32_t                    maxItems,
                             int32_t&                numItems,
                             UErrorCode&              err);


    /**
     * This constructor is used by Collation to load a resource bundle from a specific
     * file, without trying other files. This is used by the Collation caching
     * mechanism.
     */
                            ResourceBundle( const UnicodeString&    path,
                                            const UnicodeString&    localeName,
                                            UErrorCode&              status);

    /**
     * Return a list of all installed locales. This function returns a list of the IDs
     * of all locales represented in the directory specified by this ResourceBundle. It
     * depends on that directory having an "Index" tagged-list item in its "index.txt"
     * file; it parses that list to determine its return value (therefore, that list
     * also has to be up to date). This function is static.
     *
     * This function is the implementation of the Locale::listInstalledLocales()
     * function. It's private because the API for it real;ly belongs in Locale.
     *
     * @param path                 The path to the locale data files. The function will
     *                             look here for "index.txt".
     * @param numInstalledLocales  Receives the number of installed locales, according
     *                             to the Index resource in index.txt.
     * @return                     A list of the installed locales, as a pointer to an
     *                             array of UnicodeStrings. This storage is not owned by
     *                             the caller, who must not delete it. The information
     *                             in this list is derived from the Index resource in
     *                             default.txt, which must be kept up to date.
     */
    static const UnicodeString* listInstalledLocales(const UnicodeString& path,
                                                     int32_t&   numInstalledLocales);

    /**
     * Retrieve a ResourceBundle from the cache. Return NULL if not found.
     */
    static const UHashtable* getFromCache(const PathInfo& path,
                                         const UnicodeString& localeName,
                     ResourceBundleCache* someCache);

    static const UHashtable* getFromCacheWithFallback(const PathInfo& path,
                                                     const UnicodeString& desiredLocale,
                                                     UnicodeString& returnedLocale,
                             ResourceBundleCache* someCache,
                                                     UErrorCode& error);

    /**
     * Handlers which are passed to parse() have this signature.
     */
    typedef void (*Handler)(const UnicodeString& localeName,
                            UHashtable* hashtable,
                            void* context,
                ResourceBundleCache* someCache);

    /**
     * Parse a file, storing the resource data in the cache.
     */
    static void parse(const PathInfo& path, 
              const UnicodeString& localeName,
                      Handler handler,
                      void* context,
              ResourceBundleCache* someCache,
                      UErrorCode &error);

    /**
     * If the given file exists and has not been parsed, then parse it (caching the
     * resultant data) and return true.
     */
    static bool_t parseIfUnparsed(const PathInfo& path,
                                const UnicodeString& locale,
                                ResourceBundleCache* fCache,
                  VisitedFileCache* vCache,
                  UErrorCode& error);

    const UHashtable* getHashtableForLocale(const UnicodeString& localeName,
                                           UnicodeString& returnedLocale,
                                           UErrorCode& err);

    const UHashtable* getHashtableForLocale(const UnicodeString& desiredLocale,
                                           UErrorCode& error);

    const ResourceBundleData* getDataForTag(const char *tag,
                                            UErrorCode& err) const;

    void constructForLocale(const PathInfo& path,
                            const Locale& locale,
                            UErrorCode& error);

    static void addToCache(const UnicodeString& localeName,
                           UHashtable* hashtable,
                           void* context,
               ResourceBundleCache* someCache);

    static void saveCollationHashtable(const UnicodeString& localeName,
                                       UHashtable* hashtable,
                                       void* context,
                       ResourceBundleCache* cache);
private:
    /**
     * This internal class iterates over the fallback and/or default locales. It
     * progresses as follows: Specific: language+country+variant language+country
     * language Default: language+country+variant language+country language Root:
     */
    class LocaleFallbackIterator
    {
    public:
        LocaleFallbackIterator(const UnicodeString& startingLocale,
                               const UnicodeString& root,
                               bool_t useDefaultLocale);

        const UnicodeString& getLocale(void) const { return fLocale; }

        bool_t nextLocale(UErrorCode& status);

    private:
        void chopLocale(void);

        UnicodeString fLocale;
        UnicodeString fDefaultLocale;
        UnicodeString fRoot;
        bool_t fUseDefaultLocale;
        bool_t fTriedDefaultLocale;
        bool_t fTriedRoot;
    };

private:
    static const char*          kDefaultSuffix;
    static const int32_t        kDefaultSuffixLen;
    static const char*          kDefaultFilename;
    static const char*          kDefaultLocaleName;
    static const char*          kIndexLocaleName;
    static const char*          kIndexFilename;
    static const char*          kIndexTag;

    static const char*          kDefaultMinorVersion;
    static const char*          kVersionSeparator;
    static const char*          kVersionTag;

    static ResourceBundleCache* fgUserCache;
    static VisitedFileCache*    fgUserVisitedFiles;

    ResourceBundleCache* fgCache;
    VisitedFileCache*    fgVisitedFiles;

    /**
     * Data members. The ResourceBundle object is kept lightweight by having the fData[]
     * array entries be non-owned pointers. The cache (fgCache) owns the entries and
     * will delete them at static destruction time.
     */
    PathInfo                fPath;

    enum {                  kDataCount = 4 };
    const UHashtable*        fData[kDataCount]; // These aren't const if fIsDataOwned is true
    bool_t                  fLoaded[kDataCount];
    UErrorCode              fDataStatus[kDataCount]; // Returns the appropriate error code for each data table.
    bool_t                  fIsDataOwned;
	Locale					fRealLocale;
    LocaleFallbackIterator* fLocaleIterator;
    char*                   fVersionID;
};

#endif
