/*
**********************************************************************
*   Copyright (C) 1997-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*
* File resbund.cpp
*
* Modification History:
*
*   Date        Name        Description
*   02/05/97    aliu        Fixed bug in chopLocale.  Added scanForLocaleInFile
*                           based on code taken from scanForLocale.  Added
*                           constructor which attempts to read resource bundle
*                           from a specific file, without searching other files.
*   02/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.
*   03/04/97    aliu        Modified to use ExpandingDataSink objects instead of
*                           the highly inefficient ostrstream objects.
*   03/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.
*   03/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.  Improved error handling to detect
*                           duplicate tags and subtags.
*   04/07/97    aliu        Fixed bug in getHashtableForLocale().  Fixed handling of
*                           failing UErrorCode values on entry to API methods.
*                           Fixed bugs in getArrayItem() for negative indices.
*   04/29/97    aliu        Update to use new Hashtable deletion protocol.
*   05/06/97    aliu        Flattened kTransitionTable for HP compiler.  Fixed usage of
*                           CharString.
* 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.
* 06/22/99      stephen     Added missing T_FileStream_close in parse()
* 11/09/99		weiv		Added getLocale(), rewritten constructForLocale()
*******************************************************************************
*/

#include "rbcache.h"

#include "unicode/resbund.h"
#include "mutex.h"

#include "unistrm.h"
#include "filestrm.h"
#include "cstring.h"
#include "uhash.h"

#include "rbdata.h"
#include "rbread.h"

#include <iostream.h>
#include <string.h>
#include <wchar.h>

/*-----------------------------------------------------------------------------
 * Implementation Notes
 *
 * Resource bundles are read in once, and thereafter cached.
 * ResourceBundle statically keeps track of which files have been
 * read, so we are guaranteed that each file is read at most once.
 * Resource bundles can be loaded from different data directories and
 * will be treated as distinct, even if they are for the same locale.
 *
 * Resource bundles are lightweight objects, which have pointers to
 * one or more shared Hashtable objects containing all the data.
 * Copying would be cheap, but there is no copy constructor, since
 * there wasn't one in the original API.
 *
 * The ResourceBundle parsing mechanism is implemented as a transition
 * network, for easy maintenance and modification.  The network is
 * implemented as a matrix (instead of in code) to make this even
 * easier.  The matrix contains Transition objects.  Each Transition
 * object describes a destination node and an action to take before
 * moving to the destination node.  The source node is encoded by the
 * index of the object in the array that contains it.  The pieces
 * needed to understand the transition network are the enums for node
 * IDs and actions, the parse() method, which walks through the
 * network and implements the actions, and the network itself.  The
 * network guarantees certain conditions, for example, that a new
 * resource will not be closed until one has been opened first; or
 * that data will not be stored into a TaggedList until a TaggedList
 * has been created.  Nonetheless, the code in parse() does some
 * consistency checks as it runs the network, and fails with an
 * U_INTERNAL_PROGRAM_ERROR if one of these checks fails.  If the input
 * data has a bad format, an U_INVALID_FORMAT_ERROR is returned.  If you
 * see an U_INTERNAL_PROGRAM_ERROR the transition matrix has a bug in
 * it.
 *
 * Old functionality of multiple locales in a single file is still
 * supported.  For this reason, LOCALE names override FILE names.  If
 * data for en_US is located in the en.txt file, once it is loaded,
 * the code will not care where it came from (other than remembering
 * which directory it came from).  However, if there is an en_US
 * resource in en_US.txt, that will take precedence.  There is no
 * limit to the number or type of resources that can be stored in a
 * file, however, files are only searched in a specific way.  If
 * en_US_CA is requested, then first en_US_CA.txt is searched, then
 * en_US.txt, then en.txt, then default.txt.  So it only makes sense
 * to put certain locales in certain files.  In this example, it would
 * be logical to put en_US_CA, en_US, and en into the en.txt file,
 * since they would be found there if asked for.  The extreme example
 * is to place all locale resources into default.txt, which should
 * also work.
 *
 * Inheritance is implemented.  For example, xx_YY_zz inherits as
 * follows: xx_YY_zz, xx_YY, xx, default.  Inheritance is implemented
 * as an array of hashtables.  There will be from 1 to 4 hashtables in
 * the array.
 *
 * Fallback files are implemented.  The fallback pattern is Language
 * Country Variant (LCV) -> LC -> L.  Fallback is first done for the
 * requested locale.  Then it is done for the default locale, as
 * returned by Locale::getDefault().  Then the special file
 * default.txt is searched for the default locale.  The overall FILE
 * fallback path is LCV -> LC -> L -> dLCV -> dLC -> dL -> default.
 *
 * Note that although file name searching includes the default locale,
 * once a ResourceBundle object is constructed, the inheritance path
 * no longer includes the default locale.  The path is LCV -> LC -> L
 * -> default.
 *
 * File parsing is lazy.  Nothing is parsed unless it is called for by
 * someone.  So when a ResourceBundle for xx_YY_zz is constructed,
 * only that locale is parsed (along with anything else in the same
 * file).  Later, if the FooBar tag is asked for, and if it isn't
 * found in xx_YY_zz, then xx_YY.txt will be parsed and checked, and
 * so forth, until the chain is exhausted or the tag is found.
 *
 * Thread-safety is implemented around caches, both the cache that
 * stores all the resouce data, and the cache that stores flags
 * indicating whether or not a file has been visited.  These caches
 * delete their storage at static cleanup time, when the process
 * quits.
 *
 * ResourceBundle supports TableCollation as a special case.  This
 * involves having special ResourceBundle objects which DO own their
 * data, since we don't want large collation rule strings in the
 * ResourceBundle cache (these are already cached in the
 * TableCollation cache).  TableCollation files (.ctx files) have the
 * same format as normal resource data files, with a different
 * interpretation, from the standpoint of ResourceBundle.  .ctx files
 * are loaded into otherwise ordinary ResourceBundle objects.  They
 * don't inherit (that's implemented by TableCollation) and they own
 * their data (as mentioned above).  However, they still support
 * possible multiple locales in a single .ctx file.  (This is in
 * practice a bad idea, since you only want the one locale you're
 * looking for, and only one tag will be present
 * ("CollationElements"), so you don't need an inheritance chain of
 * multiple locales.)  Up to 4 locale resources will be loaded from a
 * .ctx file; everything after the first 4 is ignored (parsed and
 * deleted).  (Normal .txt files have no limit.)  Instead of being
 * loaded into the cache, and then looked up as needed, the locale
 * resources are read straight into the ResourceBundle object.
 *
 * The Index, which used to reside in default.txt, has been moved to a
 * new file, index.txt.  This file contains a slightly modified format
 * with the addition of the "InstalledLocales" tag; it looks like:
 *
 * Index {
 *   InstalledLocales {
 *     ar
 *     ..
 *     zh_TW
 *   }
 * }
 */
