/*
*******************************************************************************
*                                                                             *
* COPYRIGHT:                                                                  *
*   (C) Copyright Taligent, Inc.,  1997                                       *
*   (C) Copyright International Business Machines Corporation,  1997-1999     *
*   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
*   US Government Users Restricted Rights - Use, duplication, or disclosure   *
*   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
*                                                                             *
*******************************************************************************
*
* 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()
*******************************************************************************
*/

#include "rbcache.h"

#include "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
 * INTERNAL_PROGRAM_ERROR if one of these checks fails.  If the input
 * data has a bad format, an INVALID_FORMAT_ERROR is returned.  If you
 * see an 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 UnicodeString 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 != USING_DEFAULT_ERROR) 
    status = USING_FALLBACK_ERROR;
  
  if(fLocale.size() == 0) {
    if(fUseDefaultLocale && !fTriedDefaultLocale) {
      fLocale = fDefaultLocale;
      fTriedDefaultLocale = TRUE;
      status = USING_DEFAULT_ERROR;
    }
    else if( ! fTriedRoot) {
      fLocale = fRoot;
      fTriedRoot = TRUE;
      status = USING_DEFAULT_ERROR;
    }
    else {
      status = MISSING_RESOURCE_ERROR;
      return FALSE;
    }
  }
  
  //  cerr << "* " << fLocale << " " << errorName(status) << endl;
  return TRUE;
}

