]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/transreg.h
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / i18n / transreg.h
CommitLineData
b75a7d8f
A
1/*
2**********************************************************************
3* Copyright (c) 2001, International Business Machines
4* Corporation and others. All Rights Reserved.
5**********************************************************************
6* Date Name Description
7* 08/10/2001 aliu Creation.
8**********************************************************************
9*/
10#ifndef _TRANSREG_H
11#define _TRANSREG_H
12
13#include "unicode/utypes.h"
14
15#if !UCONFIG_NO_TRANSLITERATION
16
17#include "unicode/uobject.h"
18#include "unicode/translit.h"
19#include "hash.h"
20#include "uvector.h"
21
22U_NAMESPACE_BEGIN
23
24class Entry;
25class Spec;
26class UnicodeString;
27
28//------------------------------------------------------------------
29// TransliteratorAlias
30//------------------------------------------------------------------
31
32/**
33 * A TransliteratorAlias object is returned by get() if the given ID
34 * actually translates into something else. The caller then invokes
35 * the create() method on the alias to create the actual
36 * transliterator, and deletes the alias.
37 *
38 * Why all the shenanigans? To prevent circular calls between
39 * the registry code and the transliterator code that deadlocks.
40 */
41class TransliteratorAlias : public UMemory {
42 public:
43 /**
44 * Construct a simple alias.
45 * @param aliasID the given id.
46 */
47 TransliteratorAlias(const UnicodeString& aliasID);
48
49 /**
50 * Construct a compound RBT alias.
51 */
52 TransliteratorAlias(const UnicodeString& ID, const UnicodeString& idBlock,
53 Transliterator* adopted, int32_t idSplitPoint,
54 const UnicodeSet* compoundFilter);
55
56 ~TransliteratorAlias();
57
58 /**
59 * The whole point of create() is that the caller must invoke
60 * it when the registry mutex is NOT held, to prevent deadlock.
61 * It may only be called once.
62 */
63 Transliterator* create(UParseError&, UErrorCode&);
64
65 private:
66 // We actually come in two flavors:
67 // 1. Simple alias
68 // Here aliasID is the alias string. Everything else is
69 // null, zero, empty.
70 // 2. CompoundRBT
71 // Here ID is the ID, aliasID is the idBlock, trans is the
72 // contained RBT, and idSplitPoint is the offet in aliasID
73 // where the contained RBT goes. compoundFilter is the
74 // compound filter, and it is _not_ owned.
75 UnicodeString ID;
76 UnicodeString aliasID;
77 Transliterator* trans; // owned
78 const UnicodeSet* compoundFilter; // alias
79 int32_t idSplitPoint;
80
81 TransliteratorAlias(const TransliteratorAlias &other); // forbid copying of this class
82 TransliteratorAlias &operator=(const TransliteratorAlias &other); // forbid copying of this class
83};
84
85
86/**
87 * A registry of system transliterators. This is the data structure
88 * that implements the mapping between transliterator IDs and the data
89 * or function pointers used to create the corresponding
90 * transliterators. There is one instance of the registry that is
91 * created statically.
92 *
93 * The registry consists of a dynamic component -- a hashtable -- and
94 * a static component -- locale resource bundles. The dynamic store
95 * is semantically overlaid on the static store, so the static mapping
96 * can be dynamically overridden.
97 *
98 * This is an internal class that is only used by Transliterator.
99 * Transliterator maintains one static instance of this class and
100 * delegates all registry-related operations to it.
101 *
102 * @author Alan Liu
103 */
104class TransliteratorRegistry : public UMemory {
105
106 public:
107
108 /**
109 * Contructor
110 * @param status Output param set to success/failure code.
111 */
112 TransliteratorRegistry(UErrorCode& status);
113
114 /**
115 * Nonvirtual destructor -- this class is not subclassable.
116 */
117 ~TransliteratorRegistry();
118
119 //------------------------------------------------------------------
120 // Basic public API
121 //------------------------------------------------------------------
122
123 /**
124 * Given a simple ID (forward direction, no inline filter, not
125 * compound) attempt to instantiate it from the registry. Return
126 * 0 on failure.
127 *
128 * Return a non-NULL aliasReturn value if the ID points to an alias.
129 * We cannot instantiate it ourselves because the alias may contain
130 * filters or compounds, which we do not understand. Caller should
131 * make aliasReturn NULL before calling.
132 * @param ID the given ID
133 * @param aliasReturn the given TransliteratorAlias
134 * @param parseError Struct to recieve information on position
135 * of error if an error is encountered
136 * @param status Output param set to success/failure code.
137 */
138 Transliterator* get(const UnicodeString& ID,
139 TransliteratorAlias*& aliasReturn,
140 UParseError& parseError,
141 UErrorCode& status);
142
143 /**
144 * Register a prototype (adopted). This adds an entry to the
145 * dynamic store, or replaces an existing entry. Any entry in the
146 * underlying static locale resource store is masked.
147 */
148 void put(Transliterator* adoptedProto,
149 UBool visible);
150
151 /**
152 * Register an ID and a factory function pointer. This adds an
153 * entry to the dynamic store, or replaces an existing entry. Any
154 * entry in the underlying static locale resource store is masked.
155 */
156 void put(const UnicodeString& ID,
157 Transliterator::Factory factory,
158 Transliterator::Token context,
159 UBool visible);
160
161 /**
162 * Register an ID and a resource name. This adds an entry to the
163 * dynamic store, or replaces an existing entry. Any entry in the
164 * underlying static locale resource store is masked.
165 */
166 void put(const UnicodeString& ID,
167 const UnicodeString& resourceName,
168 UTransDirection dir,
169 UBool visible);
170
171 /**
172 * Register an ID and an alias ID. This adds an entry to the
173 * dynamic store, or replaces an existing entry. Any entry in the
174 * underlying static locale resource store is masked.
175 */
176 void put(const UnicodeString& ID,
177 const UnicodeString& alias,
178 UBool visible);
179
180 /**
181 * Unregister an ID. This removes an entry from the dynamic store
182 * if there is one. The static locale resource store is
183 * unaffected.
184 * @param ID the given ID.
185 */
186 void remove(const UnicodeString& ID);
187
188 //------------------------------------------------------------------
189 // Public ID and spec management
190 //------------------------------------------------------------------
191
192 /**
193 * Return the number of IDs currently registered with the system.
194 * To retrieve the actual IDs, call getAvailableID(i) with
195 * i from 0 to countAvailableIDs() - 1.
196 * @return the number of IDs currently registered with the system.
197 * @internal
198 */
199 int32_t countAvailableIDs(void);
200
201 /**
202 * Return the index-th available ID. index must be between 0
203 * and countAvailableIDs() - 1, inclusive. If index is out of
204 * range, the result of getAvailableID(0) is returned.
205 * @param index the given index.
206 * @return the index-th available ID. index must be between 0
207 * and countAvailableIDs() - 1, inclusive. If index is out of
208 * range, the result of getAvailableID(0) is returned.
209 * @internal
210 */
211 const UnicodeString& getAvailableID(int32_t index);
212
213 /**
214 * Return the number of registered source specifiers.
215 * @return the number of registered source specifiers.
216 */
217 int32_t countAvailableSources(void);
218
219 /**
220 * Return a registered source specifier.
221 * @param index which specifier to return, from 0 to n-1, where
222 * n = countAvailableSources()
223 * @param result fill-in paramter to receive the source specifier.
224 * If index is out of range, result will be empty.
225 * @return reference to result
226 */
227 UnicodeString& getAvailableSource(int32_t index,
228 UnicodeString& result);
229
230 /**
231 * Return the number of registered target specifiers for a given
232 * source specifier.
233 * @param source the given source specifier.
234 * @return the number of registered target specifiers for a given
235 * source specifier.
236 */
237 int32_t countAvailableTargets(const UnicodeString& source);
238
239 /**
240 * Return a registered target specifier for a given source.
241 * @param index which specifier to return, from 0 to n-1, where
242 * n = countAvailableTargets(source)
243 * @param source the source specifier
244 * @param result fill-in paramter to receive the target specifier.
245 * If source is invalid or if index is out of range, result will
246 * be empty.
247 * @return reference to result
248 */
249 UnicodeString& getAvailableTarget(int32_t index,
250 const UnicodeString& source,
251 UnicodeString& result);
252
253 /**
254 * Return the number of registered variant specifiers for a given
255 * source-target pair. There is always at least one variant: If
256 * just source-target is registered, then the single variant
257 * NO_VARIANT is returned. If source-target/variant is registered
258 * then that variant is returned.
259 * @param source the source specifiers
260 * @param target the target specifiers
261 * @return the number of registered variant specifiers for a given
262 * source-target pair.
263 */
264 int32_t countAvailableVariants(const UnicodeString& source,
265 const UnicodeString& target);
266
267 /**
268 * Return a registered variant specifier for a given source-target
269 * pair. If NO_VARIANT is one of the variants, then it will be
270 * at index 0.
271 * @param index which specifier to return, from 0 to n-1, where
272 * n = countAvailableVariants(source, target)
273 * @param source the source specifier
274 * @param target the target specifier
275 * @param result fill-in paramter to receive the variant
276 * specifier. If source is invalid or if target is invalid or if
277 * index is out of range, result will be empty.
278 * @return reference to result
279 */
280 UnicodeString& getAvailableVariant(int32_t index,
281 const UnicodeString& source,
282 const UnicodeString& target,
283 UnicodeString& result);
284
285 private:
286
287 //----------------------------------------------------------------
288 // Private implementation
289 //----------------------------------------------------------------
290
291 Entry* find(const UnicodeString& ID);
292
293 Entry* find(UnicodeString& source,
294 UnicodeString& target,
295 UnicodeString& variant);
296
297 Entry* findInDynamicStore(const Spec& src,
298 const Spec& trg,
299 const UnicodeString& variant);
300
301 Entry* findInStaticStore(const Spec& src,
302 const Spec& trg,
303 const UnicodeString& variant);
304
305 static Entry* findInBundle(const Spec& specToOpen,
306 const Spec& specToFind,
307 const UnicodeString& variant,
308 UTransDirection direction);
309
310 void registerEntry(const UnicodeString& source,
311 const UnicodeString& target,
312 const UnicodeString& variant,
313 Entry* adopted,
314 UBool visible);
315
316 void registerEntry(const UnicodeString& ID,
317 Entry* adopted,
318 UBool visible);
319
320 void registerEntry(const UnicodeString& ID,
321 const UnicodeString& source,
322 const UnicodeString& target,
323 const UnicodeString& variant,
324 Entry* adopted,
325 UBool visible);
326
327 void registerSTV(const UnicodeString& source,
328 const UnicodeString& target,
329 const UnicodeString& variant);
330
331 void removeSTV(const UnicodeString& source,
332 const UnicodeString& target,
333 const UnicodeString& variant);
334
335 Transliterator* instantiateEntry(const UnicodeString& ID,
336 Entry *entry,
337 TransliteratorAlias*& aliasReturn,
338 UParseError& parseError,
339 UErrorCode& status);
340
341 private:
342
343 /**
344 * Dynamic registry mapping full IDs to Entry objects. This
345 * contains both public and internal entities. The visibility is
346 * controlled by whether an entry is listed in availableIDs and
347 * specDAG or not.
348 */
349 Hashtable registry;
350
351 /**
352 * DAG of visible IDs by spec. Hashtable: source => (Hashtable:
353 * target => (UVector: variant)) The UVector of variants is never
354 * empty. For a source-target with no variant, the special
355 * variant NO_VARIANT (the empty string) is stored in slot zero of
356 * the UVector.
357 */
358 Hashtable specDAG;
359
360 /**
361 * Vector of public full IDs.
362 */
363 UVector availableIDs;
364
365 TransliteratorRegistry(const TransliteratorRegistry &other); // forbid copying of this class
366 TransliteratorRegistry &operator=(const TransliteratorRegistry &other); // forbid copying of this class
367};
368
369U_NAMESPACE_END
370
371#endif /* #if !UCONFIG_NO_TRANSLITERATION */
372
373#endif
374//eof