//-----------------------------------------------------------------------------

const char* ResourceBundle::kDefaultSuffix      = ".res";
const int32_t ResourceBundle::kDefaultSuffixLen = 4;
const char* ResourceBundle::kDefaultFilename    = "default";
const char* ResourceBundle::kDefaultLocaleName  = "default";
const char* ResourceBundle::kIndexLocaleName    = "index";
const char* ResourceBundle::kIndexFilename      = "index";
const char* ResourceBundle::kIndexTag           = "InstalledLocales";

// The default minor version and the version separator must be exactly one
// character long.
const char*         ResourceBundle::kDefaultMinorVersion    = "0";
const char*         ResourceBundle::kVersionSeparator       = ".";
const char*         ResourceBundle::kVersionTag             = "Version";

ResourceBundleCache*    ResourceBundle::fgUserCache = new ResourceBundleCache();
VisitedFileCache*       ResourceBundle::fgUserVisitedFiles = new VisitedFileCache();
// allocated on the heap so we don't have to expose the definitions of
// these classes to the world

//-----------------------------------------------------------------------------

ResourceBundle::LocaleFallbackIterator::LocaleFallbackIterator(const UnicodeString& startingLocale,
							       const UnicodeString& root,
							       bool_t useDefaultLocale)
:   fLocale(startingLocale),
    fRoot(root),
    fUseDefaultLocale(useDefaultLocale),
    fTriedDefaultLocale(FALSE),
    fTriedRoot(FALSE)
{
    if (fUseDefaultLocale) Locale::getDefault().getName(fDefaultLocale);
}

bool_t
ResourceBundle::LocaleFallbackIterator::nextLocale(UErrorCode& status)
{
  if(fUseDefaultLocale)
    fTriedDefaultLocale = fTriedDefaultLocale || (fLocale == fDefaultLocale);
  
  chopLocale();
  if(status != U_USING_DEFAULT_ERROR) 
    status = U_USING_FALLBACK_ERROR;
  
  if(fLocale.length() == 0) {
    if(fUseDefaultLocale && !fTriedDefaultLocale) {
      fLocale = fDefaultLocale;
      fTriedDefaultLocale = TRUE;
      status = U_USING_DEFAULT_ERROR;
    }
    else if( ! fTriedRoot) {
      fLocale = fRoot;
      fTriedRoot = TRUE;
      status = U_USING_DEFAULT_ERROR;
    }
    else {
      status = U_MISSING_RESOURCE_ERROR;
      return FALSE;
    }
  }
  
  //  cerr << "* " << fLocale << " " << u_errorName(status) << endl;
  return TRUE;
}

void
ResourceBundle::LocaleFallbackIterator::chopLocale()
{
  int32_t size = fLocale.length();
  int32_t i;
  
  for(i = size - 1; i > 0; i--) 
    if(fLocale[i] == 0x005F/*'_'*/) 
      break;
  
  if(i < 0) 
    i = 0;
  
  fLocale.remove(i, size - i);
}

//-----------------------------------------------------------------------------

ResourceBundle::ResourceBundle( const UnicodeString&    path,
                                const Locale&           locale,
                                UErrorCode&              error)
  : fgCache(fgUserCache),
    fgVisitedFiles(fgUserVisitedFiles)
{
  constructForLocale(PathInfo(path, kDefaultSuffix), locale, error);
}

ResourceBundle::ResourceBundle( const UnicodeString&    path,
                                UErrorCode&              error)
  : fgCache(fgUserCache),
    fgVisitedFiles(fgUserVisitedFiles)
{
  constructForLocale(PathInfo(path, kDefaultSuffix), 
		     Locale::getDefault(), error);
}

/**
 * This constructor is used by TableCollation to load a resource
 * bundle from a specific file, without trying other files.  This is
 * used by the TableCollation caching mechanism.  This is not a public
 * API constructor.  
 */
ResourceBundle::ResourceBundle( const UnicodeString&    path,
                                const UnicodeString&    localeName,
                                UErrorCode&              status)
  :   fPath(path, UnicodeString(kDefaultSuffix,"")),
	  fRealLocale(localeName),
      fIsDataOwned(TRUE),
      fVersionID(0),
      fgCache(fgUserCache),
      fgVisitedFiles(fgUserVisitedFiles)
{
  status = U_ZERO_ERROR;
  
  int32_t i;
  for(i = 0; i < kDataCount; ++i) {
    fData[i] = 0;
    fLoaded[i] = FALSE;
    fDataStatus[i] = U_INTERNAL_PROGRAM_ERROR;
  }
  
  fLocaleIterator = 0;
  
  // If the file doesn't exist, return an error
  if(fPath.fileExists(localeName)) {
    parse(fPath, localeName, saveCollationHashtable, 
	  (void*)this, fgCache, status);
  }
  else {
    status = U_MISSING_RESOURCE_ERROR;
  }
  
  // Prevent further attempts to load hashtables
  for(i = 0; i < kDataCount; ++i) 
    fLoaded[i] = TRUE;
}

