1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/unicode/alphaindex.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,761 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* 1.7 +* Copyright (C) 2011-2013 International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************* 1.11 +*/ 1.12 + 1.13 +#ifndef INDEXCHARS_H 1.14 +#define INDEXCHARS_H 1.15 + 1.16 +#include "unicode/utypes.h" 1.17 +#include "unicode/uobject.h" 1.18 +#include "unicode/locid.h" 1.19 + 1.20 + 1.21 +#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_NORMALIZATION 1.22 + 1.23 +/** 1.24 + * \file 1.25 + * \brief C++ API: Index Characters 1.26 + */ 1.27 + 1.28 +U_CDECL_BEGIN 1.29 + 1.30 +/** 1.31 + * Constants for Alphabetic Index Label Types. 1.32 + * The form of these enum constants anticipates having a plain C API 1.33 + * for Alphabetic Indexes that will also use them. 1.34 + * @stable ICU 4.8 1.35 + */ 1.36 +typedef enum UAlphabeticIndexLabelType { 1.37 + /** 1.38 + * Normal Label, typically the starting letter of the names 1.39 + * in the bucket with this label. 1.40 + * @stable ICU 4.8 1.41 + */ 1.42 + U_ALPHAINDEX_NORMAL = 0, 1.43 + 1.44 + /** 1.45 + * Undeflow Label. The bucket with this label contains names 1.46 + * in scripts that sort before any of the bucket labels in this index. 1.47 + * @stable ICU 4.8 1.48 + */ 1.49 + U_ALPHAINDEX_UNDERFLOW = 1, 1.50 + 1.51 + /** 1.52 + * Inflow Label. The bucket with this label contains names 1.53 + * in scripts that sort between two of the bucket labels in this index. 1.54 + * Inflow labels are created when an index contains normal labels for 1.55 + * multiple scripts, and skips other scripts that sort between some of the 1.56 + * included scripts. 1.57 + * @stable ICU 4.8 1.58 + */ 1.59 + U_ALPHAINDEX_INFLOW = 2, 1.60 + 1.61 + /** 1.62 + * Overflow Label. Te bucket with this label contains names in scripts 1.63 + * that sort after all of the bucket labels in this index. 1.64 + * @stable ICU 4.8 1.65 + */ 1.66 + U_ALPHAINDEX_OVERFLOW = 3 1.67 +} UAlphabeticIndexLabelType; 1.68 + 1.69 + 1.70 +struct UHashtable; 1.71 +U_CDECL_END 1.72 + 1.73 +U_NAMESPACE_BEGIN 1.74 + 1.75 +// Forward Declarations 1.76 + 1.77 +class BucketList; 1.78 +class Collator; 1.79 +class RuleBasedCollator; 1.80 +class StringEnumeration; 1.81 +class UnicodeSet; 1.82 +class UVector; 1.83 + 1.84 +/** 1.85 + * AlphabeticIndex supports the creation of a UI index appropriate for a given language. 1.86 + * It can support either direct use, or use with a client that doesn't support localized collation. 1.87 + * The following is an example of what an index might look like in a UI: 1.88 + * 1.89 + * <pre> 1.90 + * <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> 1.91 + * 1.92 + * <b>A</b> 1.93 + * Addison 1.94 + * Albertson 1.95 + * Azensky 1.96 + * <b>B</b> 1.97 + * Baker 1.98 + * ... 1.99 + * </pre> 1.100 + * 1.101 + * The class can generate a list of labels for use as a UI "index", that is, a list of 1.102 + * clickable characters (or character sequences) that allow the user to see a segment 1.103 + * (bucket) of a larger "target" list. That is, each label corresponds to a bucket in 1.104 + * the target list, where everything in the bucket is greater than or equal to the character 1.105 + * (according to the locale's collation). Strings can be added to the index; 1.106 + * they will be in sorted order in the right bucket. 1.107 + * <p> 1.108 + * The class also supports having buckets for strings before the first (underflow), 1.109 + * after the last (overflow), and between scripts (inflow). For example, if the index 1.110 + * is constructed with labels for Russian and English, Greek characters would fall 1.111 + * into an inflow bucket between the other two scripts. 1.112 + * <p> 1.113 + * The AlphabeticIndex class is not intended for public subclassing. 1.114 + * 1.115 + * <p><em>Note:</em> If you expect to have a lot of ASCII or Latin characters 1.116 + * as well as characters from the user's language, 1.117 + * then it is a good idea to call addLabels(Locale::getEnglish(), status).</p> 1.118 + * 1.119 + * <h2>Direct Use</h2> 1.120 + * <p>The following shows an example of building an index directly. 1.121 + * The "show..." methods below are just to illustrate usage. 1.122 + * 1.123 + * <pre> 1.124 + * // Create a simple index. "Item" is assumed to be an application 1.125 + * // defined type that the application's UI and other processing knows about, 1.126 + * // and that has a name. 1.127 + * 1.128 + * UErrorCode status = U_ZERO_ERROR; 1.129 + * AlphabeticIndex index = new AlphabeticIndex(desiredLocale, status); 1.130 + * index->addLabels(additionalLocale, status); 1.131 + * for (Item *item in some source of Items ) { 1.132 + * index->addRecord(item->name(), item, status); 1.133 + * } 1.134 + * ... 1.135 + * // Show index at top. We could skip or gray out empty buckets 1.136 + * 1.137 + * while (index->nextBucket(status)) { 1.138 + * if (showAll || index->getBucketRecordCount() != 0) { 1.139 + * showLabelAtTop(UI, index->getBucketLabel()); 1.140 + * } 1.141 + * } 1.142 + * ... 1.143 + * // Show the buckets with their contents, skipping empty buckets 1.144 + * 1.145 + * index->resetBucketIterator(status); 1.146 + * while (index->nextBucket(status)) { 1.147 + * if (index->getBucketRecordCount() != 0) { 1.148 + * showLabelInList(UI, index->getBucketLabel()); 1.149 + * while (index->nextRecord(status)) { 1.150 + * showIndexedItem(UI, static_cast<Item *>(index->getRecordData())) 1.151 + * </pre> 1.152 + * 1.153 + * The caller can build different UIs using this class. 1.154 + * For example, an index character could be omitted or grayed-out 1.155 + * if its bucket is empty. Small buckets could also be combined based on size, such as: 1.156 + * 1.157 + * <pre> 1.158 + * <b>... A-F G-N O-Z ...</b> 1.159 + * </pre> 1.160 + * 1.161 + * <h2>Client Support</h2> 1.162 + * <p>Callers can also use the AlphabeticIndex::ImmutableIndex, or the AlphabeticIndex itself, 1.163 + * to support sorting on a client that doesn't support AlphabeticIndex functionality. 1.164 + * 1.165 + * <p>The ImmutableIndex is both immutable and thread-safe. 1.166 + * The corresponding AlphabeticIndex methods are not thread-safe because 1.167 + * they "lazily" build the index buckets. 1.168 + * <ul> 1.169 + * <li>ImmutableIndex.getBucket(index) provides random access to all 1.170 + * buckets and their labels and label types. 1.171 + * <li>The AlphabeticIndex bucket iterator or ImmutableIndex.getBucket(0..getBucketCount-1) 1.172 + * can be used to get a list of the labels, 1.173 + * such as "...", "A", "B",..., and send that list to the client. 1.174 + * <li>When the client has a new name, it sends that name to the server. 1.175 + * The server needs to call the following methods, 1.176 + * and communicate the bucketIndex and collationKey back to the client. 1.177 + * 1.178 + * <pre> 1.179 + * int32_t bucketIndex = index.getBucketIndex(name, status); 1.180 + * const UnicodeString &label = immutableIndex.getBucket(bucketIndex)->getLabel(); // optional 1.181 + * int32_t skLength = collator.getSortKey(name, sk, skCapacity); 1.182 + * </pre> 1.183 + * 1.184 + * <li>The client would put the name (and associated information) into its bucket for bucketIndex. The sort key sk is a 1.185 + * sequence of bytes that can be compared with a binary compare, and produce the right localized result.</li> 1.186 + * </ul> 1.187 + * 1.188 + * @stable ICU 4.8 1.189 + */ 1.190 +class U_I18N_API AlphabeticIndex: public UObject { 1.191 +public: 1.192 +#ifdef U_HIDE_DRAFT_API 1.193 + class Bucket; 1.194 +#else 1.195 + /** 1.196 + * An index "bucket" with a label string and type. 1.197 + * It is referenced by getBucketIndex(), 1.198 + * and returned by ImmutableIndex.getBucket(). 1.199 + * 1.200 + * The Bucket class is not intended for public subclassing. 1.201 + * @draft ICU 51 1.202 + */ 1.203 + class U_I18N_API Bucket : public UObject { 1.204 + public: 1.205 + /** 1.206 + * Destructor. 1.207 + * @draft ICU 51 1.208 + */ 1.209 + virtual ~Bucket(); 1.210 + 1.211 + /** 1.212 + * Returns the label string. 1.213 + * 1.214 + * @return the label string for the bucket 1.215 + * @draft ICU 51 1.216 + */ 1.217 + const UnicodeString &getLabel() const { return label_; } 1.218 + /** 1.219 + * Returns whether this bucket is a normal, underflow, overflow, or inflow bucket. 1.220 + * 1.221 + * @return the bucket label type 1.222 + * @draft ICU 51 1.223 + */ 1.224 + UAlphabeticIndexLabelType getLabelType() const { return labelType_; } 1.225 + 1.226 + private: 1.227 + friend class AlphabeticIndex; 1.228 + friend class BucketList; 1.229 + 1.230 + UnicodeString label_; 1.231 + UnicodeString lowerBoundary_; 1.232 + UAlphabeticIndexLabelType labelType_; 1.233 + Bucket *displayBucket_; 1.234 + int32_t displayIndex_; 1.235 + UVector *records_; // Records are owned by the inputList_ vector. 1.236 + 1.237 + Bucket(const UnicodeString &label, // Parameter strings are copied. 1.238 + const UnicodeString &lowerBoundary, 1.239 + UAlphabeticIndexLabelType type); 1.240 + }; 1.241 + 1.242 + /** 1.243 + * Immutable, thread-safe version of AlphabeticIndex. 1.244 + * This class provides thread-safe methods for bucketing, 1.245 + * and random access to buckets and their properties, 1.246 + * but does not offer adding records to the index. 1.247 + * 1.248 + * The ImmutableIndex class is not intended for public subclassing. 1.249 + * 1.250 + * @draft ICU 51 1.251 + */ 1.252 + class U_I18N_API ImmutableIndex : public UObject { 1.253 + public: 1.254 + /** 1.255 + * Destructor. 1.256 + * @draft ICU 51 1.257 + */ 1.258 + virtual ~ImmutableIndex(); 1.259 + 1.260 + /** 1.261 + * Returns the number of index buckets and labels, including underflow/inflow/overflow. 1.262 + * 1.263 + * @return the number of index buckets 1.264 + * @draft ICU 51 1.265 + */ 1.266 + int32_t getBucketCount() const; 1.267 + 1.268 + /** 1.269 + * Finds the index bucket for the given name and returns the number of that bucket. 1.270 + * Use getBucket() to get the bucket's properties. 1.271 + * 1.272 + * @param name the string to be sorted into an index bucket 1.273 + * @return the bucket number for the name 1.274 + * @draft ICU 51 1.275 + */ 1.276 + int32_t getBucketIndex(const UnicodeString &name, UErrorCode &errorCode) const; 1.277 + 1.278 + /** 1.279 + * Returns the index-th bucket. Returns NULL if the index is out of range. 1.280 + * 1.281 + * @param index bucket number 1.282 + * @return the index-th bucket 1.283 + * @draft ICU 51 1.284 + */ 1.285 + const Bucket *getBucket(int32_t index) const; 1.286 + 1.287 + private: 1.288 + friend class AlphabeticIndex; 1.289 + 1.290 + ImmutableIndex(BucketList *bucketList, Collator *collatorPrimaryOnly) 1.291 + : buckets_(bucketList), collatorPrimaryOnly_(collatorPrimaryOnly) {} 1.292 + 1.293 + BucketList *buckets_; 1.294 + Collator *collatorPrimaryOnly_; 1.295 + }; 1.296 +#endif /* U_HIDE_DRAFT_API */ 1.297 + 1.298 + /** 1.299 + * Construct an AlphabeticIndex object for the specified locale. If the locale's 1.300 + * data does not include index characters, a set of them will be 1.301 + * synthesized based on the locale's exemplar characters. The locale 1.302 + * determines the sorting order for both the index characters and the 1.303 + * user item names appearing under each Index character. 1.304 + * 1.305 + * @param locale the desired locale. 1.306 + * @param status Error code, will be set with the reason if the construction 1.307 + * of the AlphabeticIndex object fails. 1.308 + * @stable ICU 4.8 1.309 + */ 1.310 + AlphabeticIndex(const Locale &locale, UErrorCode &status); 1.311 + 1.312 +#ifndef U_HIDE_DRAFT_API 1.313 + /** 1.314 + * Construct an AlphabeticIndex that uses a specific collator. 1.315 + * 1.316 + * The index will be created with no labels; the addLabels() function must be called 1.317 + * after creation to add the desired labels to the index. 1.318 + * 1.319 + * The index adopts the collator, and is responsible for deleting it. 1.320 + * The caller should make no further use of the collator after creating the index. 1.321 + * 1.322 + * @param collator The collator to use to order the contents of this index. 1.323 + * @param status Error code, will be set with the reason if the 1.324 + * operation fails. 1.325 + * @draft ICU 51 1.326 + */ 1.327 + AlphabeticIndex(RuleBasedCollator *collator, UErrorCode &status); 1.328 +#endif /* U_HIDE_DRAFT_API */ 1.329 + 1.330 + /** 1.331 + * Add Labels to this Index. The labels are additions to those 1.332 + * that are already in the index; they do not replace the existing 1.333 + * ones. 1.334 + * @param additions The additional characters to add to the index, such as A-Z. 1.335 + * @param status Error code, will be set with the reason if the 1.336 + * operation fails. 1.337 + * @return this, for chaining 1.338 + * @stable ICU 4.8 1.339 + */ 1.340 + virtual AlphabeticIndex &addLabels(const UnicodeSet &additions, UErrorCode &status); 1.341 + 1.342 + /** 1.343 + * Add the index characters from a Locale to the index. The labels 1.344 + * are added to those that are already in the index; they do not replace the 1.345 + * existing index characters. The collation order for this index is not 1.346 + * changed; it remains that of the locale that was originally specified 1.347 + * when creating this Index. 1.348 + * 1.349 + * @param locale The locale whose index characters are to be added. 1.350 + * @param status Error code, will be set with the reason if the 1.351 + * operation fails. 1.352 + * @return this, for chaining 1.353 + * @stable ICU 4.8 1.354 + */ 1.355 + virtual AlphabeticIndex &addLabels(const Locale &locale, UErrorCode &status); 1.356 + 1.357 + /** 1.358 + * Destructor 1.359 + * @stable ICU 4.8 1.360 + */ 1.361 + virtual ~AlphabeticIndex(); 1.362 + 1.363 +#ifndef U_HIDE_DRAFT_API 1.364 + /** 1.365 + * Builds an immutable, thread-safe version of this instance, without data records. 1.366 + * 1.367 + * @return an immutable index instance 1.368 + * @draft ICU 51 1.369 + */ 1.370 + ImmutableIndex *buildImmutableIndex(UErrorCode &errorCode); 1.371 +#endif /* U_HIDE_DRAFT_API */ 1.372 + 1.373 + /** 1.374 + * Get the Collator that establishes the ordering of the items in this index. 1.375 + * Ownership of the collator remains with the AlphabeticIndex instance. 1.376 + * 1.377 + * The returned collator is a reference to the internal collator used by this 1.378 + * index. It may be safely used to compare the names of items or to get 1.379 + * sort keys for names. However if any settings need to be changed, 1.380 + * or other non-const methods called, a cloned copy must be made first. 1.381 + * 1.382 + * @return The collator 1.383 + * @stable ICU 4.8 1.384 + */ 1.385 + virtual const RuleBasedCollator &getCollator() const; 1.386 + 1.387 + 1.388 + /** 1.389 + * Get the default label used for abbreviated buckets <i>between</i> other index characters. 1.390 + * For example, consider the labels when Latin and Greek are used: 1.391 + * X Y Z ... Α Β Γ. 1.392 + * 1.393 + * @return inflow label 1.394 + * @stable ICU 4.8 1.395 + */ 1.396 + virtual const UnicodeString &getInflowLabel() const; 1.397 + 1.398 + /** 1.399 + * Set the default label used for abbreviated buckets <i>between</i> other index characters. 1.400 + * An inflow label will be automatically inserted if two otherwise-adjacent label characters 1.401 + * are from different scripts, e.g. Latin and Cyrillic, and a third script, e.g. Greek, 1.402 + * sorts between the two. The default inflow character is an ellipsis (...) 1.403 + * 1.404 + * @param inflowLabel the new Inflow label. 1.405 + * @param status Error code, will be set with the reason if the operation fails. 1.406 + * @return this 1.407 + * @stable ICU 4.8 1.408 + */ 1.409 + virtual AlphabeticIndex &setInflowLabel(const UnicodeString &inflowLabel, UErrorCode &status); 1.410 + 1.411 + 1.412 + /** 1.413 + * Get the special label used for items that sort after the last normal label, 1.414 + * and that would not otherwise have an appropriate label. 1.415 + * 1.416 + * @return the overflow label 1.417 + * @stable ICU 4.8 1.418 + */ 1.419 + virtual const UnicodeString &getOverflowLabel() const; 1.420 + 1.421 + 1.422 + /** 1.423 + * Set the label used for items that sort after the last normal label, 1.424 + * and that would not otherwise have an appropriate label. 1.425 + * 1.426 + * @param overflowLabel the new overflow label. 1.427 + * @param status Error code, will be set with the reason if the operation fails. 1.428 + * @return this 1.429 + * @stable ICU 4.8 1.430 + */ 1.431 + virtual AlphabeticIndex &setOverflowLabel(const UnicodeString &overflowLabel, UErrorCode &status); 1.432 + 1.433 + /** 1.434 + * Get the special label used for items that sort before the first normal label, 1.435 + * and that would not otherwise have an appropriate label. 1.436 + * 1.437 + * @return underflow label 1.438 + * @stable ICU 4.8 1.439 + */ 1.440 + virtual const UnicodeString &getUnderflowLabel() const; 1.441 + 1.442 + /** 1.443 + * Set the label used for items that sort before the first normal label, 1.444 + * and that would not otherwise have an appropriate label. 1.445 + * 1.446 + * @param underflowLabel the new underflow label. 1.447 + * @param status Error code, will be set with the reason if the operation fails. 1.448 + * @return this 1.449 + * @stable ICU 4.8 1.450 + */ 1.451 + virtual AlphabeticIndex &setUnderflowLabel(const UnicodeString &underflowLabel, UErrorCode &status); 1.452 + 1.453 + 1.454 + /** 1.455 + * Get the limit on the number of labels permitted in the index. 1.456 + * The number does not include over, under and inflow labels. 1.457 + * 1.458 + * @return maxLabelCount maximum number of labels. 1.459 + * @stable ICU 4.8 1.460 + */ 1.461 + virtual int32_t getMaxLabelCount() const; 1.462 + 1.463 + /** 1.464 + * Set a limit on the number of labels permitted in the index. 1.465 + * The number does not include over, under and inflow labels. 1.466 + * Currently, if the number is exceeded, then every 1.467 + * nth item is removed to bring the count down. 1.468 + * A more sophisticated mechanism may be available in the future. 1.469 + * 1.470 + * @param maxLabelCount the maximum number of labels. 1.471 + * @param status error code 1.472 + * @return This, for chaining 1.473 + * @stable ICU 4.8 1.474 + */ 1.475 + virtual AlphabeticIndex &setMaxLabelCount(int32_t maxLabelCount, UErrorCode &status); 1.476 + 1.477 + 1.478 + /** 1.479 + * Add a record to the index. Each record will be associated with an index Bucket 1.480 + * based on the record's name. The list of records for each bucket will be sorted 1.481 + * based on the collation ordering of the names in the index's locale. 1.482 + * Records with duplicate names are permitted; they will be kept in the order 1.483 + * that they were added. 1.484 + * 1.485 + * @param name The display name for the Record. The Record will be placed in 1.486 + * a bucket based on this name. 1.487 + * @param data An optional pointer to user data associated with this 1.488 + * item. When iterating the contents of a bucket, both the 1.489 + * data pointer the name will be available for each Record. 1.490 + * @param status Error code, will be set with the reason if the operation fails. 1.491 + * @return This, for chaining. 1.492 + * @stable ICU 4.8 1.493 + */ 1.494 + virtual AlphabeticIndex &addRecord(const UnicodeString &name, const void *data, UErrorCode &status); 1.495 + 1.496 + /** 1.497 + * Remove all Records from the Index. The set of Buckets, which define the headings under 1.498 + * which records are classified, is not altered. 1.499 + * 1.500 + * @param status Error code, will be set with the reason if the operation fails. 1.501 + * @return This, for chaining. 1.502 + * @stable ICU 4.8 1.503 + */ 1.504 + virtual AlphabeticIndex &clearRecords(UErrorCode &status); 1.505 + 1.506 + 1.507 + /** Get the number of labels in this index. 1.508 + * Note: may trigger lazy index construction. 1.509 + * 1.510 + * @param status Error code, will be set with the reason if the operation fails. 1.511 + * @return The number of labels in this index, including any under, over or 1.512 + * in-flow labels. 1.513 + * @stable ICU 4.8 1.514 + */ 1.515 + virtual int32_t getBucketCount(UErrorCode &status); 1.516 + 1.517 + 1.518 + /** Get the total number of Records in this index, that is, the number 1.519 + * of <name, data> pairs added. 1.520 + * 1.521 + * @param status Error code, will be set with the reason if the operation fails. 1.522 + * @return The number of records in this index, that is, the total number 1.523 + * of (name, data) items added with addRecord(). 1.524 + * @stable ICU 4.8 1.525 + */ 1.526 + virtual int32_t getRecordCount(UErrorCode &status); 1.527 + 1.528 + 1.529 + 1.530 + /** 1.531 + * Given the name of a record, return the zero-based index of the Bucket 1.532 + * in which the item should appear. The name need not be in the index. 1.533 + * A Record will not be added to the index by this function. 1.534 + * Bucket numbers are zero-based, in Bucket iteration order. 1.535 + * 1.536 + * @param itemName The name whose bucket position in the index is to be determined. 1.537 + * @param status Error code, will be set with the reason if the operation fails. 1.538 + * @return The bucket number for this name. 1.539 + * @stable ICU 4.8 1.540 + * 1.541 + */ 1.542 + virtual int32_t getBucketIndex(const UnicodeString &itemName, UErrorCode &status); 1.543 + 1.544 + 1.545 + /** 1.546 + * Get the zero based index of the current Bucket from an iteration 1.547 + * over the Buckets of this index. Return -1 if no iteration is in process. 1.548 + * @return the index of the current Bucket 1.549 + * @stable ICU 4.8 1.550 + */ 1.551 + virtual int32_t getBucketIndex() const; 1.552 + 1.553 + 1.554 + /** 1.555 + * Advance the iteration over the Buckets of this index. Return FALSE if 1.556 + * there are no more Buckets. 1.557 + * 1.558 + * @param status Error code, will be set with the reason if the operation fails. 1.559 + * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while 1.560 + * an enumeration of its contents are in process. 1.561 + * 1.562 + * @return TRUE if success, FALSE if at end of iteration 1.563 + * @stable ICU 4.8 1.564 + */ 1.565 + virtual UBool nextBucket(UErrorCode &status); 1.566 + 1.567 + /** 1.568 + * Return the name of the Label of the current bucket from an iteration over the buckets. 1.569 + * If the iteration is before the first Bucket (nextBucket() has not been called), 1.570 + * or after the last, return an empty string. 1.571 + * 1.572 + * @return the bucket label. 1.573 + * @stable ICU 4.8 1.574 + */ 1.575 + virtual const UnicodeString &getBucketLabel() const; 1.576 + 1.577 + /** 1.578 + * Return the type of the label for the current Bucket (selected by the 1.579 + * iteration over Buckets.) 1.580 + * 1.581 + * @return the label type. 1.582 + * @stable ICU 4.8 1.583 + */ 1.584 + virtual UAlphabeticIndexLabelType getBucketLabelType() const; 1.585 + 1.586 + /** 1.587 + * Get the number of <name, data> Records in the current Bucket. 1.588 + * If the current bucket iteration position is before the first label or after the 1.589 + * last, return 0. 1.590 + * 1.591 + * @return the number of Records. 1.592 + * @stable ICU 4.8 1.593 + */ 1.594 + virtual int32_t getBucketRecordCount() const; 1.595 + 1.596 + 1.597 + /** 1.598 + * Reset the Bucket iteration for this index. The next call to nextBucket() 1.599 + * will restart the iteration at the first label. 1.600 + * 1.601 + * @param status Error code, will be set with the reason if the operation fails. 1.602 + * @return this, for chaining. 1.603 + * @stable ICU 4.8 1.604 + */ 1.605 + virtual AlphabeticIndex &resetBucketIterator(UErrorCode &status); 1.606 + 1.607 + /** 1.608 + * Advance to the next record in the current Bucket. 1.609 + * When nextBucket() is called, Record iteration is reset to just before the 1.610 + * first Record in the new Bucket. 1.611 + * 1.612 + * @param status Error code, will be set with the reason if the operation fails. 1.613 + * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while 1.614 + * an enumeration of its contents are in process. 1.615 + * @return TRUE if successful, FALSE when the iteration advances past the last item. 1.616 + * @stable ICU 4.8 1.617 + */ 1.618 + virtual UBool nextRecord(UErrorCode &status); 1.619 + 1.620 + /** 1.621 + * Get the name of the current Record. 1.622 + * Return an empty string if the Record iteration position is before first 1.623 + * or after the last. 1.624 + * 1.625 + * @return The name of the current index item. 1.626 + * @stable ICU 4.8 1.627 + */ 1.628 + virtual const UnicodeString &getRecordName() const; 1.629 + 1.630 + 1.631 + /** 1.632 + * Return the data pointer of the Record currently being iterated over. 1.633 + * Return NULL if the current iteration position before the first item in this Bucket, 1.634 + * or after the last. 1.635 + * 1.636 + * @return The current Record's data pointer. 1.637 + * @stable ICU 4.8 1.638 + */ 1.639 + virtual const void *getRecordData() const; 1.640 + 1.641 + 1.642 + /** 1.643 + * Reset the Record iterator position to before the first Record in the current Bucket. 1.644 + * 1.645 + * @return This, for chaining. 1.646 + * @stable ICU 4.8 1.647 + */ 1.648 + virtual AlphabeticIndex &resetRecordIterator(); 1.649 + 1.650 +private: 1.651 + /** 1.652 + * No Copy constructor. 1.653 + * @internal 1.654 + */ 1.655 + AlphabeticIndex(const AlphabeticIndex &other); 1.656 + 1.657 + /** 1.658 + * No assignment. 1.659 + */ 1.660 + AlphabeticIndex &operator =(const AlphabeticIndex & /*other*/) { return *this;}; 1.661 + 1.662 + /** 1.663 + * No Equality operators. 1.664 + * @internal 1.665 + */ 1.666 + virtual UBool operator==(const AlphabeticIndex& other) const; 1.667 + 1.668 + /** 1.669 + * Inequality operator. 1.670 + * @internal 1.671 + */ 1.672 + virtual UBool operator!=(const AlphabeticIndex& other) const; 1.673 + 1.674 + // Common initialization, for use from all constructors. 1.675 + void init(const Locale *locale, UErrorCode &status); 1.676 + 1.677 + /** 1.678 + * This method is called to get the index exemplars. Normally these come from the locale directly, 1.679 + * but if they aren't available, we have to synthesize them. 1.680 + */ 1.681 + void addIndexExemplars(const Locale &locale, UErrorCode &status); 1.682 + /** 1.683 + * Add Chinese index characters from the tailoring. 1.684 + */ 1.685 + UBool addChineseIndexCharacters(UErrorCode &errorCode); 1.686 + 1.687 + UVector *firstStringsInScript(UErrorCode &status); 1.688 + 1.689 + static UnicodeString separated(const UnicodeString &item); 1.690 + 1.691 + /** 1.692 + * Determine the best labels to use. 1.693 + * This is based on the exemplars, but we also process to make sure that they are unique, 1.694 + * and sort differently, and that the overall list is small enough. 1.695 + */ 1.696 + void initLabels(UVector &indexCharacters, UErrorCode &errorCode) const; 1.697 + BucketList *createBucketList(UErrorCode &errorCode) const; 1.698 + void initBuckets(UErrorCode &errorCode); 1.699 + void clearBuckets(); 1.700 + void internalResetBucketIterator(); 1.701 + 1.702 +public: 1.703 + 1.704 + // The Record is declared public only to allow access from 1.705 + // implementation code written in plain C. 1.706 + // It is not intended for public use. 1.707 + 1.708 +#ifndef U_HIDE_INTERNAL_API 1.709 + /** 1.710 + * A (name, data) pair, to be sorted by name into one of the index buckets. 1.711 + * The user data is not used by the index implementation. 1.712 + * @internal 1.713 + */ 1.714 + struct Record: public UMemory { 1.715 + const UnicodeString name_; 1.716 + const void *data_; 1.717 + Record(const UnicodeString &name, const void *data); 1.718 + ~Record(); 1.719 + }; 1.720 +#endif /* U_HIDE_INTERNAL_API */ 1.721 + 1.722 +private: 1.723 + 1.724 + /** 1.725 + * Holds all user records before they are distributed into buckets. 1.726 + * Type of contents is (Record *) 1.727 + * @internal 1.728 + */ 1.729 + UVector *inputList_; 1.730 + 1.731 + int32_t labelsIterIndex_; // Index of next item to return. 1.732 + int32_t itemsIterIndex_; 1.733 + Bucket *currentBucket_; // While an iteration of the index in underway, 1.734 + // point to the bucket for the current label. 1.735 + // NULL when no iteration underway. 1.736 + 1.737 + int32_t maxLabelCount_; // Limit on # of labels permitted in the index. 1.738 + 1.739 + UnicodeSet *initialLabels_; // Initial (unprocessed) set of Labels. Union 1.740 + // of those explicitly set by the user plus 1.741 + // those from locales. Raw values, before 1.742 + // crunching into bucket labels. 1.743 + 1.744 + UVector *firstCharsInScripts_; // The first character from each script, 1.745 + // in collation order. 1.746 + 1.747 + RuleBasedCollator *collator_; 1.748 + RuleBasedCollator *collatorPrimaryOnly_; 1.749 + 1.750 + // Lazy evaluated: null means that we have not built yet. 1.751 + BucketList *buckets_; 1.752 + 1.753 + UnicodeString inflowLabel_; 1.754 + UnicodeString overflowLabel_; 1.755 + UnicodeString underflowLabel_; 1.756 + UnicodeString overflowComparisonString_; 1.757 + 1.758 + UnicodeString emptyString_; 1.759 +}; 1.760 + 1.761 +U_NAMESPACE_END 1.762 + 1.763 +#endif /* UCONFIG_NO_COLLATION / UCONFIG_NO_NORMALIZATION */ 1.764 +#endif