1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 359d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1997-2013, International Business Machines 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File resbund.cpp 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History: 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 02/05/97 aliu Fixed bug in chopLocale. Added scanForLocaleInFile 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* based on code taken from scanForLocale. Added 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* constructor which attempts to read resource bundle 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* from a specific file, without searching other files. 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 02/11/97 aliu Added UErrorCode return values to constructors. Fixed 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* infinite loops in scanForFile and scanForLocale. 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modified getRawResourceData to not delete storage in 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* localeData and resourceData which it doesn't own. 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Added Mac compatibility #ifdefs for tellp() and 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* ios::nocreate. 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/04/97 aliu Modified to use ExpandingDataSink objects instead of 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* the highly inefficient ostrstream objects. 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/13/97 aliu Rewrote to load in entire resource bundle and store 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* it as a Hashtable of ResourceBundleData objects. 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Added state table to govern parsing of files. 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modified to load locale index out of new file distinct 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* from default.txt. 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/25/97 aliu Modified to support 2-d arrays, needed for timezone data. 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Added support for custom file suffixes. Again, needed 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* to support timezone data. Improved error handling to 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* detect duplicate tags and subtags. 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 04/07/97 aliu Fixed bug in getHashtableForLocale(). Fixed handling 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* of failing UErrorCode values on entry to API methods. 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Fixed bugs in getArrayItem() for negative indices. 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 04/29/97 aliu Update to use new Hashtable deletion protocol. 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 05/06/97 aliu Flattened kTransitionTable for HP compiler. 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Fixed usage of CharString. 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 06/11/99 stephen Removed parsing of .txt files. 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Reworked to use new binary format. 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Cleaned up. 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 06/14/99 stephen Removed methods taking a filename suffix. 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 06/22/99 stephen Added missing T_FileStream_close in parse() 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11/09/99 weiv Added getLocale(), rewritten constructForLocale() 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* March 2000 weiv complete overhaul. 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/resbund.h" 5159d709d503bab6e2b61931737e662dd293b40578ccornelius 5259d709d503bab6e2b61931737e662dd293b40578ccornelius#include "mutex.h" 5359d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h" 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h" 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uresimp.h" 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*----------------------------------------------------------------------------- 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Implementation Notes 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Resource bundles are read in once, and thereafter cached. 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ResourceBundle statically keeps track of which files have been 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * read, so we are guaranteed that each file is read at most once. 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Resource bundles can be loaded from different data directories and 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * will be treated as distinct, even if they are for the same locale. 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Resource bundles are lightweight objects, which have pointers to 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * one or more shared Hashtable objects containing all the data. 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Copying would be cheap, but there is no copy constructor, since 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * there wasn't one in the original API. 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The ResourceBundle parsing mechanism is implemented as a transition 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * network, for easy maintenance and modification. The network is 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * implemented as a matrix (instead of in code) to make this even 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * easier. The matrix contains Transition objects. Each Transition 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * object describes a destination node and an action to take before 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * moving to the destination node. The source node is encoded by the 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * index of the object in the array that contains it. The pieces 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * needed to understand the transition network are the enums for node 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * IDs and actions, the parse() method, which walks through the 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * network and implements the actions, and the network itself. The 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * network guarantees certain conditions, for example, that a new 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * resource will not be closed until one has been opened first; or 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that data will not be stored into a TaggedList until a TaggedList 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * has been created. Nonetheless, the code in parse() does some 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * consistency checks as it runs the network, and fails with an 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * U_INTERNAL_PROGRAM_ERROR if one of these checks fails. If the input 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * data has a bad format, an U_INVALID_FORMAT_ERROR is returned. If you 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * see an U_INTERNAL_PROGRAM_ERROR the transition matrix has a bug in 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * it. 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Old functionality of multiple locales in a single file is still 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * supported. For this reason, LOCALE names override FILE names. If 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * data for en_US is located in the en.txt file, once it is loaded, 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the code will not care where it came from (other than remembering 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * which directory it came from). However, if there is an en_US 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * resource in en_US.txt, that will take precedence. There is no 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * limit to the number or type of resources that can be stored in a 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * file, however, files are only searched in a specific way. If 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * en_US_CA is requested, then first en_US_CA.txt is searched, then 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * en_US.txt, then en.txt, then default.txt. So it only makes sense 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to put certain locales in certain files. In this example, it would 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * be logical to put en_US_CA, en_US, and en into the en.txt file, 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * since they would be found there if asked for. The extreme example 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is to place all locale resources into default.txt, which should 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * also work. 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Inheritance is implemented. For example, xx_YY_zz inherits as 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * follows: xx_YY_zz, xx_YY, xx, default. Inheritance is implemented 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * as an array of hashtables. There will be from 1 to 4 hashtables in 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the array. 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Fallback files are implemented. The fallback pattern is Language 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Country Variant (LCV) -> LC -> L. Fallback is first done for the 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * requested locale. Then it is done for the default locale, as 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * returned by Locale::getDefault(). Then the special file 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * default.txt is searched for the default locale. The overall FILE 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * fallback path is LCV -> LC -> L -> dLCV -> dLC -> dL -> default. 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Note that although file name searching includes the default locale, 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * once a ResourceBundle object is constructed, the inheritance path 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * no longer includes the default locale. The path is LCV -> LC -> L 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -> default. 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * File parsing is lazy. Nothing is parsed unless it is called for by 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * someone. So when a ResourceBundle for xx_YY_zz is constructed, 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * only that locale is parsed (along with anything else in the same 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * file). Later, if the FooBar tag is asked for, and if it isn't 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * found in xx_YY_zz, then xx_YY.txt will be parsed and checked, and 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * so forth, until the chain is exhausted or the tag is found. 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Thread-safety is implemented around caches, both the cache that 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * stores all the resouce data, and the cache that stores flags 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * indicating whether or not a file has been visited. These caches 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * delete their storage at static cleanup time, when the process 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * quits. 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ResourceBundle supports TableCollation as a special case. This 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * involves having special ResourceBundle objects which DO own their 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * data, since we don't want large collation rule strings in the 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ResourceBundle cache (these are already cached in the 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * TableCollation cache). TableCollation files (.ctx files) have the 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * same format as normal resource data files, with a different 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * interpretation, from the standpoint of ResourceBundle. .ctx files 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * are loaded into otherwise ordinary ResourceBundle objects. They 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * don't inherit (that's implemented by TableCollation) and they own 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * their data (as mentioned above). However, they still support 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * possible multiple locales in a single .ctx file. (This is in 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * practice a bad idea, since you only want the one locale you're 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * looking for, and only one tag will be present 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ("CollationElements"), so you don't need an inheritance chain of 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * multiple locales.) Up to 4 locale resources will be loaded from a 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * .ctx file; everything after the first 4 is ignored (parsed and 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * deleted). (Normal .txt files have no limit.) Instead of being 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loaded into the cache, and then looked up as needed, the locale 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * resources are read straight into the ResourceBundle object. 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The Index, which used to reside in default.txt, has been moved to a 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * new file, index.txt. This file contains a slightly modified format 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * with the addition of the "InstalledLocales" tag; it looks like: 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Index { 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * InstalledLocales { 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ar 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * .. 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * zh_TW 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------------- 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ResourceBundle) 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::ResourceBundle(UErrorCode &err) 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru :UObject(), fLocale(NULL) 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = ures_open(0, Locale::getDefault().getName(), &err); 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::ResourceBundle(const ResourceBundle &other) 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru :UObject(other), fLocale(NULL) 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (other.fResource) { 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = ures_copyResb(0, other.fResource, &status); 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Copying a bad resource bundle */ 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = NULL; 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::ResourceBundle(UResourceBundle *res, UErrorCode& err) 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru :UObject(), fLocale(NULL) 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (res) { 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = ures_copyResb(0, res, &err); 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Copying a bad resource bundle */ 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = NULL; 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::ResourceBundle(const char* path, const Locale& locale, UErrorCode& err) 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru :UObject(), fLocale(NULL) 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = ures_open(path, locale.getName(), &err); 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle& ResourceBundle::operator=(const ResourceBundle& other) 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(this == &other) { 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fResource != 0) { 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(fResource); 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = NULL; 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 22259d709d503bab6e2b61931737e662dd293b40578ccornelius if (fLocale != NULL) { 22359d709d503bab6e2b61931737e662dd293b40578ccornelius delete fLocale; 22459d709d503bab6e2b61931737e662dd293b40578ccornelius fLocale = NULL; 22559d709d503bab6e2b61931737e662dd293b40578ccornelius } 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (other.fResource) { 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = ures_copyResb(0, other.fResource, &status); 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Copying a bad resource bundle */ 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fResource = NULL; 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::~ResourceBundle() 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fResource != 0) { 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(fResource); 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fLocale != NULL) { 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete(fLocale); 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle * 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::clone() const { 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new ResourceBundle(*this); 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString ResourceBundle::getString(UErrorCode& status) const { 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *r = ures_getString(fResource, &len, &status); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UnicodeString(TRUE, r, len); 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst uint8_t *ResourceBundle::getBinary(int32_t& len, UErrorCode& status) const { 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getBinary(fResource, &len, &status); 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst int32_t *ResourceBundle::getIntVector(int32_t& len, UErrorCode& status) const { 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getIntVector(fResource, &len, &status); 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuint32_t ResourceBundle::getUInt(UErrorCode& status) const { 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getUInt(fResource, &status); 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t ResourceBundle::getInt(UErrorCode& status) const { 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getInt(fResource, &status); 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char *ResourceBundle::getName(void) const { 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getName(fResource); 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char *ResourceBundle::getKey(void) const { 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getKey(fResource); 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUResType ResourceBundle::getType(void) const { 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getType(fResource); 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t ResourceBundle::getSize(void) const { 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getSize(fResource); 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool ResourceBundle::hasNext(void) const { 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_hasNext(fResource); 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid ResourceBundle::resetIterator(void) { 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_resetIterator(fResource); 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle ResourceBundle::getNext(UErrorCode& status) { 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UResourceBundle r; 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_initStackObject(&r); 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getNextResource(fResource, &r, &status); 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ResourceBundle res(&r, status); 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(&r); 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return res; 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString ResourceBundle::getNextString(UErrorCode& status) { 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* r = ures_getNextString(fResource, &len, 0, &status); 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UnicodeString(TRUE, r, len); 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString ResourceBundle::getNextString(const char ** key, UErrorCode& status) { 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* r = ures_getNextString(fResource, &len, key, &status); 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UnicodeString(TRUE, r, len); 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle ResourceBundle::get(int32_t indexR, UErrorCode& status) const { 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UResourceBundle r; 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_initStackObject(&r); 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getByIndex(fResource, indexR, &r, &status); 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ResourceBundle res(&r, status); 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(&r); 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return res; 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString ResourceBundle::getStringEx(int32_t indexS, UErrorCode& status) const { 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* r = ures_getStringByIndex(fResource, indexS, &len, &status); 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UnicodeString(TRUE, r, len); 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle ResourceBundle::get(const char* key, UErrorCode& status) const { 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UResourceBundle r; 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_initStackObject(&r); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getByKey(fResource, key, &r, &status); 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ResourceBundle res(&r, status); 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(&r); 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return res; 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle ResourceBundle::getWithFallback(const char* key, UErrorCode& status){ 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UResourceBundle r; 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_initStackObject(&r); 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getByKeyWithFallback(fResource, key, &r, &status); 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ResourceBundle res(&r, status); 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(status)){ 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(&r); 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return res; 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString ResourceBundle::getStringEx(const char* key, UErrorCode& status) const { 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* r = ures_getStringByKey(fResource, key, &len, &status); 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UnicodeString(TRUE, r, len); 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char* 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruResourceBundle::getVersionNumber() const 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 37027f654740f2a26ad62a5c155af9199af9e69b889claireho return ures_getVersionNumberInternal(fResource); 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid ResourceBundle::getVersion(UVersionInfo versionInfo) const { 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getVersion(fResource, versionInfo); 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 37759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UMutex gLocaleLock = U_MUTEX_INITIALIZER; 37859d709d503bab6e2b61931737e662dd293b40578ccorneliusconst Locale &ResourceBundle::getLocale(void) const { 37959d709d503bab6e2b61931737e662dd293b40578ccornelius Mutex lock(&gLocaleLock); 38059d709d503bab6e2b61931737e662dd293b40578ccornelius if (fLocale != NULL) { 38159d709d503bab6e2b61931737e662dd293b40578ccornelius return *fLocale; 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 38359d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode status = U_ZERO_ERROR; 38459d709d503bab6e2b61931737e662dd293b40578ccornelius const char *localeName = ures_getLocaleInternal(fResource, &status); 38559d709d503bab6e2b61931737e662dd293b40578ccornelius ResourceBundle *ncThis = const_cast<ResourceBundle *>(this); 38659d709d503bab6e2b61931737e662dd293b40578ccornelius ncThis->fLocale = new Locale(localeName); 38759d709d503bab6e2b61931737e662dd293b40578ccornelius return ncThis->fLocale != NULL ? *ncThis->fLocale : Locale::getDefault(); 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &status) const 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ures_getLocaleByType(fResource, type, &status); 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 39659d709d503bab6e2b61931737e662dd293b40578ccornelius//eof 397