void
ResourceBundle::LocaleFallbackIterator::chopLocale()
{
  int32_t size = fLocale.size();
  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, kDefaultSuffix),
      fRealLocaleID(localeName),
      fIsDataOwned(TRUE),
      fVersionID(0),
      fgCache(fgUserCache),
      fgVisitedFiles(fgUserVisitedFiles)
{
  status = ZERO_ERROR;
  
  int32_t i;
  for(i = 0; i < kDataCount; ++i) {
    fData[i] = 0;
    fLoaded[i] = FALSE;
  }
  
  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 = 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;
      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 = icu_mbstowcs(NULL, kDefaultSuffix, kDefaultSuffixLen);
  wchar_t* wideName = new wchar_t[wideNameLen + 1];
  icu_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;
  
  error = ZERO_ERROR;
  
  locale.getName(fRealLocaleID);
  
  // if the locale we were passed is Locale("", "", ""), that, by
  // convention, refers to the root locale (default.txt), even when
  // the system default locale is something else (otherwise there's no
  // way to get to it).  We can accomplish this by changing the locale
  // name to "default" here.  I'm not sure this is the best way to do
  // this, but it's simple and it works.
  if(fRealLocaleID.size() == 0)
    fRealLocaleID = kDefaultLocaleName;
  
  for(i = 1; i < kDataCount; ++i) {
    fData[i] = 0;
    fLoaded[i] = FALSE;
  }
  
  UnicodeString returnedLocale;
  error = ZERO_ERROR;
  fData[0] = getHashtableForLocale(fRealLocaleID, returnedLocale, error);
  fLoaded[0] = TRUE;
  if(SUCCESS(error)) 
    fRealLocaleID = returnedLocale;
  
  fLocaleIterator = new LocaleFallbackIterator(fRealLocaleID, 
					       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(FAILURE(error)) return 0;

  error = 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
  // 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 = ZERO_ERROR;

  for(;;) {
    // Build a filename for the locale.
    if(parseIfUnparsed(fPath, iterator.getLocale(), 
		       fgCache, fgVisitedFiles, error)) {
      if(FAILURE(error)) 
	return 0;
      
      error = ZERO_ERROR;
      h = getFromCacheWithFallback(fPath, desiredLocale, 
				   returnedLocale, fgCache, error);
      didTryCacheWithFallback = TRUE;
      if(h != 0 && SUCCESS(error)) 
	return h;
    }
    
    if(!iterator.nextLocale(fileError)) {
      error = 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 = 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(FAILURE(error)) 
    return 0;
  error = 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 = ZERO_ERROR;
    if(parseIfUnparsed(fPath, iterator.getLocale(), 
		       fgCache, fgVisitedFiles, parseError)) {
      if(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(FAILURE(error)) 
    return 0;
  error = 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 UnicodeString& tag,
			      UErrorCode& err) const
{
  // 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)) {
	nonconst->fData[i] = 
	  nonconst->getHashtableForLocale(fLocaleIterator->getLocale(), err);
      }
    }
    
    if(fData[i] != 0) {
      const ResourceBundleData* s = 
	(const ResourceBundleData*)uhash_get(fData[i], 
					     tag.hashCode() & 0x7FFFFFFF);
      if(s != 0) {
	err = ZERO_ERROR;
	return s;
      }
    }
  }
  
#ifdef _DEBUG
  //  cerr << "Failed to find tag " << tag << " in " << fPath << fRealLocaleID << fFilenameSuffix << endl;
  //  cerr << *this;
#endif
  err = MISSING_RESOURCE_ERROR;
  return 0;
}

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

const UnicodeString*
ResourceBundle::getString(  const UnicodeString&    resourceTag,
                            UErrorCode&              err) const
{
  if(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 = MISSING_RESOURCE_ERROR;
  return NULL;
}

const UnicodeString*
ResourceBundle::getStringArray( const UnicodeString&    resourceTag,
                                int32_t&                count,
                                UErrorCode&              err) const
{
  if(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 = MISSING_RESOURCE_ERROR;
  return 0;
}

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

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

const UnicodeString*
ResourceBundle::getArrayItem(   const UnicodeString&    resourceTag,
                                int32_t                 index,
                                UErrorCode&              err) const
{
  if(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 = MISSING_RESOURCE_ERROR;
  return NULL;
}

const UnicodeString** 
ResourceBundle::get2dArray(const UnicodeString&   resourceTag,
			   int32_t&             rowCount,
			   int32_t&             columnCount,
			   UErrorCode&           err) const
{
  if(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 = MISSING_RESOURCE_ERROR;
  return 0;
}

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

const UnicodeString*
ResourceBundle::get2dArrayItem(const UnicodeString&    resourceTag,
			       int32_t              rowIndex,
			       int32_t              columnIndex,
			       UErrorCode&           err) const
{
  if(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 = MISSING_RESOURCE_ERROR;
  return NULL;
}

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

const UnicodeString*
ResourceBundle::getTaggedArrayItem( const UnicodeString&    resourceTag,
                                    const UnicodeString&    itemTag,
                                    UErrorCode&              err) const
{
  if(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 = MISSING_RESOURCE_ERROR;
  return NULL;
}

extern "C" void 
T_ResourceBundle_getTaggedArrayUChars(const ResourceBundle*   bundle,
				      const UnicodeString&    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 UnicodeString&    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(FAILURE(err)) 
    return;

  const ResourceBundleData* data = bundle->getDataForTag(resourceTag, err);
  if(FAILURE(err) || data == 0 
     || data->getDynamicClassID() != TaggedList::getStaticClassID()) {
    err = 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 UnicodeString&    resourceTag,
                                UnicodeString*&         itemTags,
                                UnicodeString*&         items,
                                int32_t&                numItems,
                                UErrorCode&              err) const
{
  if(FAILURE(err)) 
    return;

  const ResourceBundleData* data = getDataForTag(resourceTag, err);
  if(FAILURE(err) || data == 0 
     || data->getDynamicClassID() != TaggedList::getStaticClassID()) {
    err = 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 = 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 = icu_strlen(ICU_VERSION);
    int32_t minor_len = 0;
    if(SUCCESS(status) && minor_version.size() > 0) 
      minor_len = minor_version.size();
    len += (minor_len > 0) ? minor_len : 1 /*==icu_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]; 
    
    icu_strcpy(fVersionID, ICU_VERSION);
    icu_strcat(fVersionID, kVersionSeparator);
    if(minor_len > 0) {
      minor_version.extract(0, minor_len, fVersionID + len - minor_len);
      fVersionID[len] =  0;
    }
    else {
      icu_strcat(fVersionID, kDefaultMinorVersion);
    }
  }
  return fVersionID;
}

const UnicodeString*
ResourceBundle::listInstalledLocales(const UnicodeString& path,
                                     int32_t&   numInstalledLocales)
{
  const UHashtable* h = getFromCache(PathInfo(path, kDefaultSuffix), 
				     kIndexLocaleName, fgUserCache);
  
  if(h == 0) {
    UErrorCode error = ZERO_ERROR;
    if(parseIfUnparsed(PathInfo(path, kDefaultSuffix), 
		       kIndexFilename, fgUserCache, 
		       fgUserVisitedFiles, error)) {
      h = getFromCache(PathInfo(path, kDefaultSuffix), 
		       kIndexLocaleName, fgUserCache);
    }
  }
  
  if(h != 0) {
    UnicodeString ukIndexTag = 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(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(FAILURE(err)) 
    return 0;

  if(!resourceKey) {
    err = ILLEGAL_ARGUMENT_ERROR;
    return 0;
  }
  const ResourceBundleData* data  = resourceBundle->getDataForTag(resourceKey,
								  err);
  if(FAILURE(err)) 
    return 0;
  
  ClassID 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 = 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;
  UHashtable *data;
  
  if (FAILURE(status)) return;
  
  f = path.openFile(locale);
  if(f == 0) {
    status = FILE_ACCESS_ERROR;
    return;
  }
  
  /* Get the data from the compiled resource bundle file */
  data = rb_parse(f, localeName, status);

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

  if(FAILURE(status)) {
    return;
  }

  /* 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 = ZERO_ERROR;
  Mutex lock;
  if(uhash_get(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF) == 0) {
    uhash_putKey(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF, 
		 hashtable, &err);
  }
}

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[icu_wcslen(source.fWPrefix)+1];
    fWSuffix = new wchar_t[icu_wcslen(source.fWSuffix)+1];
    icu_wcscpy(fWPrefix, source.fWPrefix);
    icu_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[icu_wcslen(path)+1];
  fWSuffix = new wchar_t[icu_wcslen(suffix)+1];
  icu_wcscpy(fWPrefix, path);
  icu_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[icu_wcslen(source.fWPrefix)+1];
      tempSuff = new wchar_t[icu_wcslen(source.fWSuffix)+1];
      icu_wcscpy(tempPref, source.fWPrefix);
      icu_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 = icu_wcstombs(NULL, fWPrefix, ((size_t)-1) >> 1);
    size_t suffSize = icu_wcstombs(NULL, fWSuffix, ((size_t)-1) >> 1);
    size_t tempSize = icu_max((int32_t)prefSize, (int32_t)suffSize);
    char *temp = new char[tempSize + 1];

    tempSize = icu_wcstombs(temp, fWPrefix, prefSize);
    temp[tempSize] = 0;
    key += UnicodeString(temp);
    
    key += name;
    
    tempSize = icu_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 = icu_wcstombs(NULL, fWPrefix, ((size_t)-1) >> 1);
    size_t suffSize = icu_wcstombs(NULL, fWSuffix, ((size_t)-1) >> 1);
    size_t tempSize = icu_max((int32_t)prefSize, (int32_t)suffSize);
    char *temp = new char[tempSize + 1];
    
    tempSize = icu_wcstombs(temp, fWSuffix, suffSize);
    temp[tempSize] = 0;
    key += UnicodeString(temp);
    
    key += kSeparator;
    
    tempSize = icu_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.size();
    char* temp = new char[nameSize + 1];
    localeName.extract(0, nameSize, temp);
    temp[nameSize] = 0;
    int32_t wideNameLen = icu_mbstowcs(NULL, temp, nameSize);
    wchar_t* wideName = new wchar_t[wideNameLen + 1];
    icu_mbstowcs(wideName, temp, nameSize);
    wideName[wideNameLen] = 0;
    delete [] temp;
    
    size_t prefLen = icu_wcslen(fWPrefix);
    size_t suffLen = icu_wcslen(fWSuffix);
    
    int32_t destSize = prefLen + suffLen + wideNameLen;
    wchar_t* dest = new wchar_t[destSize + 1];
    icu_wcscpy(dest, fWPrefix);
    dest[prefLen] = 0;
    
    icu_wcscat(dest, wideName);
    dest[prefLen + wideNameLen] = 0;
    
    icu_wcscat(dest, fWSuffix);
    dest[destSize] = 0;
    
    int32_t fmodeLen = icu_mbstowcs(NULL, "rb", 2);
    wchar_t* fmode = new wchar_t[fmodeLen + 1];
    icu_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.size();
    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