void
ResourceBundle::saveCollationHashtable(const UnicodeString& localeName,
				       UHashtable* hashtable,
				       void* context,
				       ResourceBundleCache* fgCache)
{
  ResourceBundle* bundle = (ResourceBundle*)context;
  for(int32_t i = 0; i < kDataCount; ++i) {
    if( ! bundle->fLoaded[i]) {
      bundle->fData[i] = hashtable;
      bundle->fLoaded[i] = TRUE;
      bundle->fDataStatus[i] = U_ZERO_ERROR; /* ??? */
      return;
    }
  }
  // Out of room; discard extra data.  We only expect to see one anyway.
  uhash_close(hashtable);
}

ResourceBundle::ResourceBundle(const wchar_t* path,
			       const Locale& locale, 
			       UErrorCode& err)
  : fgCache(fgUserCache),
    fgVisitedFiles(fgUserVisitedFiles)
{
  int32_t wideNameLen = uprv_mbstowcs(NULL, kDefaultSuffix, kDefaultSuffixLen);
  wchar_t* wideName = new wchar_t[wideNameLen + 1];
  uprv_mbstowcs(wideName, kDefaultSuffix, kDefaultSuffixLen);
  wideName[wideNameLen] = 0;
  constructForLocale(PathInfo(path, wideName), locale, err);
  delete [] wideName;
}

ResourceBundle::~ResourceBundle()
{
  delete fLocaleIterator;
  delete [] fVersionID;
  
  if(fIsDataOwned)
    for(int32_t i = 0; i < kDataCount; ++i) {
      if(fData[i]) 
	uhash_close((UHashtable*)fData[i]);
    }
}

void 
ResourceBundle::constructForLocale(const PathInfo& path,
				   const Locale& locale,
				   UErrorCode& error)
{
  int32_t i;
  fPath = path;
  fIsDataOwned = FALSE;
  fVersionID = 0;

  // fRealLocale can be inited in three ways, see 1), 2), 3)
  UnicodeString returnedLocale;
  locale.getName(returnedLocale);
  if (returnedLocale.length()!=0) {
	// 1) Desired Locale has a name
	fRealLocale = Locale(returnedLocale); 
  } else {
	// 2) Desired Locale name is empty, so we use default locale for the system
	fRealLocale = Locale(kDefaultLocaleName); 
  }
  error = U_ZERO_ERROR;
  for(i = 1; i < kDataCount; ++i) {
    fData[i] = 0;
    fDataStatus[i] = U_INTERNAL_PROGRAM_ERROR;
    fLoaded[i] = FALSE;
  }
  
  error = U_ZERO_ERROR;
  fData[0] = getHashtableForLocale(fRealLocale.getName(), returnedLocale, error);
  fLoaded[0] = TRUE;
  fDataStatus[0] = U_ZERO_ERROR;
  if(U_SUCCESS(error))
		// 3) We're unable to get the desired Locale, so we're using what is provided (fallback occured)
		fRealLocale = Locale(returnedLocale);
  
  fLocaleIterator = new LocaleFallbackIterator(fRealLocale.getName(), 
					       kDefaultLocaleName, FALSE);
}

/**
 * Return the hash table with data for the given locale.  This method employs
 * fallback both in files and in locale names.  It returns the locale name
 * which is actually used to return the data, if any.
 *
 * Parse all files found at the given path for the given path, in an effort
 * to find data for the given locale.  Use fallbacks and defaults as needed.
 * Store read in file data in the cache for future use.  Return the hashtable
 * for the given locale, if found, or 0 if not.
 */
const UHashtable* 
ResourceBundle::getHashtableForLocale(const UnicodeString& desiredLocale,
				      UnicodeString& returnedLocale,
				      UErrorCode& error)
{
  if(U_FAILURE(error)) return 0;

  error = U_ZERO_ERROR;
  const UHashtable* h = getFromCache(fPath, desiredLocale, fgCache);
  if(h != 0) {
    returnedLocale = desiredLocale;
    return h;
  }
  
  LocaleFallbackIterator iterator(desiredLocale, kDefaultFilename, TRUE);
  bool_t didTryCacheWithFallback = FALSE;
  
  // A note on fileError.  We are tracking two different error states
  // here.  One is that returned while iterating over different files.
  // For instance, when going from de_CH.txt to de.txt we will get a
  // U_USING_FALLBACK_ERROR, but we don't care -- because if de.txt
  // contains the de_CH locale, it isn't a fallback, from our
  // perspective.  Therefore we keep file associated errors in
  // fileError, apart from the error parameter.
  UErrorCode fileError = U_ZERO_ERROR;

  for(;;) {
    // Build a filename for the locale.
    if(parseIfUnparsed(fPath, iterator.getLocale(), 
		       fgCache, fgVisitedFiles, error)) {
      if(U_FAILURE(error)) 
          return 0;
      
      error = U_ZERO_ERROR;
      h = getFromCacheWithFallback(fPath, desiredLocale, 
				   returnedLocale, fgCache, error);
      didTryCacheWithFallback = TRUE;
      if(h != 0 && U_SUCCESS(error)) 
	return h;
    }
    
    if(!iterator.nextLocale(fileError)) {
      error = U_MISSING_RESOURCE_ERROR;
      break;
    }
  }
  
  // We want to try loading from the cache will fallback at least
  // once.  These lines of code handle the case in which all of the
  // fallback FILES have been loaded, so fgVisitedFiles keeps us from
  // parsing them again.  In this case we still want to make an
  // attempt to load our locale from the cache.
  if(didTryCacheWithFallback) 
    return 0;
  error = U_ZERO_ERROR;
  return getFromCacheWithFallback(fPath, desiredLocale, 
				  returnedLocale, fgCache, error);
}

