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