/src/mozilla-central/intl/icu/source/i18n/unicode/alphaindex.h
Line | Count | Source (jump to first uncovered line) |
1 | | // © 2016 and later: Unicode, Inc. and others. |
2 | | // License & terms of use: http://www.unicode.org/copyright.html |
3 | | /* |
4 | | ******************************************************************************* |
5 | | * |
6 | | * Copyright (C) 2011-2014 International Business Machines |
7 | | * Corporation and others. All Rights Reserved. |
8 | | * |
9 | | ******************************************************************************* |
10 | | */ |
11 | | |
12 | | #ifndef INDEXCHARS_H |
13 | | #define INDEXCHARS_H |
14 | | |
15 | | #include "unicode/utypes.h" |
16 | | #include "unicode/uobject.h" |
17 | | #include "unicode/locid.h" |
18 | | #include "unicode/unistr.h" |
19 | | |
20 | | #if !UCONFIG_NO_COLLATION |
21 | | |
22 | | /** |
23 | | * \file |
24 | | * \brief C++ API: Index Characters |
25 | | */ |
26 | | |
27 | | U_CDECL_BEGIN |
28 | | |
29 | | /** |
30 | | * Constants for Alphabetic Index Label Types. |
31 | | * The form of these enum constants anticipates having a plain C API |
32 | | * for Alphabetic Indexes that will also use them. |
33 | | * @stable ICU 4.8 |
34 | | */ |
35 | | typedef enum UAlphabeticIndexLabelType { |
36 | | /** |
37 | | * Normal Label, typically the starting letter of the names |
38 | | * in the bucket with this label. |
39 | | * @stable ICU 4.8 |
40 | | */ |
41 | | U_ALPHAINDEX_NORMAL = 0, |
42 | | |
43 | | /** |
44 | | * Undeflow Label. The bucket with this label contains names |
45 | | * in scripts that sort before any of the bucket labels in this index. |
46 | | * @stable ICU 4.8 |
47 | | */ |
48 | | U_ALPHAINDEX_UNDERFLOW = 1, |
49 | | |
50 | | /** |
51 | | * Inflow Label. The bucket with this label contains names |
52 | | * in scripts that sort between two of the bucket labels in this index. |
53 | | * Inflow labels are created when an index contains normal labels for |
54 | | * multiple scripts, and skips other scripts that sort between some of the |
55 | | * included scripts. |
56 | | * @stable ICU 4.8 |
57 | | */ |
58 | | U_ALPHAINDEX_INFLOW = 2, |
59 | | |
60 | | /** |
61 | | * Overflow Label. Te bucket with this label contains names in scripts |
62 | | * that sort after all of the bucket labels in this index. |
63 | | * @stable ICU 4.8 |
64 | | */ |
65 | | U_ALPHAINDEX_OVERFLOW = 3 |
66 | | } UAlphabeticIndexLabelType; |
67 | | |
68 | | |
69 | | struct UHashtable; |
70 | | U_CDECL_END |
71 | | |
72 | | U_NAMESPACE_BEGIN |
73 | | |
74 | | // Forward Declarations |
75 | | |
76 | | class BucketList; |
77 | | class Collator; |
78 | | class RuleBasedCollator; |
79 | | class StringEnumeration; |
80 | | class UnicodeSet; |
81 | | class UVector; |
82 | | |
83 | | /** |
84 | | * AlphabeticIndex supports the creation of a UI index appropriate for a given language. |
85 | | * It can support either direct use, or use with a client that doesn't support localized collation. |
86 | | * The following is an example of what an index might look like in a UI: |
87 | | * |
88 | | * <pre> |
89 | | * <b>... A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ...</b> |
90 | | * |
91 | | * <b>A</b> |
92 | | * Addison |
93 | | * Albertson |
94 | | * Azensky |
95 | | * <b>B</b> |
96 | | * Baker |
97 | | * ... |
98 | | * </pre> |
99 | | * |
100 | | * The class can generate a list of labels for use as a UI "index", that is, a list of |
101 | | * clickable characters (or character sequences) that allow the user to see a segment |
102 | | * (bucket) of a larger "target" list. That is, each label corresponds to a bucket in |
103 | | * the target list, where everything in the bucket is greater than or equal to the character |
104 | | * (according to the locale's collation). Strings can be added to the index; |
105 | | * they will be in sorted order in the right bucket. |
106 | | * <p> |
107 | | * The class also supports having buckets for strings before the first (underflow), |
108 | | * after the last (overflow), and between scripts (inflow). For example, if the index |
109 | | * is constructed with labels for Russian and English, Greek characters would fall |
110 | | * into an inflow bucket between the other two scripts. |
111 | | * <p> |
112 | | * The AlphabeticIndex class is not intended for public subclassing. |
113 | | * |
114 | | * <p><em>Note:</em> If you expect to have a lot of ASCII or Latin characters |
115 | | * as well as characters from the user's language, |
116 | | * then it is a good idea to call addLabels(Locale::getEnglish(), status).</p> |
117 | | * |
118 | | * <h2>Direct Use</h2> |
119 | | * <p>The following shows an example of building an index directly. |
120 | | * The "show..." methods below are just to illustrate usage. |
121 | | * |
122 | | * <pre> |
123 | | * // Create a simple index. "Item" is assumed to be an application |
124 | | * // defined type that the application's UI and other processing knows about, |
125 | | * // and that has a name. |
126 | | * |
127 | | * UErrorCode status = U_ZERO_ERROR; |
128 | | * AlphabeticIndex index = new AlphabeticIndex(desiredLocale, status); |
129 | | * index->addLabels(additionalLocale, status); |
130 | | * for (Item *item in some source of Items ) { |
131 | | * index->addRecord(item->name(), item, status); |
132 | | * } |
133 | | * ... |
134 | | * // Show index at top. We could skip or gray out empty buckets |
135 | | * |
136 | | * while (index->nextBucket(status)) { |
137 | | * if (showAll || index->getBucketRecordCount() != 0) { |
138 | | * showLabelAtTop(UI, index->getBucketLabel()); |
139 | | * } |
140 | | * } |
141 | | * ... |
142 | | * // Show the buckets with their contents, skipping empty buckets |
143 | | * |
144 | | * index->resetBucketIterator(status); |
145 | | * while (index->nextBucket(status)) { |
146 | | * if (index->getBucketRecordCount() != 0) { |
147 | | * showLabelInList(UI, index->getBucketLabel()); |
148 | | * while (index->nextRecord(status)) { |
149 | | * showIndexedItem(UI, static_cast<Item *>(index->getRecordData())) |
150 | | * </pre> |
151 | | * |
152 | | * The caller can build different UIs using this class. |
153 | | * For example, an index character could be omitted or grayed-out |
154 | | * if its bucket is empty. Small buckets could also be combined based on size, such as: |
155 | | * |
156 | | * <pre> |
157 | | * <b>... A-F G-N O-Z ...</b> |
158 | | * </pre> |
159 | | * |
160 | | * <h2>Client Support</h2> |
161 | | * <p>Callers can also use the AlphabeticIndex::ImmutableIndex, or the AlphabeticIndex itself, |
162 | | * to support sorting on a client that doesn't support AlphabeticIndex functionality. |
163 | | * |
164 | | * <p>The ImmutableIndex is both immutable and thread-safe. |
165 | | * The corresponding AlphabeticIndex methods are not thread-safe because |
166 | | * they "lazily" build the index buckets. |
167 | | * <ul> |
168 | | * <li>ImmutableIndex.getBucket(index) provides random access to all |
169 | | * buckets and their labels and label types. |
170 | | * <li>The AlphabeticIndex bucket iterator or ImmutableIndex.getBucket(0..getBucketCount-1) |
171 | | * can be used to get a list of the labels, |
172 | | * such as "...", "A", "B",..., and send that list to the client. |
173 | | * <li>When the client has a new name, it sends that name to the server. |
174 | | * The server needs to call the following methods, |
175 | | * and communicate the bucketIndex and collationKey back to the client. |
176 | | * |
177 | | * <pre> |
178 | | * int32_t bucketIndex = index.getBucketIndex(name, status); |
179 | | * const UnicodeString &label = immutableIndex.getBucket(bucketIndex)->getLabel(); // optional |
180 | | * int32_t skLength = collator.getSortKey(name, sk, skCapacity); |
181 | | * </pre> |
182 | | * |
183 | | * <li>The client would put the name (and associated information) into its bucket for bucketIndex. The sort key sk is a |
184 | | * sequence of bytes that can be compared with a binary compare, and produce the right localized result.</li> |
185 | | * </ul> |
186 | | * |
187 | | * @stable ICU 4.8 |
188 | | */ |
189 | | class U_I18N_API AlphabeticIndex: public UObject { |
190 | | public: |
191 | | /** |
192 | | * An index "bucket" with a label string and type. |
193 | | * It is referenced by getBucketIndex(), |
194 | | * and returned by ImmutableIndex.getBucket(). |
195 | | * |
196 | | * The Bucket class is not intended for public subclassing. |
197 | | * @stable ICU 51 |
198 | | */ |
199 | | class U_I18N_API Bucket : public UObject { |
200 | | public: |
201 | | /** |
202 | | * Destructor. |
203 | | * @stable ICU 51 |
204 | | */ |
205 | | virtual ~Bucket(); |
206 | | |
207 | | /** |
208 | | * Returns the label string. |
209 | | * |
210 | | * @return the label string for the bucket |
211 | | * @stable ICU 51 |
212 | | */ |
213 | 0 | const UnicodeString &getLabel() const { return label_; } |
214 | | /** |
215 | | * Returns whether this bucket is a normal, underflow, overflow, or inflow bucket. |
216 | | * |
217 | | * @return the bucket label type |
218 | | * @stable ICU 51 |
219 | | */ |
220 | 0 | UAlphabeticIndexLabelType getLabelType() const { return labelType_; } |
221 | | |
222 | | private: |
223 | | friend class AlphabeticIndex; |
224 | | friend class BucketList; |
225 | | |
226 | | UnicodeString label_; |
227 | | UnicodeString lowerBoundary_; |
228 | | UAlphabeticIndexLabelType labelType_; |
229 | | Bucket *displayBucket_; |
230 | | int32_t displayIndex_; |
231 | | UVector *records_; // Records are owned by the inputList_ vector. |
232 | | |
233 | | Bucket(const UnicodeString &label, // Parameter strings are copied. |
234 | | const UnicodeString &lowerBoundary, |
235 | | UAlphabeticIndexLabelType type); |
236 | | }; |
237 | | |
238 | | /** |
239 | | * Immutable, thread-safe version of AlphabeticIndex. |
240 | | * This class provides thread-safe methods for bucketing, |
241 | | * and random access to buckets and their properties, |
242 | | * but does not offer adding records to the index. |
243 | | * |
244 | | * The ImmutableIndex class is not intended for public subclassing. |
245 | | * |
246 | | * @stable ICU 51 |
247 | | */ |
248 | | class U_I18N_API ImmutableIndex : public UObject { |
249 | | public: |
250 | | /** |
251 | | * Destructor. |
252 | | * @stable ICU 51 |
253 | | */ |
254 | | virtual ~ImmutableIndex(); |
255 | | |
256 | | /** |
257 | | * Returns the number of index buckets and labels, including underflow/inflow/overflow. |
258 | | * |
259 | | * @return the number of index buckets |
260 | | * @stable ICU 51 |
261 | | */ |
262 | | int32_t getBucketCount() const; |
263 | | |
264 | | /** |
265 | | * Finds the index bucket for the given name and returns the number of that bucket. |
266 | | * Use getBucket() to get the bucket's properties. |
267 | | * |
268 | | * @param name the string to be sorted into an index bucket |
269 | | * @return the bucket number for the name |
270 | | * @stable ICU 51 |
271 | | */ |
272 | | int32_t getBucketIndex(const UnicodeString &name, UErrorCode &errorCode) const; |
273 | | |
274 | | /** |
275 | | * Returns the index-th bucket. Returns NULL if the index is out of range. |
276 | | * |
277 | | * @param index bucket number |
278 | | * @return the index-th bucket |
279 | | * @stable ICU 51 |
280 | | */ |
281 | | const Bucket *getBucket(int32_t index) const; |
282 | | |
283 | | private: |
284 | | friend class AlphabeticIndex; |
285 | | |
286 | | ImmutableIndex(BucketList *bucketList, Collator *collatorPrimaryOnly) |
287 | 0 | : buckets_(bucketList), collatorPrimaryOnly_(collatorPrimaryOnly) {} |
288 | | |
289 | | BucketList *buckets_; |
290 | | Collator *collatorPrimaryOnly_; |
291 | | }; |
292 | | |
293 | | /** |
294 | | * Construct an AlphabeticIndex object for the specified locale. If the locale's |
295 | | * data does not include index characters, a set of them will be |
296 | | * synthesized based on the locale's exemplar characters. The locale |
297 | | * determines the sorting order for both the index characters and the |
298 | | * user item names appearing under each Index character. |
299 | | * |
300 | | * @param locale the desired locale. |
301 | | * @param status Error code, will be set with the reason if the construction |
302 | | * of the AlphabeticIndex object fails. |
303 | | * @stable ICU 4.8 |
304 | | */ |
305 | | AlphabeticIndex(const Locale &locale, UErrorCode &status); |
306 | | |
307 | | /** |
308 | | * Construct an AlphabeticIndex that uses a specific collator. |
309 | | * |
310 | | * The index will be created with no labels; the addLabels() function must be called |
311 | | * after creation to add the desired labels to the index. |
312 | | * |
313 | | * The index adopts the collator, and is responsible for deleting it. |
314 | | * The caller should make no further use of the collator after creating the index. |
315 | | * |
316 | | * @param collator The collator to use to order the contents of this index. |
317 | | * @param status Error code, will be set with the reason if the |
318 | | * operation fails. |
319 | | * @stable ICU 51 |
320 | | */ |
321 | | AlphabeticIndex(RuleBasedCollator *collator, UErrorCode &status); |
322 | | |
323 | | /** |
324 | | * Add Labels to this Index. The labels are additions to those |
325 | | * that are already in the index; they do not replace the existing |
326 | | * ones. |
327 | | * @param additions The additional characters to add to the index, such as A-Z. |
328 | | * @param status Error code, will be set with the reason if the |
329 | | * operation fails. |
330 | | * @return this, for chaining |
331 | | * @stable ICU 4.8 |
332 | | */ |
333 | | virtual AlphabeticIndex &addLabels(const UnicodeSet &additions, UErrorCode &status); |
334 | | |
335 | | /** |
336 | | * Add the index characters from a Locale to the index. The labels |
337 | | * are added to those that are already in the index; they do not replace the |
338 | | * existing index characters. The collation order for this index is not |
339 | | * changed; it remains that of the locale that was originally specified |
340 | | * when creating this Index. |
341 | | * |
342 | | * @param locale The locale whose index characters are to be added. |
343 | | * @param status Error code, will be set with the reason if the |
344 | | * operation fails. |
345 | | * @return this, for chaining |
346 | | * @stable ICU 4.8 |
347 | | */ |
348 | | virtual AlphabeticIndex &addLabels(const Locale &locale, UErrorCode &status); |
349 | | |
350 | | /** |
351 | | * Destructor |
352 | | * @stable ICU 4.8 |
353 | | */ |
354 | | virtual ~AlphabeticIndex(); |
355 | | |
356 | | /** |
357 | | * Builds an immutable, thread-safe version of this instance, without data records. |
358 | | * |
359 | | * @return an immutable index instance |
360 | | * @stable ICU 51 |
361 | | */ |
362 | | ImmutableIndex *buildImmutableIndex(UErrorCode &errorCode); |
363 | | |
364 | | /** |
365 | | * Get the Collator that establishes the ordering of the items in this index. |
366 | | * Ownership of the collator remains with the AlphabeticIndex instance. |
367 | | * |
368 | | * The returned collator is a reference to the internal collator used by this |
369 | | * index. It may be safely used to compare the names of items or to get |
370 | | * sort keys for names. However if any settings need to be changed, |
371 | | * or other non-const methods called, a cloned copy must be made first. |
372 | | * |
373 | | * @return The collator |
374 | | * @stable ICU 4.8 |
375 | | */ |
376 | | virtual const RuleBasedCollator &getCollator() const; |
377 | | |
378 | | |
379 | | /** |
380 | | * Get the default label used for abbreviated buckets <i>between</i> other index characters. |
381 | | * For example, consider the labels when Latin and Greek are used: |
382 | | * X Y Z ... Α Β Γ. |
383 | | * |
384 | | * @return inflow label |
385 | | * @stable ICU 4.8 |
386 | | */ |
387 | | virtual const UnicodeString &getInflowLabel() const; |
388 | | |
389 | | /** |
390 | | * Set the default label used for abbreviated buckets <i>between</i> other index characters. |
391 | | * An inflow label will be automatically inserted if two otherwise-adjacent label characters |
392 | | * are from different scripts, e.g. Latin and Cyrillic, and a third script, e.g. Greek, |
393 | | * sorts between the two. The default inflow character is an ellipsis (...) |
394 | | * |
395 | | * @param inflowLabel the new Inflow label. |
396 | | * @param status Error code, will be set with the reason if the operation fails. |
397 | | * @return this |
398 | | * @stable ICU 4.8 |
399 | | */ |
400 | | virtual AlphabeticIndex &setInflowLabel(const UnicodeString &inflowLabel, UErrorCode &status); |
401 | | |
402 | | |
403 | | /** |
404 | | * Get the special label used for items that sort after the last normal label, |
405 | | * and that would not otherwise have an appropriate label. |
406 | | * |
407 | | * @return the overflow label |
408 | | * @stable ICU 4.8 |
409 | | */ |
410 | | virtual const UnicodeString &getOverflowLabel() const; |
411 | | |
412 | | |
413 | | /** |
414 | | * Set the label used for items that sort after the last normal label, |
415 | | * and that would not otherwise have an appropriate label. |
416 | | * |
417 | | * @param overflowLabel the new overflow label. |
418 | | * @param status Error code, will be set with the reason if the operation fails. |
419 | | * @return this |
420 | | * @stable ICU 4.8 |
421 | | */ |
422 | | virtual AlphabeticIndex &setOverflowLabel(const UnicodeString &overflowLabel, UErrorCode &status); |
423 | | |
424 | | /** |
425 | | * Get the special label used for items that sort before the first normal label, |
426 | | * and that would not otherwise have an appropriate label. |
427 | | * |
428 | | * @return underflow label |
429 | | * @stable ICU 4.8 |
430 | | */ |
431 | | virtual const UnicodeString &getUnderflowLabel() const; |
432 | | |
433 | | /** |
434 | | * Set the label used for items that sort before the first normal label, |
435 | | * and that would not otherwise have an appropriate label. |
436 | | * |
437 | | * @param underflowLabel the new underflow label. |
438 | | * @param status Error code, will be set with the reason if the operation fails. |
439 | | * @return this |
440 | | * @stable ICU 4.8 |
441 | | */ |
442 | | virtual AlphabeticIndex &setUnderflowLabel(const UnicodeString &underflowLabel, UErrorCode &status); |
443 | | |
444 | | |
445 | | /** |
446 | | * Get the limit on the number of labels permitted in the index. |
447 | | * The number does not include over, under and inflow labels. |
448 | | * |
449 | | * @return maxLabelCount maximum number of labels. |
450 | | * @stable ICU 4.8 |
451 | | */ |
452 | | virtual int32_t getMaxLabelCount() const; |
453 | | |
454 | | /** |
455 | | * Set a limit on the number of labels permitted in the index. |
456 | | * The number does not include over, under and inflow labels. |
457 | | * Currently, if the number is exceeded, then every |
458 | | * nth item is removed to bring the count down. |
459 | | * A more sophisticated mechanism may be available in the future. |
460 | | * |
461 | | * @param maxLabelCount the maximum number of labels. |
462 | | * @param status error code |
463 | | * @return This, for chaining |
464 | | * @stable ICU 4.8 |
465 | | */ |
466 | | virtual AlphabeticIndex &setMaxLabelCount(int32_t maxLabelCount, UErrorCode &status); |
467 | | |
468 | | |
469 | | /** |
470 | | * Add a record to the index. Each record will be associated with an index Bucket |
471 | | * based on the record's name. The list of records for each bucket will be sorted |
472 | | * based on the collation ordering of the names in the index's locale. |
473 | | * Records with duplicate names are permitted; they will be kept in the order |
474 | | * that they were added. |
475 | | * |
476 | | * @param name The display name for the Record. The Record will be placed in |
477 | | * a bucket based on this name. |
478 | | * @param data An optional pointer to user data associated with this |
479 | | * item. When iterating the contents of a bucket, both the |
480 | | * data pointer the name will be available for each Record. |
481 | | * @param status Error code, will be set with the reason if the operation fails. |
482 | | * @return This, for chaining. |
483 | | * @stable ICU 4.8 |
484 | | */ |
485 | | virtual AlphabeticIndex &addRecord(const UnicodeString &name, const void *data, UErrorCode &status); |
486 | | |
487 | | /** |
488 | | * Remove all Records from the Index. The set of Buckets, which define the headings under |
489 | | * which records are classified, is not altered. |
490 | | * |
491 | | * @param status Error code, will be set with the reason if the operation fails. |
492 | | * @return This, for chaining. |
493 | | * @stable ICU 4.8 |
494 | | */ |
495 | | virtual AlphabeticIndex &clearRecords(UErrorCode &status); |
496 | | |
497 | | |
498 | | /** Get the number of labels in this index. |
499 | | * Note: may trigger lazy index construction. |
500 | | * |
501 | | * @param status Error code, will be set with the reason if the operation fails. |
502 | | * @return The number of labels in this index, including any under, over or |
503 | | * in-flow labels. |
504 | | * @stable ICU 4.8 |
505 | | */ |
506 | | virtual int32_t getBucketCount(UErrorCode &status); |
507 | | |
508 | | |
509 | | /** Get the total number of Records in this index, that is, the number |
510 | | * of <name, data> pairs added. |
511 | | * |
512 | | * @param status Error code, will be set with the reason if the operation fails. |
513 | | * @return The number of records in this index, that is, the total number |
514 | | * of (name, data) items added with addRecord(). |
515 | | * @stable ICU 4.8 |
516 | | */ |
517 | | virtual int32_t getRecordCount(UErrorCode &status); |
518 | | |
519 | | |
520 | | |
521 | | /** |
522 | | * Given the name of a record, return the zero-based index of the Bucket |
523 | | * in which the item should appear. The name need not be in the index. |
524 | | * A Record will not be added to the index by this function. |
525 | | * Bucket numbers are zero-based, in Bucket iteration order. |
526 | | * |
527 | | * @param itemName The name whose bucket position in the index is to be determined. |
528 | | * @param status Error code, will be set with the reason if the operation fails. |
529 | | * @return The bucket number for this name. |
530 | | * @stable ICU 4.8 |
531 | | * |
532 | | */ |
533 | | virtual int32_t getBucketIndex(const UnicodeString &itemName, UErrorCode &status); |
534 | | |
535 | | |
536 | | /** |
537 | | * Get the zero based index of the current Bucket from an iteration |
538 | | * over the Buckets of this index. Return -1 if no iteration is in process. |
539 | | * @return the index of the current Bucket |
540 | | * @stable ICU 4.8 |
541 | | */ |
542 | | virtual int32_t getBucketIndex() const; |
543 | | |
544 | | |
545 | | /** |
546 | | * Advance the iteration over the Buckets of this index. Return FALSE if |
547 | | * there are no more Buckets. |
548 | | * |
549 | | * @param status Error code, will be set with the reason if the operation fails. |
550 | | * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while |
551 | | * an enumeration of its contents are in process. |
552 | | * |
553 | | * @return TRUE if success, FALSE if at end of iteration |
554 | | * @stable ICU 4.8 |
555 | | */ |
556 | | virtual UBool nextBucket(UErrorCode &status); |
557 | | |
558 | | /** |
559 | | * Return the name of the Label of the current bucket from an iteration over the buckets. |
560 | | * If the iteration is before the first Bucket (nextBucket() has not been called), |
561 | | * or after the last, return an empty string. |
562 | | * |
563 | | * @return the bucket label. |
564 | | * @stable ICU 4.8 |
565 | | */ |
566 | | virtual const UnicodeString &getBucketLabel() const; |
567 | | |
568 | | /** |
569 | | * Return the type of the label for the current Bucket (selected by the |
570 | | * iteration over Buckets.) |
571 | | * |
572 | | * @return the label type. |
573 | | * @stable ICU 4.8 |
574 | | */ |
575 | | virtual UAlphabeticIndexLabelType getBucketLabelType() const; |
576 | | |
577 | | /** |
578 | | * Get the number of <name, data> Records in the current Bucket. |
579 | | * If the current bucket iteration position is before the first label or after the |
580 | | * last, return 0. |
581 | | * |
582 | | * @return the number of Records. |
583 | | * @stable ICU 4.8 |
584 | | */ |
585 | | virtual int32_t getBucketRecordCount() const; |
586 | | |
587 | | |
588 | | /** |
589 | | * Reset the Bucket iteration for this index. The next call to nextBucket() |
590 | | * will restart the iteration at the first label. |
591 | | * |
592 | | * @param status Error code, will be set with the reason if the operation fails. |
593 | | * @return this, for chaining. |
594 | | * @stable ICU 4.8 |
595 | | */ |
596 | | virtual AlphabeticIndex &resetBucketIterator(UErrorCode &status); |
597 | | |
598 | | /** |
599 | | * Advance to the next record in the current Bucket. |
600 | | * When nextBucket() is called, Record iteration is reset to just before the |
601 | | * first Record in the new Bucket. |
602 | | * |
603 | | * @param status Error code, will be set with the reason if the operation fails. |
604 | | * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while |
605 | | * an enumeration of its contents are in process. |
606 | | * @return TRUE if successful, FALSE when the iteration advances past the last item. |
607 | | * @stable ICU 4.8 |
608 | | */ |
609 | | virtual UBool nextRecord(UErrorCode &status); |
610 | | |
611 | | /** |
612 | | * Get the name of the current Record. |
613 | | * Return an empty string if the Record iteration position is before first |
614 | | * or after the last. |
615 | | * |
616 | | * @return The name of the current index item. |
617 | | * @stable ICU 4.8 |
618 | | */ |
619 | | virtual const UnicodeString &getRecordName() const; |
620 | | |
621 | | |
622 | | /** |
623 | | * Return the data pointer of the Record currently being iterated over. |
624 | | * Return NULL if the current iteration position before the first item in this Bucket, |
625 | | * or after the last. |
626 | | * |
627 | | * @return The current Record's data pointer. |
628 | | * @stable ICU 4.8 |
629 | | */ |
630 | | virtual const void *getRecordData() const; |
631 | | |
632 | | |
633 | | /** |
634 | | * Reset the Record iterator position to before the first Record in the current Bucket. |
635 | | * |
636 | | * @return This, for chaining. |
637 | | * @stable ICU 4.8 |
638 | | */ |
639 | | virtual AlphabeticIndex &resetRecordIterator(); |
640 | | |
641 | | private: |
642 | | /** |
643 | | * No Copy constructor. |
644 | | * @internal |
645 | | */ |
646 | | AlphabeticIndex(const AlphabeticIndex &other); |
647 | | |
648 | | /** |
649 | | * No assignment. |
650 | | */ |
651 | 0 | AlphabeticIndex &operator =(const AlphabeticIndex & /*other*/) { return *this;}; |
652 | | |
653 | | /** |
654 | | * No Equality operators. |
655 | | * @internal |
656 | | */ |
657 | | virtual UBool operator==(const AlphabeticIndex& other) const; |
658 | | |
659 | | /** |
660 | | * Inequality operator. |
661 | | * @internal |
662 | | */ |
663 | | virtual UBool operator!=(const AlphabeticIndex& other) const; |
664 | | |
665 | | // Common initialization, for use from all constructors. |
666 | | void init(const Locale *locale, UErrorCode &status); |
667 | | |
668 | | /** |
669 | | * This method is called to get the index exemplars. Normally these come from the locale directly, |
670 | | * but if they aren't available, we have to synthesize them. |
671 | | */ |
672 | | void addIndexExemplars(const Locale &locale, UErrorCode &status); |
673 | | /** |
674 | | * Add Chinese index characters from the tailoring. |
675 | | */ |
676 | | UBool addChineseIndexCharacters(UErrorCode &errorCode); |
677 | | |
678 | | UVector *firstStringsInScript(UErrorCode &status); |
679 | | |
680 | | static UnicodeString separated(const UnicodeString &item); |
681 | | |
682 | | /** |
683 | | * Determine the best labels to use. |
684 | | * This is based on the exemplars, but we also process to make sure that they are unique, |
685 | | * and sort differently, and that the overall list is small enough. |
686 | | */ |
687 | | void initLabels(UVector &indexCharacters, UErrorCode &errorCode) const; |
688 | | BucketList *createBucketList(UErrorCode &errorCode) const; |
689 | | void initBuckets(UErrorCode &errorCode); |
690 | | void clearBuckets(); |
691 | | void internalResetBucketIterator(); |
692 | | |
693 | | public: |
694 | | |
695 | | // The Record is declared public only to allow access from |
696 | | // implementation code written in plain C. |
697 | | // It is not intended for public use. |
698 | | |
699 | | #ifndef U_HIDE_INTERNAL_API |
700 | | /** |
701 | | * A (name, data) pair, to be sorted by name into one of the index buckets. |
702 | | * The user data is not used by the index implementation. |
703 | | * @internal |
704 | | */ |
705 | | struct Record: public UMemory { |
706 | | const UnicodeString name_; |
707 | | const void *data_; |
708 | | Record(const UnicodeString &name, const void *data); |
709 | | ~Record(); |
710 | | }; |
711 | | #endif /* U_HIDE_INTERNAL_API */ |
712 | | |
713 | | private: |
714 | | |
715 | | /** |
716 | | * Holds all user records before they are distributed into buckets. |
717 | | * Type of contents is (Record *) |
718 | | * @internal |
719 | | */ |
720 | | UVector *inputList_; |
721 | | |
722 | | int32_t labelsIterIndex_; // Index of next item to return. |
723 | | int32_t itemsIterIndex_; |
724 | | Bucket *currentBucket_; // While an iteration of the index in underway, |
725 | | // point to the bucket for the current label. |
726 | | // NULL when no iteration underway. |
727 | | |
728 | | int32_t maxLabelCount_; // Limit on # of labels permitted in the index. |
729 | | |
730 | | UnicodeSet *initialLabels_; // Initial (unprocessed) set of Labels. Union |
731 | | // of those explicitly set by the user plus |
732 | | // those from locales. Raw values, before |
733 | | // crunching into bucket labels. |
734 | | |
735 | | UVector *firstCharsInScripts_; // The first character from each script, |
736 | | // in collation order. |
737 | | |
738 | | RuleBasedCollator *collator_; |
739 | | RuleBasedCollator *collatorPrimaryOnly_; |
740 | | |
741 | | // Lazy evaluated: null means that we have not built yet. |
742 | | BucketList *buckets_; |
743 | | |
744 | | UnicodeString inflowLabel_; |
745 | | UnicodeString overflowLabel_; |
746 | | UnicodeString underflowLabel_; |
747 | | UnicodeString overflowComparisonString_; |
748 | | |
749 | | UnicodeString emptyString_; |
750 | | }; |
751 | | |
752 | | U_NAMESPACE_END |
753 | | |
754 | | #endif // !UCONFIG_NO_COLLATION |
755 | | #endif |