/**
 * Return the hash table with data for the given locale.  This method employs
 * fallback in file names only.  If data is returned, it will be exactly for
 * the given locale.
 */
const UHashtable* 
ResourceBundle::getHashtableForLocale(const UnicodeString& desiredLocale,
				      UErrorCode& error)
{
  if(U_FAILURE(error)) 
    return 0;
  error = U_ZERO_ERROR;
  
  // First try the cache
  const UHashtable* h = getFromCache(fPath, desiredLocale, fgCache);
  if(h != 0) 
    return h;
  
  // Now try files
  LocaleFallbackIterator iterator(desiredLocale, kDefaultFilename, FALSE);
  
  for(;;) {
    UErrorCode parseError = U_ZERO_ERROR;
    if(parseIfUnparsed(fPath, iterator.getLocale(), 
		       fgCache, fgVisitedFiles, parseError)) {
      if(U_FAILURE(parseError)) {
	error = parseError;
	return 0;
      }
      
      const UHashtable* h = getFromCache(fPath, desiredLocale, fgCache);
      if(h != 0) 
	return h;
    }
    
    if(!iterator.nextLocale(error)) 
      return 0;
  }
}

/**
 * Try to retrieve a locale data hash from the cache, using fallbacks
 * if necessary.  Ultimately we will try to load the data under
 * kDefaultLocaleName.  
 */
const UHashtable* 
ResourceBundle::getFromCacheWithFallback(const PathInfo& path,
					 const UnicodeString& desiredLocale,
					 UnicodeString& returnedLocale,
					 ResourceBundleCache* fgCache,
					 UErrorCode& error)
{
  if(U_FAILURE(error)) 
    return 0;
  error = U_ZERO_ERROR;
  
  LocaleFallbackIterator iterator(desiredLocale, kDefaultLocaleName, TRUE);
  
  for(;;) {
    const UHashtable* h = getFromCache(path, iterator.getLocale(), fgCache);
    if(h != 0) {
      returnedLocale = iterator.getLocale();
      return h;
    }
    
    if(!iterator.nextLocale(error)) 
      return 0;
  }
}

/**
 * Parse the given file, if it hasn't been attempted already, and if
 * it actually exists.  Return true if a parse is attempted.  Upon
 * return, if the return value is true, the error code may be set as a
 * result of a parse failure to a failing value.  If the parse was
 * successful, additional entries may have been created in the cache.
 */
bool_t
ResourceBundle::parseIfUnparsed(const PathInfo& path,
				const UnicodeString& locale,
				ResourceBundleCache* fgCache,
				VisitedFileCache* fgVisitedFiles,
				UErrorCode& error)
{
  UnicodeString key(path.makeCacheKey(locale));
  
  if(!fgVisitedFiles->wasVisited(key) && path.fileExists(locale)) {
    parse(path, locale, addToCache, (void*)&path, fgCache, error);
    { 
      Mutex lock;
      fgVisitedFiles->markAsVisited(key);
    }
    return TRUE;
  }
  return FALSE;
}

/**
 * Given a tag, try to retrieve the data for that tag.  This method is
 * semantically const, but may actually modify this object.  All
 * public API methods such as getString() rely on getDataForTag()
 * ultimately.  This method implements inheritance of data between
 * locales.  
 */
const ResourceBundleData* 
ResourceBundle::getDataForTag(const char *tag,
			      UErrorCode& err) const
{
  err = U_ZERO_ERROR; /* just to make sure there's no fallback/etc left over */
  // Iterate over the kDataCount hashtables which may be associated with this
  // bundle.  At most we have kDataCount, but we may have as few as one.
  for(int32_t i = 0; i < kDataCount; ++i) {

  // First try to load up this hashtable, if it hasn't been loaded yet.
    if(!fLoaded[i] && fData[i] == 0) {
      ResourceBundle* nonconst = (ResourceBundle*)this;
      nonconst->fLoaded[i] = TRUE;
      if(fLocaleIterator->nextLocale(err)) {
	UErrorCode getHashtableStatus = U_ZERO_ERROR;

	nonconst->fDataStatus[i] = err;
	nonconst->fData[i] = 
	  nonconst->getHashtableForLocale(fLocaleIterator->getLocale(), getHashtableStatus);
      }
    }

    
    if(fData[i] != 0) {
      const ResourceBundleData* s = 
	(const ResourceBundleData*)uhash_get(fData[i], 
					     UnicodeString(tag, "").hashCode() & 0x7FFFFFFF);
      if(s != 0) {
	err = fDataStatus[i];  /* restore the error from the original lookup. */
	return s;
      }
    }
  }
  
#ifdef _DEBUG
  //  cerr << "Failed to find tag " << tag << " in " << fPath << fRealLocaleID << fFilenameSuffix << endl;
  //  cerr << *this;
#endif
  err = U_MISSING_RESOURCE_ERROR;
  return 0;
}

void
ResourceBundle::getString(  const char             *resourceTag,
                            UnicodeString&          theString,
                            UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return;
  
  const UnicodeString* temp = getString(resourceTag, err);
  if(U_SUCCESS(err))
    theString = *temp;
}

const UnicodeString*
ResourceBundle::getString(  const char              *resourceTag,
                            UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return NULL;
  
  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(data != 0 
     && data->getDynamicClassID() == StringList::getStaticClassID() 
     && ((StringList*)data)->fCount == 1) {
    return &(((StringList*)data)->fStrings[0]);
  }
  else err = U_MISSING_RESOURCE_ERROR;
  return NULL;
}

const UnicodeString*
ResourceBundle::getStringArray( const char             *resourceTag,
                                int32_t&                count,
                                UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return 0;
  
  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(data != 0 
     && data->getDynamicClassID() == StringList::getStaticClassID()) {
    count = ((StringList*)data)->fCount;
    return ((StringList*)data)->fStrings;
  }
  err = U_MISSING_RESOURCE_ERROR;
  return 0;
}

void
ResourceBundle::getArrayItem(   const char             *resourceTag,
                                int32_t                 index,
                                UnicodeString&          theArrayItem,
                                UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return;

  const UnicodeString* temp = getArrayItem(resourceTag, index, err);
  if(U_SUCCESS(err))
    theArrayItem = *temp;
}

const UnicodeString*
ResourceBundle::getArrayItem(   const char             *resourceTag,
                                int32_t                 index,
                                UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return NULL;

  // Casting to unsigned turns a signed value into a large unsigned
  // value.  This allows us to do one comparison to check that 0 <=
  // index < count, instead of two separate comparisons for each index
  // check.
  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(data != 0 
     && data->getDynamicClassID() == StringList::getStaticClassID() 
     && (uint32_t)index < (uint32_t)((StringList*)data)->fCount) {
    return &(((StringList*)data)->fStrings[index]);
  }
  else
    err = U_MISSING_RESOURCE_ERROR;
  return NULL;
}

const UnicodeString** 
ResourceBundle::get2dArray(const char *resourceTag,
			   int32_t&             rowCount,
			   int32_t&             columnCount,
			   UErrorCode&           err) const
{
  if(U_FAILURE(err)) 
    return 0;

  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(data != 0 
     && data->getDynamicClassID() == String2dList::getStaticClassID()) {
    String2dList *list = (String2dList*)data;
    rowCount = list->fRowCount;
    columnCount = list->fColCount;
    // Why is this cast required? It shouldn't be. [LIU]
    return (const UnicodeString**)list->fStrings; 
  }
  err = U_MISSING_RESOURCE_ERROR;
  return 0;
}

void
ResourceBundle::get2dArrayItem(const char *resourceTag,
			       int32_t              rowIndex,
			       int32_t              columnIndex,
			       UnicodeString&       theArrayItem,
			       UErrorCode&           err) const
{
  if(U_FAILURE(err)) 
    return;
  
  const UnicodeString* temp = get2dArrayItem(resourceTag, rowIndex, 
					     columnIndex, err);
  
  if(U_SUCCESS(err))
    theArrayItem = *temp;
}

const UnicodeString*
ResourceBundle::get2dArrayItem(const char *resourceTag,
			       int32_t              rowIndex,
			       int32_t              columnIndex,
			       UErrorCode&           err) const
{
  if(U_FAILURE(err)) 
    return NULL;

  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(data != 0 
     && data->getDynamicClassID() == String2dList::getStaticClassID()) {
    String2dList *list = (String2dList*)data;
    // Casting to unsigned turns a signed value into a large unsigned
    // value.  This allows us to do one comparison to check that 0 <=
    // index < count, instead of two separate comparisons for each
    // index check.
    if(((uint32_t)rowIndex) < (uint32_t)(list->fRowCount) 
       && ((uint32_t)columnIndex) < (uint32_t)(list->fColCount)) {
      return &(list->fStrings[rowIndex][columnIndex]);
    }
  }
  err = U_MISSING_RESOURCE_ERROR;
  return NULL;
}

void
ResourceBundle::getTaggedArrayItem( const char             *resourceTag,
                                    const UnicodeString&    itemTag,
                                    UnicodeString&          theArrayItem,
                                    UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return;
  
  const UnicodeString* temp = getTaggedArrayItem(resourceTag, itemTag, err);
    
  if(U_SUCCESS(err)) 
    theArrayItem = *temp;
}

const UnicodeString*
ResourceBundle::getTaggedArrayItem( const char             *resourceTag,
                                    const UnicodeString&    itemTag,
                                    UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return NULL;

  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(data != 0 
     && data->getDynamicClassID() == TaggedList::getStaticClassID()) {
    const UnicodeString* s = ((TaggedList*)data)->get(itemTag);
    if(s != 0)  
      return s;
  }
  
  err = U_MISSING_RESOURCE_ERROR;
  return NULL;
}

extern "C" void 
T_ResourceBundle_getTaggedArrayUChars(const ResourceBundle*   bundle,
				      const char           *resourceTag,
				      UChar const**         itemTags,
				      UChar const**         items,
				      int32_t                    maxItems,
				      int32_t*                numItems,
				      UErrorCode*              err)
{
  // this function is here solely because there seems to be no way to
  // declare an extern "C" function as a friend of a class.  So we
  // have a function with ordinary C++ linkage that is a friend of
  // ResourceBundle and does the work, and a hidden method with C
  // linkage that calls it and is used by the C wrappers.  Disgusting,
  // isn't it?  This was all rtg's idea.  --jf 12/16/98
  getTaggedArrayUCharsImplementation(bundle, resourceTag,
				     itemTags, items, maxItems, 
				     *numItems, *err);
}

void 
getTaggedArrayUCharsImplementation( const ResourceBundle*   bundle,
				    const char           *resourceTag,
				    UChar const**         itemTags,
				    UChar const**     items,
				    int32_t        maxItems,
				    int32_t&          numItems,
				    UErrorCode&              err)
{
  // this is here solely to support the C implementation of
  // ResourceBundle.  This function isn't defined as part of the API;
  // The C wrappers know it's here and define it on their own.  --jf
  // 12/16/98
  if(U_FAILURE(err)) 
    return;

  const ResourceBundleData* data = bundle->getDataForTag(resourceTag, err);
  if(U_FAILURE(err) || data == 0 
     || data->getDynamicClassID() != TaggedList::getStaticClassID()) {
    err = U_MISSING_RESOURCE_ERROR;
    return;
  }
  
  UHashtable* forEnumerationValues = ((TaggedList*)data)->fHashtableValues;
  void*                   value;
  
  numItems = 0;
  int32_t pos = -1;
  while(value = uhash_nextElement(forEnumerationValues, &pos)) {
    if(numItems < maxItems) {
      itemTags[numItems] = 
	((const UnicodeString*)uhash_get(((TaggedList*)data)->fHashtableKeys,
					 numItems+1))->getUChars();
      items[numItems] = ((const UnicodeString*)value)->getUChars();
    }
    numItems++;
  }
}

void
ResourceBundle::getTaggedArray( const char             *resourceTag,
                                UnicodeString*&         itemTags,
                                UnicodeString*&         items,
                                int32_t&                numItems,
                                UErrorCode&              err) const
{
  if(U_FAILURE(err)) 
    return;

  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(U_FAILURE(err) || data == 0 
     || data->getDynamicClassID() != TaggedList::getStaticClassID()) {
    err = U_MISSING_RESOURCE_ERROR;
    return;
  }
  
  // go through the resource once and count how many items there are
  
  numItems = uhash_size(((TaggedList*)data)->fHashtableValues);
  
  // now create the string arrays and go through the hash table again, this
  // time copying the keys and values into the string arrays
  itemTags = new UnicodeString[numItems];
  items = new UnicodeString[numItems];
  
  UHashtable* forEnumerationValues = ((TaggedList*)data)->fHashtableValues;
  void*                   value;
    
  numItems = 0;
  int32_t pos = -1;
  while(value = uhash_nextElement(forEnumerationValues, &pos)) {
    itemTags[numItems] = 
      *((const UnicodeString*)uhash_get(((TaggedList*)data)->fHashtableKeys, 
					numItems+1));
    items[numItems] = *((const UnicodeString*)value);
    numItems++;
  }
}

const char*
ResourceBundle::getVersionNumber()  const
{
  if(fVersionID == 0) {
    // If the version ID has not been built yet, then do so.  Retrieve
    // the minor version from the file.
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString minor_version;
    getString(kVersionTag, minor_version, status);
    
    // Determine the length of of the final version string.  This is
    // the length of the major part + the length of the separator
    // (==1) + the length of the minor part (+ 1 for the zero byte at
    // the end).
    int32_t len = uprv_strlen(U_ICU_VERSION);
    int32_t minor_len = 0;
    if(U_SUCCESS(status) && minor_version.length() > 0) 
      minor_len = minor_version.length();
    len += (minor_len > 0) ? minor_len : 1 /*==uprv_strlen(kDefaultMinorVersion)*/;
    ++len; // Add length of separator
    
    // Allocate the string, and build it up.
    // + 1 for zero byte
    ((ResourceBundle*)this)->fVersionID = new char[1 + len]; 
    
    uprv_strcpy(fVersionID, U_ICU_VERSION);
    uprv_strcat(fVersionID, kVersionSeparator);
    if(minor_len > 0) {
      minor_version.extract(0, minor_len, fVersionID + len - minor_len);
      fVersionID[len] =  0;
    }
    else {
      uprv_strcat(fVersionID, kDefaultMinorVersion);
    }
  }
  return fVersionID;
}

const UnicodeString*
ResourceBundle::listInstalledLocales(const UnicodeString& path,
                                     int32_t&   numInstalledLocales)
{
  const UnicodeString kDefaultSuffixString = UnicodeString(kDefaultSuffix,"");


  const UHashtable* h = getFromCache(PathInfo(path, kDefaultSuffixString), 
				     UnicodeString(kIndexLocaleName,""), fgUserCache);
  
  if(h == 0) {
    UErrorCode error = U_ZERO_ERROR;
    if(parseIfUnparsed(PathInfo(path, kDefaultSuffixString), 
		       UnicodeString(kIndexFilename,""), fgUserCache, 
		       fgUserVisitedFiles, error)) {
      h = getFromCache(PathInfo(path, kDefaultSuffixString), 
		       UnicodeString(kIndexLocaleName,""), fgUserCache);
    }
  }
  
  if(h != 0) {
    UnicodeString ukIndexTag = UnicodeString(kIndexTag,"");
    ResourceBundleData *data = 
      (ResourceBundleData*) uhash_get(h, ukIndexTag.hashCode() & 0x7FFFFFFF);
    if(data != 0 
       && data->getDynamicClassID() == StringList::getStaticClassID()) {
      numInstalledLocales = ((StringList*)data)->fCount;
      return ((StringList*)data)->fStrings;
    }
  }
  
  numInstalledLocales = 0;
  return 0;
}

extern "C" const UnicodeString** 
T_ResourceBundle_listInstalledLocales(const char* path,
				      int32_t* numInstalledLocales) 
{
  // this is here solely to support the C implementation of Locale.
  // This function isn't defined as part of the API; T_Locale knows
  // it's here and defines it on its own.  --rtg 11/28/98
  
  return listInstalledLocalesImplementation(path, numInstalledLocales);
}

const UnicodeString** 
listInstalledLocalesImplementation(const char* path,
				   int32_t* numInstalledLocales) 
{
  // this function is here solely because there seems to be no way to
  // declare an extern "C" function as a friend of a class.  So we
  // have a function with ordinary C++ linkage that is a friend of
  // ResourceBundle and does the work, and a hidden method with C
  // linkage that calls it and is used by the C implementation of
  // Locale.  Disgusting, isn't it?  --rtg 11/30/98
  const UnicodeString* array = (ResourceBundle::listInstalledLocales(UnicodeString(path,""), *numInstalledLocales));
  const UnicodeString**  arrayOfPtrs = (const UnicodeString**) new UnicodeString*[*numInstalledLocales];
  for(int i = 0; i < *numInstalledLocales; i++)
    arrayOfPtrs[i] = &array[i];
  return arrayOfPtrs;
}

int32_t
T_ResourceBundle_countArrayItemsImplementation(const ResourceBundle* resourceBundle, 
					       const char* resourceKey,
					       UErrorCode& err) 
{
  if(U_FAILURE(err)) 
    return 0;

  if(!resourceKey) {
    err = U_ILLEGAL_ARGUMENT_ERROR;
    return 0;
  }
  const ResourceBundleData* data  = resourceBundle->getDataForTag(resourceKey,
								  err);
  if(U_FAILURE(err)) 
    return 0;
  
  UClassID rbkeyClassID = data->getDynamicClassID();
  int32_t numItems = 0;
  
  if(rbkeyClassID == StringList::getStaticClassID()) {
    numItems = ((StringList*)data)->fCount;
  }
  else if(rbkeyClassID == TaggedList::getStaticClassID()) {
    numItems =  uhash_size(((TaggedList*)data)->fHashtableValues);
  }
  else if(rbkeyClassID == String2dList::getStaticClassID()) {
    numItems = ((String2dList*)data)->fRowCount; 
  }
  else {
    err = U_MISSING_RESOURCE_ERROR;
    return 0;
  }
  
  return numItems;
}


extern "C" int32_t 
T_ResourceBundle_countArrayItems(const ResourceBundle* resourceBundle, 
				 const char* resourceKey,
				 UErrorCode* err) 
{
  return T_ResourceBundle_countArrayItemsImplementation(resourceBundle,
							resourceKey,
							*err);
}

/**
 * Retrieve a ResourceBundle from the cache.  Return NULL if not found.
 */
const UHashtable* 
ResourceBundle::getFromCache(const PathInfo& path,
			     const UnicodeString& localeName,
			     ResourceBundleCache* fgCache)
{
    UnicodeString keyname(path.makeHashkey(localeName));
    Mutex lock;
    
    return (const UHashtable*)
      uhash_get(fgCache->hashTable, keyname.hashCode() & 0x7FFFFFFF);
}

/**
 * Parse a file, storing the resource data in the cache.
 */
void 
ResourceBundle::parse(const PathInfo& path,
		      const UnicodeString& locale,
		      Handler handler,
		      void *context,
		      ResourceBundleCache *fgCache,
		      UErrorCode& status)
{
  FileStream *f;
  UnicodeString localeName, realLocale;
  UHashtable *data;
  
  if (U_FAILURE(status)) return;
  
  f = path.openFile(locale);
  if(f == 0) {
    status = U_FILE_ACCESS_ERROR;
    return;
  }
  
  realLocale = locale;
  /* Get the data from the compiled resource bundle file */
  data = rb_parse(f, localeName, status);

  /* Close the file */
  T_FileStream_close(f);

  if(U_FAILURE(status)) {
    return;
  }
  /* If an alias file is encountered, parse the new locale file. */
  if (data == 0) {
      f = path.openFile(localeName);
      if(f == 0) {
        status = U_FILE_ACCESS_ERROR;
        return;
      }
      data = rb_parse(f, localeName, status);
      T_FileStream_close(f);

      if(U_FAILURE(status)) {
        return;
      }
      localeName = realLocale;
  }

  /* Invoke the handler function */
  handler(localeName, data, context, fgCache);
}

void
ResourceBundle::addToCache(const UnicodeString& localeName,
			   UHashtable* hashtable,
			   void* context,
			   ResourceBundleCache* fgCache)
{
  PathInfo *c = (PathInfo*)context;
  UnicodeString keyName(c->makeHashkey(localeName));
  UErrorCode err = U_ZERO_ERROR;
  Mutex lock;
  if(uhash_get(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF) == 0) {
    uhash_putKey(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF, 
		 hashtable, &err);
  }
}

const Locale &ResourceBundle::getLocale(void) const
{
	return fRealLocale;
}

ResourceBundle::PathInfo::PathInfo()
  : fWPrefix(NULL), fWSuffix(NULL)
{}

ResourceBundle::PathInfo::PathInfo(const PathInfo& source) 
  : fPrefix(source.fPrefix), 
    fSuffix(source.fSuffix), 
    fWPrefix(NULL), fWSuffix(NULL)
{
  if(source.fWPrefix) {
    fWPrefix = new wchar_t[uprv_wcslen(source.fWPrefix)+1];
    fWSuffix = new wchar_t[uprv_wcslen(source.fWSuffix)+1];
    uprv_wcscpy(fWPrefix, source.fWPrefix);
    uprv_wcscpy(fWSuffix, source.fWSuffix);
  }
}

ResourceBundle::PathInfo::PathInfo(const UnicodeString& path)
  : fPrefix(path), 
    fWPrefix(NULL), 
    fWSuffix(NULL)
{}

ResourceBundle::PathInfo::PathInfo(const UnicodeString& path, 
				   const UnicodeString& suffix)
  : fPrefix(path), 
    fSuffix(suffix), 
    fWPrefix(NULL), 
    fWSuffix(NULL)
{}

ResourceBundle::PathInfo::PathInfo(const wchar_t* path,
				   const wchar_t* suffix)
  : fPrefix(), 
    fSuffix(), 
    fWPrefix(NULL), 
    fWSuffix(NULL)
{
  fWPrefix = new wchar_t[uprv_wcslen(path)+1];
  fWSuffix = new wchar_t[uprv_wcslen(suffix)+1];
  uprv_wcscpy(fWPrefix, path);
  uprv_wcscpy(fWSuffix, suffix);
}

ResourceBundle::PathInfo::~PathInfo()
{
  delete [] fWPrefix;
  delete [] fWSuffix;
}

ResourceBundle::PathInfo&
ResourceBundle::PathInfo::operator=(const PathInfo& source)
{
  if(this != &source) {
    wchar_t* tempPref = NULL;
    wchar_t* tempSuff = NULL;
    if(source.fWPrefix) {
      tempPref = new wchar_t[uprv_wcslen(source.fWPrefix)+1];
      tempSuff = new wchar_t[uprv_wcslen(source.fWSuffix)+1];
      uprv_wcscpy(tempPref, source.fWPrefix);
      uprv_wcscpy(tempSuff, source.fWSuffix);
    }
    delete fWPrefix;
    fWPrefix = tempPref;
    delete fWSuffix;
    fWSuffix = tempSuff;
    fPrefix = source.fPrefix;
    fSuffix = source.fSuffix;
  }
  return *this;
}

bool_t 
ResourceBundle::PathInfo::fileExists(const UnicodeString& localeName) const
{
  FileStream *temp = openFile(localeName);
  if(temp) {
    T_FileStream_close(temp);
    return TRUE;
  }
  else {
    return FALSE;
  }
}

UnicodeString 
ResourceBundle::PathInfo::makeCacheKey(const UnicodeString& name) const
{
  if(fWPrefix) {
    UnicodeString key;
    
    size_t prefSize = uprv_wcstombs(NULL, fWPrefix, ((size_t)-1) >> 1);
    size_t suffSize = uprv_wcstombs(NULL, fWSuffix, ((size_t)-1) >> 1);
    size_t tempSize = uprv_max((int32_t)prefSize, (int32_t)suffSize);
    char *temp = new char[tempSize + 1];

    tempSize = uprv_wcstombs(temp, fWPrefix, prefSize);
    temp[tempSize] = 0;
    key += UnicodeString(temp);
    
    key += name;
    
    tempSize = uprv_wcstombs(temp, fWSuffix, suffSize);
    temp[tempSize] = 0;
    key += UnicodeString(temp);
    
    delete [] temp;
    
    return key;
  } 
  else {
    UnicodeString workingName(fPrefix);
    workingName += name;
    workingName += fSuffix;
    
    return workingName;
  }
}

UnicodeString 
ResourceBundle::PathInfo::makeHashkey(const UnicodeString& localeName) const
{
  if(fWPrefix) {
    UnicodeString key(localeName);
    
    key += kSeparator;
    
    size_t prefSize = uprv_wcstombs(NULL, fWPrefix, ((size_t)-1) >> 1);
    size_t suffSize = uprv_wcstombs(NULL, fWSuffix, ((size_t)-1) >> 1);
    size_t tempSize = uprv_max((int32_t)prefSize, (int32_t)suffSize);
    char *temp = new char[tempSize + 1];
    
    tempSize = uprv_wcstombs(temp, fWSuffix, suffSize);
    temp[tempSize] = 0;
    key += UnicodeString(temp);
    
    key += kSeparator;
    
    tempSize = uprv_wcstombs(temp, fWPrefix, prefSize);
    temp[tempSize] = 0;
    key += UnicodeString(temp);
    
    delete [] temp;
    
    return key;
  }
  else {
    UnicodeString keyName = localeName;
    keyName += kSeparator;
    keyName += fSuffix;
    keyName += kSeparator;
    keyName += fPrefix;
    return keyName;
  }
}

FileStream* 
ResourceBundle::PathInfo::openFile(const UnicodeString& localeName) const
{
  if(fWPrefix) {
    //use the wide version of fopen in TPlatformUtilities.
    int32_t nameSize = localeName.length();
    char* temp = new char[nameSize + 1];
    localeName.extract(0, nameSize, temp);
    temp[nameSize] = 0;
    int32_t wideNameLen = uprv_mbstowcs(NULL, temp, nameSize);
    wchar_t* wideName = new wchar_t[wideNameLen + 1];
    uprv_mbstowcs(wideName, temp, nameSize);
    wideName[wideNameLen] = 0;
    delete [] temp;
    
    size_t prefLen = uprv_wcslen(fWPrefix);
    size_t suffLen = uprv_wcslen(fWSuffix);
    
    int32_t destSize = prefLen + suffLen + wideNameLen;
    wchar_t* dest = new wchar_t[destSize + 1];
    uprv_wcscpy(dest, fWPrefix);
    dest[prefLen] = 0;
    
    uprv_wcscat(dest, wideName);
    dest[prefLen + wideNameLen] = 0;
    
    uprv_wcscat(dest, fWSuffix);
    dest[destSize] = 0;
    
    int32_t fmodeLen = uprv_mbstowcs(NULL, "rb", 2);
    wchar_t* fmode = new wchar_t[fmodeLen + 1];
    uprv_mbstowcs(fmode, "rb", 2);
    fmode[fmodeLen] = 0;

    FileStream* result = T_FileStream_wopen(dest, fmode);
    
    delete [] fmode;
    delete [] dest;
    delete [] wideName;
    return result;
  } 
  else {
    //open file using standard char* routines
    UnicodeString workingName(makeCacheKey(localeName));
    int32_t size = workingName.length();
    char* returnVal = new char[size + 1];
    workingName.extract(0, size, returnVal, "");
    returnVal[size] = 0;
    FileStream* result = T_FileStream_open(returnVal, "rb");
    delete [] returnVal;
    return result;
  }
}

const UChar ResourceBundle::PathInfo::kSeparator = 0xF8FF;

//eof
