intl/icu/source/common/unicode/ucharstrie.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/common/unicode/ucharstrie.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,576 @@
     1.4 +/*
     1.5 +*******************************************************************************
     1.6 +*   Copyright (C) 2010-2012, International Business Machines
     1.7 +*   Corporation and others.  All Rights Reserved.
     1.8 +*******************************************************************************
     1.9 +*   file name:  ucharstrie.h
    1.10 +*   encoding:   US-ASCII
    1.11 +*   tab size:   8 (not used)
    1.12 +*   indentation:4
    1.13 +*
    1.14 +*   created on: 2010nov14
    1.15 +*   created by: Markus W. Scherer
    1.16 +*/
    1.17 +
    1.18 +#ifndef __UCHARSTRIE_H__
    1.19 +#define __UCHARSTRIE_H__
    1.20 +
    1.21 +/**
    1.22 + * \file
    1.23 + * \brief C++ API: Trie for mapping Unicode strings (or 16-bit-unit sequences)
    1.24 + *                 to integer values.
    1.25 + */
    1.26 +
    1.27 +#include "unicode/utypes.h"
    1.28 +#include "unicode/unistr.h"
    1.29 +#include "unicode/uobject.h"
    1.30 +#include "unicode/ustringtrie.h"
    1.31 +
    1.32 +U_NAMESPACE_BEGIN
    1.33 +
    1.34 +class Appendable;
    1.35 +class UCharsTrieBuilder;
    1.36 +class UVector32;
    1.37 +
    1.38 +/**
    1.39 + * Light-weight, non-const reader class for a UCharsTrie.
    1.40 + * Traverses a UChar-serialized data structure with minimal state,
    1.41 + * for mapping strings (16-bit-unit sequences) to non-negative integer values.
    1.42 + *
    1.43 + * This class owns the serialized trie data only if it was constructed by
    1.44 + * the builder's build() method.
    1.45 + * The public constructor and the copy constructor only alias the data (only copy the pointer).
    1.46 + * There is no assignment operator.
    1.47 + *
    1.48 + * This class is not intended for public subclassing.
    1.49 + * @stable ICU 4.8
    1.50 + */
    1.51 +class U_COMMON_API UCharsTrie : public UMemory {
    1.52 +public:
    1.53 +    /**
    1.54 +     * Constructs a UCharsTrie reader instance.
    1.55 +     *
    1.56 +     * The trieUChars must contain a copy of a UChar sequence from the UCharsTrieBuilder,
    1.57 +     * starting with the first UChar of that sequence.
    1.58 +     * The UCharsTrie object will not read more UChars than
    1.59 +     * the UCharsTrieBuilder generated in the corresponding build() call.
    1.60 +     *
    1.61 +     * The array is not copied/cloned and must not be modified while
    1.62 +     * the UCharsTrie object is in use.
    1.63 +     *
    1.64 +     * @param trieUChars The UChar array that contains the serialized trie.
    1.65 +     * @stable ICU 4.8
    1.66 +     */
    1.67 +    UCharsTrie(const UChar *trieUChars)
    1.68 +            : ownedArray_(NULL), uchars_(trieUChars),
    1.69 +              pos_(uchars_), remainingMatchLength_(-1) {}
    1.70 +
    1.71 +    /**
    1.72 +     * Destructor.
    1.73 +     * @stable ICU 4.8
    1.74 +     */
    1.75 +    ~UCharsTrie();
    1.76 +
    1.77 +    /**
    1.78 +     * Copy constructor, copies the other trie reader object and its state,
    1.79 +     * but not the UChar array which will be shared. (Shallow copy.)
    1.80 +     * @param other Another UCharsTrie object.
    1.81 +     * @stable ICU 4.8
    1.82 +     */
    1.83 +    UCharsTrie(const UCharsTrie &other)
    1.84 +            : ownedArray_(NULL), uchars_(other.uchars_),
    1.85 +              pos_(other.pos_), remainingMatchLength_(other.remainingMatchLength_) {}
    1.86 +
    1.87 +    /**
    1.88 +     * Resets this trie to its initial state.
    1.89 +     * @return *this
    1.90 +     * @stable ICU 4.8
    1.91 +     */
    1.92 +    UCharsTrie &reset() {
    1.93 +        pos_=uchars_;
    1.94 +        remainingMatchLength_=-1;
    1.95 +        return *this;
    1.96 +    }
    1.97 +
    1.98 +    /**
    1.99 +     * UCharsTrie state object, for saving a trie's current state
   1.100 +     * and resetting the trie back to this state later.
   1.101 +     * @stable ICU 4.8
   1.102 +     */
   1.103 +    class State : public UMemory {
   1.104 +    public:
   1.105 +        /**
   1.106 +         * Constructs an empty State.
   1.107 +         * @stable ICU 4.8
   1.108 +         */
   1.109 +        State() { uchars=NULL; }
   1.110 +    private:
   1.111 +        friend class UCharsTrie;
   1.112 +
   1.113 +        const UChar *uchars;
   1.114 +        const UChar *pos;
   1.115 +        int32_t remainingMatchLength;
   1.116 +    };
   1.117 +
   1.118 +    /**
   1.119 +     * Saves the state of this trie.
   1.120 +     * @param state The State object to hold the trie's state.
   1.121 +     * @return *this
   1.122 +     * @see resetToState
   1.123 +     * @stable ICU 4.8
   1.124 +     */
   1.125 +    const UCharsTrie &saveState(State &state) const {
   1.126 +        state.uchars=uchars_;
   1.127 +        state.pos=pos_;
   1.128 +        state.remainingMatchLength=remainingMatchLength_;
   1.129 +        return *this;
   1.130 +    }
   1.131 +
   1.132 +    /**
   1.133 +     * Resets this trie to the saved state.
   1.134 +     * If the state object contains no state, or the state of a different trie,
   1.135 +     * then this trie remains unchanged.
   1.136 +     * @param state The State object which holds a saved trie state.
   1.137 +     * @return *this
   1.138 +     * @see saveState
   1.139 +     * @see reset
   1.140 +     * @stable ICU 4.8
   1.141 +     */
   1.142 +    UCharsTrie &resetToState(const State &state) {
   1.143 +        if(uchars_==state.uchars && uchars_!=NULL) {
   1.144 +            pos_=state.pos;
   1.145 +            remainingMatchLength_=state.remainingMatchLength;
   1.146 +        }
   1.147 +        return *this;
   1.148 +    }
   1.149 +
   1.150 +    /**
   1.151 +     * Determines whether the string so far matches, whether it has a value,
   1.152 +     * and whether another input UChar can continue a matching string.
   1.153 +     * @return The match/value Result.
   1.154 +     * @stable ICU 4.8
   1.155 +     */
   1.156 +    UStringTrieResult current() const;
   1.157 +
   1.158 +    /**
   1.159 +     * Traverses the trie from the initial state for this input UChar.
   1.160 +     * Equivalent to reset().next(uchar).
   1.161 +     * @param uchar Input char value. Values below 0 and above 0xffff will never match.
   1.162 +     * @return The match/value Result.
   1.163 +     * @stable ICU 4.8
   1.164 +     */
   1.165 +    inline UStringTrieResult first(int32_t uchar) {
   1.166 +        remainingMatchLength_=-1;
   1.167 +        return nextImpl(uchars_, uchar);
   1.168 +    }
   1.169 +
   1.170 +    /**
   1.171 +     * Traverses the trie from the initial state for the
   1.172 +     * one or two UTF-16 code units for this input code point.
   1.173 +     * Equivalent to reset().nextForCodePoint(cp).
   1.174 +     * @param cp A Unicode code point 0..0x10ffff.
   1.175 +     * @return The match/value Result.
   1.176 +     * @stable ICU 4.8
   1.177 +     */
   1.178 +    UStringTrieResult firstForCodePoint(UChar32 cp);
   1.179 +
   1.180 +    /**
   1.181 +     * Traverses the trie from the current state for this input UChar.
   1.182 +     * @param uchar Input char value. Values below 0 and above 0xffff will never match.
   1.183 +     * @return The match/value Result.
   1.184 +     * @stable ICU 4.8
   1.185 +     */
   1.186 +    UStringTrieResult next(int32_t uchar);
   1.187 +
   1.188 +    /**
   1.189 +     * Traverses the trie from the current state for the
   1.190 +     * one or two UTF-16 code units for this input code point.
   1.191 +     * @param cp A Unicode code point 0..0x10ffff.
   1.192 +     * @return The match/value Result.
   1.193 +     * @stable ICU 4.8
   1.194 +     */
   1.195 +    UStringTrieResult nextForCodePoint(UChar32 cp);
   1.196 +
   1.197 +    /**
   1.198 +     * Traverses the trie from the current state for this string.
   1.199 +     * Equivalent to
   1.200 +     * \code
   1.201 +     * Result result=current();
   1.202 +     * for(each c in s)
   1.203 +     *   if(!USTRINGTRIE_HAS_NEXT(result)) return USTRINGTRIE_NO_MATCH;
   1.204 +     *   result=next(c);
   1.205 +     * return result;
   1.206 +     * \endcode
   1.207 +     * @param s A string. Can be NULL if length is 0.
   1.208 +     * @param length The length of the string. Can be -1 if NUL-terminated.
   1.209 +     * @return The match/value Result.
   1.210 +     * @stable ICU 4.8
   1.211 +     */
   1.212 +    UStringTrieResult next(const UChar *s, int32_t length);
   1.213 +
   1.214 +    /**
   1.215 +     * Returns a matching string's value if called immediately after
   1.216 +     * current()/first()/next() returned USTRINGTRIE_INTERMEDIATE_VALUE or USTRINGTRIE_FINAL_VALUE.
   1.217 +     * getValue() can be called multiple times.
   1.218 +     *
   1.219 +     * Do not call getValue() after USTRINGTRIE_NO_MATCH or USTRINGTRIE_NO_VALUE!
   1.220 +     * @return The value for the string so far.
   1.221 +     * @stable ICU 4.8
   1.222 +     */
   1.223 +    inline int32_t getValue() const {
   1.224 +        const UChar *pos=pos_;
   1.225 +        int32_t leadUnit=*pos++;
   1.226 +        // U_ASSERT(leadUnit>=kMinValueLead);
   1.227 +        return leadUnit&kValueIsFinal ?
   1.228 +            readValue(pos, leadUnit&0x7fff) : readNodeValue(pos, leadUnit);
   1.229 +    }
   1.230 +
   1.231 +    /**
   1.232 +     * Determines whether all strings reachable from the current state
   1.233 +     * map to the same value.
   1.234 +     * @param uniqueValue Receives the unique value, if this function returns TRUE.
   1.235 +     *                    (output-only)
   1.236 +     * @return TRUE if all strings reachable from the current state
   1.237 +     *         map to the same value.
   1.238 +     * @stable ICU 4.8
   1.239 +     */
   1.240 +    inline UBool hasUniqueValue(int32_t &uniqueValue) const {
   1.241 +        const UChar *pos=pos_;
   1.242 +        // Skip the rest of a pending linear-match node.
   1.243 +        return pos!=NULL && findUniqueValue(pos+remainingMatchLength_+1, FALSE, uniqueValue);
   1.244 +    }
   1.245 +
   1.246 +    /**
   1.247 +     * Finds each UChar which continues the string from the current state.
   1.248 +     * That is, each UChar c for which it would be next(c)!=USTRINGTRIE_NO_MATCH now.
   1.249 +     * @param out Each next UChar is appended to this object.
   1.250 +     * @return the number of UChars which continue the string from here
   1.251 +     * @stable ICU 4.8
   1.252 +     */
   1.253 +    int32_t getNextUChars(Appendable &out) const;
   1.254 +
   1.255 +    /**
   1.256 +     * Iterator for all of the (string, value) pairs in a UCharsTrie.
   1.257 +     * @stable ICU 4.8
   1.258 +     */
   1.259 +    class U_COMMON_API Iterator : public UMemory {
   1.260 +    public:
   1.261 +        /**
   1.262 +         * Iterates from the root of a UChar-serialized UCharsTrie.
   1.263 +         * @param trieUChars The trie UChars.
   1.264 +         * @param maxStringLength If 0, the iterator returns full strings.
   1.265 +         *                        Otherwise, the iterator returns strings with this maximum length.
   1.266 +         * @param errorCode Standard ICU error code. Its input value must
   1.267 +         *                  pass the U_SUCCESS() test, or else the function returns
   1.268 +         *                  immediately. Check for U_FAILURE() on output or use with
   1.269 +         *                  function chaining. (See User Guide for details.)
   1.270 +         * @stable ICU 4.8
   1.271 +         */
   1.272 +        Iterator(const UChar *trieUChars, int32_t maxStringLength, UErrorCode &errorCode);
   1.273 +
   1.274 +        /**
   1.275 +         * Iterates from the current state of the specified UCharsTrie.
   1.276 +         * @param trie The trie whose state will be copied for iteration.
   1.277 +         * @param maxStringLength If 0, the iterator returns full strings.
   1.278 +         *                        Otherwise, the iterator returns strings with this maximum length.
   1.279 +         * @param errorCode Standard ICU error code. Its input value must
   1.280 +         *                  pass the U_SUCCESS() test, or else the function returns
   1.281 +         *                  immediately. Check for U_FAILURE() on output or use with
   1.282 +         *                  function chaining. (See User Guide for details.)
   1.283 +         * @stable ICU 4.8
   1.284 +         */
   1.285 +        Iterator(const UCharsTrie &trie, int32_t maxStringLength, UErrorCode &errorCode);
   1.286 +
   1.287 +        /**
   1.288 +         * Destructor.
   1.289 +         * @stable ICU 4.8
   1.290 +         */
   1.291 +        ~Iterator();
   1.292 +
   1.293 +        /**
   1.294 +         * Resets this iterator to its initial state.
   1.295 +         * @return *this
   1.296 +         * @stable ICU 4.8
   1.297 +         */
   1.298 +        Iterator &reset();
   1.299 +
   1.300 +        /**
   1.301 +         * @return TRUE if there are more elements.
   1.302 +         * @stable ICU 4.8
   1.303 +         */
   1.304 +        UBool hasNext() const;
   1.305 +
   1.306 +        /**
   1.307 +         * Finds the next (string, value) pair if there is one.
   1.308 +         *
   1.309 +         * If the string is truncated to the maximum length and does not
   1.310 +         * have a real value, then the value is set to -1.
   1.311 +         * In this case, this "not a real value" is indistinguishable from
   1.312 +         * a real value of -1.
   1.313 +         * @param errorCode Standard ICU error code. Its input value must
   1.314 +         *                  pass the U_SUCCESS() test, or else the function returns
   1.315 +         *                  immediately. Check for U_FAILURE() on output or use with
   1.316 +         *                  function chaining. (See User Guide for details.)
   1.317 +         * @return TRUE if there is another element.
   1.318 +         * @stable ICU 4.8
   1.319 +         */
   1.320 +        UBool next(UErrorCode &errorCode);
   1.321 +
   1.322 +        /**
   1.323 +         * @return The string for the last successful next().
   1.324 +         * @stable ICU 4.8
   1.325 +         */
   1.326 +        const UnicodeString &getString() const { return str_; }
   1.327 +        /**
   1.328 +         * @return The value for the last successful next().
   1.329 +         * @stable ICU 4.8
   1.330 +         */
   1.331 +        int32_t getValue() const { return value_; }
   1.332 +
   1.333 +    private:
   1.334 +        UBool truncateAndStop() {
   1.335 +            pos_=NULL;
   1.336 +            value_=-1;  // no real value for str
   1.337 +            return TRUE;
   1.338 +        }
   1.339 +
   1.340 +        const UChar *branchNext(const UChar *pos, int32_t length, UErrorCode &errorCode);
   1.341 +
   1.342 +        const UChar *uchars_;
   1.343 +        const UChar *pos_;
   1.344 +        const UChar *initialPos_;
   1.345 +        int32_t remainingMatchLength_;
   1.346 +        int32_t initialRemainingMatchLength_;
   1.347 +        UBool skipValue_;  // Skip intermediate value which was already delivered.
   1.348 +
   1.349 +        UnicodeString str_;
   1.350 +        int32_t maxLength_;
   1.351 +        int32_t value_;
   1.352 +
   1.353 +        // The stack stores pairs of integers for backtracking to another
   1.354 +        // outbound edge of a branch node.
   1.355 +        // The first integer is an offset from uchars_.
   1.356 +        // The second integer has the str_.length() from before the node in bits 15..0,
   1.357 +        // and the remaining branch length in bits 31..16.
   1.358 +        // (We could store the remaining branch length minus 1 in bits 30..16 and not use the sign bit,
   1.359 +        // but the code looks more confusing that way.)
   1.360 +        UVector32 *stack_;
   1.361 +    };
   1.362 +
   1.363 +private:
   1.364 +    friend class UCharsTrieBuilder;
   1.365 +
   1.366 +    /**
   1.367 +     * Constructs a UCharsTrie reader instance.
   1.368 +     * Unlike the public constructor which just aliases an array,
   1.369 +     * this constructor adopts the builder's array.
   1.370 +     * This constructor is only called by the builder.
   1.371 +     */
   1.372 +    UCharsTrie(UChar *adoptUChars, const UChar *trieUChars)
   1.373 +            : ownedArray_(adoptUChars), uchars_(trieUChars),
   1.374 +              pos_(uchars_), remainingMatchLength_(-1) {}
   1.375 +
   1.376 +    // No assignment operator.
   1.377 +    UCharsTrie &operator=(const UCharsTrie &other);
   1.378 +
   1.379 +    inline void stop() {
   1.380 +        pos_=NULL;
   1.381 +    }
   1.382 +
   1.383 +    // Reads a compact 32-bit integer.
   1.384 +    // pos is already after the leadUnit, and the lead unit has bit 15 reset.
   1.385 +    static inline int32_t readValue(const UChar *pos, int32_t leadUnit) {
   1.386 +        int32_t value;
   1.387 +        if(leadUnit<kMinTwoUnitValueLead) {
   1.388 +            value=leadUnit;
   1.389 +        } else if(leadUnit<kThreeUnitValueLead) {
   1.390 +            value=((leadUnit-kMinTwoUnitValueLead)<<16)|*pos;
   1.391 +        } else {
   1.392 +            value=(pos[0]<<16)|pos[1];
   1.393 +        }
   1.394 +        return value;
   1.395 +    }
   1.396 +    static inline const UChar *skipValue(const UChar *pos, int32_t leadUnit) {
   1.397 +        if(leadUnit>=kMinTwoUnitValueLead) {
   1.398 +            if(leadUnit<kThreeUnitValueLead) {
   1.399 +                ++pos;
   1.400 +            } else {
   1.401 +                pos+=2;
   1.402 +            }
   1.403 +        }
   1.404 +        return pos;
   1.405 +    }
   1.406 +    static inline const UChar *skipValue(const UChar *pos) {
   1.407 +        int32_t leadUnit=*pos++;
   1.408 +        return skipValue(pos, leadUnit&0x7fff);
   1.409 +    }
   1.410 +
   1.411 +    static inline int32_t readNodeValue(const UChar *pos, int32_t leadUnit) {
   1.412 +        // U_ASSERT(kMinValueLead<=leadUnit && leadUnit<kValueIsFinal);
   1.413 +        int32_t value;
   1.414 +        if(leadUnit<kMinTwoUnitNodeValueLead) {
   1.415 +            value=(leadUnit>>6)-1;
   1.416 +        } else if(leadUnit<kThreeUnitNodeValueLead) {
   1.417 +            value=(((leadUnit&0x7fc0)-kMinTwoUnitNodeValueLead)<<10)|*pos;
   1.418 +        } else {
   1.419 +            value=(pos[0]<<16)|pos[1];
   1.420 +        }
   1.421 +        return value;
   1.422 +    }
   1.423 +    static inline const UChar *skipNodeValue(const UChar *pos, int32_t leadUnit) {
   1.424 +        // U_ASSERT(kMinValueLead<=leadUnit && leadUnit<kValueIsFinal);
   1.425 +        if(leadUnit>=kMinTwoUnitNodeValueLead) {
   1.426 +            if(leadUnit<kThreeUnitNodeValueLead) {
   1.427 +                ++pos;
   1.428 +            } else {
   1.429 +                pos+=2;
   1.430 +            }
   1.431 +        }
   1.432 +        return pos;
   1.433 +    }
   1.434 +
   1.435 +    static inline const UChar *jumpByDelta(const UChar *pos) {
   1.436 +        int32_t delta=*pos++;
   1.437 +        if(delta>=kMinTwoUnitDeltaLead) {
   1.438 +            if(delta==kThreeUnitDeltaLead) {
   1.439 +                delta=(pos[0]<<16)|pos[1];
   1.440 +                pos+=2;
   1.441 +            } else {
   1.442 +                delta=((delta-kMinTwoUnitDeltaLead)<<16)|*pos++;
   1.443 +            }
   1.444 +        }
   1.445 +        return pos+delta;
   1.446 +    }
   1.447 +
   1.448 +    static const UChar *skipDelta(const UChar *pos) {
   1.449 +        int32_t delta=*pos++;
   1.450 +        if(delta>=kMinTwoUnitDeltaLead) {
   1.451 +            if(delta==kThreeUnitDeltaLead) {
   1.452 +                pos+=2;
   1.453 +            } else {
   1.454 +                ++pos;
   1.455 +            }
   1.456 +        }
   1.457 +        return pos;
   1.458 +    }
   1.459 +
   1.460 +    static inline UStringTrieResult valueResult(int32_t node) {
   1.461 +        return (UStringTrieResult)(USTRINGTRIE_INTERMEDIATE_VALUE-(node>>15));
   1.462 +    }
   1.463 +
   1.464 +    // Handles a branch node for both next(uchar) and next(string).
   1.465 +    UStringTrieResult branchNext(const UChar *pos, int32_t length, int32_t uchar);
   1.466 +
   1.467 +    // Requires remainingLength_<0.
   1.468 +    UStringTrieResult nextImpl(const UChar *pos, int32_t uchar);
   1.469 +
   1.470 +    // Helper functions for hasUniqueValue().
   1.471 +    // Recursively finds a unique value (or whether there is not a unique one)
   1.472 +    // from a branch.
   1.473 +    static const UChar *findUniqueValueFromBranch(const UChar *pos, int32_t length,
   1.474 +                                                  UBool haveUniqueValue, int32_t &uniqueValue);
   1.475 +    // Recursively finds a unique value (or whether there is not a unique one)
   1.476 +    // starting from a position on a node lead unit.
   1.477 +    static UBool findUniqueValue(const UChar *pos, UBool haveUniqueValue, int32_t &uniqueValue);
   1.478 +
   1.479 +    // Helper functions for getNextUChars().
   1.480 +    // getNextUChars() when pos is on a branch node.
   1.481 +    static void getNextBranchUChars(const UChar *pos, int32_t length, Appendable &out);
   1.482 +
   1.483 +    // UCharsTrie data structure
   1.484 +    //
   1.485 +    // The trie consists of a series of UChar-serialized nodes for incremental
   1.486 +    // Unicode string/UChar sequence matching. (UChar=16-bit unsigned integer)
   1.487 +    // The root node is at the beginning of the trie data.
   1.488 +    //
   1.489 +    // Types of nodes are distinguished by their node lead unit ranges.
   1.490 +    // After each node, except a final-value node, another node follows to
   1.491 +    // encode match values or continue matching further units.
   1.492 +    //
   1.493 +    // Node types:
   1.494 +    //  - Final-value node: Stores a 32-bit integer in a compact, variable-length format.
   1.495 +    //    The value is for the string/UChar sequence so far.
   1.496 +    //  - Match node, optionally with an intermediate value in a different compact format.
   1.497 +    //    The value, if present, is for the string/UChar sequence so far.
   1.498 +    //
   1.499 +    //  Aside from the value, which uses the node lead unit's high bits:
   1.500 +    //
   1.501 +    //  - Linear-match node: Matches a number of units.
   1.502 +    //  - Branch node: Branches to other nodes according to the current input unit.
   1.503 +    //    The node unit is the length of the branch (number of units to select from)
   1.504 +    //    minus 1. It is followed by a sub-node:
   1.505 +    //    - If the length is at most kMaxBranchLinearSubNodeLength, then
   1.506 +    //      there are length-1 (key, value) pairs and then one more comparison unit.
   1.507 +    //      If one of the key units matches, then the value is either a final value for
   1.508 +    //      the string so far, or a "jump" delta to the next node.
   1.509 +    //      If the last unit matches, then matching continues with the next node.
   1.510 +    //      (Values have the same encoding as final-value nodes.)
   1.511 +    //    - If the length is greater than kMaxBranchLinearSubNodeLength, then
   1.512 +    //      there is one unit and one "jump" delta.
   1.513 +    //      If the input unit is less than the sub-node unit, then "jump" by delta to
   1.514 +    //      the next sub-node which will have a length of length/2.
   1.515 +    //      (The delta has its own compact encoding.)
   1.516 +    //      Otherwise, skip the "jump" delta to the next sub-node
   1.517 +    //      which will have a length of length-length/2.
   1.518 +
   1.519 +    // Match-node lead unit values, after masking off intermediate-value bits:
   1.520 +
   1.521 +    // 0000..002f: Branch node. If node!=0 then the length is node+1, otherwise
   1.522 +    // the length is one more than the next unit.
   1.523 +
   1.524 +    // For a branch sub-node with at most this many entries, we drop down
   1.525 +    // to a linear search.
   1.526 +    static const int32_t kMaxBranchLinearSubNodeLength=5;
   1.527 +
   1.528 +    // 0030..003f: Linear-match node, match 1..16 units and continue reading the next node.
   1.529 +    static const int32_t kMinLinearMatch=0x30;
   1.530 +    static const int32_t kMaxLinearMatchLength=0x10;
   1.531 +
   1.532 +    // Match-node lead unit bits 14..6 for the optional intermediate value.
   1.533 +    // If these bits are 0, then there is no intermediate value.
   1.534 +    // Otherwise, see the *NodeValue* constants below.
   1.535 +    static const int32_t kMinValueLead=kMinLinearMatch+kMaxLinearMatchLength;  // 0x0040
   1.536 +    static const int32_t kNodeTypeMask=kMinValueLead-1;  // 0x003f
   1.537 +
   1.538 +    // A final-value node has bit 15 set.
   1.539 +    static const int32_t kValueIsFinal=0x8000;
   1.540 +
   1.541 +    // Compact value: After testing and masking off bit 15, use the following thresholds.
   1.542 +    static const int32_t kMaxOneUnitValue=0x3fff;
   1.543 +
   1.544 +    static const int32_t kMinTwoUnitValueLead=kMaxOneUnitValue+1;  // 0x4000
   1.545 +    static const int32_t kThreeUnitValueLead=0x7fff;
   1.546 +
   1.547 +    static const int32_t kMaxTwoUnitValue=((kThreeUnitValueLead-kMinTwoUnitValueLead)<<16)-1;  // 0x3ffeffff
   1.548 +
   1.549 +    // Compact intermediate-value integer, lead unit shared with a branch or linear-match node.
   1.550 +    static const int32_t kMaxOneUnitNodeValue=0xff;
   1.551 +    static const int32_t kMinTwoUnitNodeValueLead=kMinValueLead+((kMaxOneUnitNodeValue+1)<<6);  // 0x4040
   1.552 +    static const int32_t kThreeUnitNodeValueLead=0x7fc0;
   1.553 +
   1.554 +    static const int32_t kMaxTwoUnitNodeValue=
   1.555 +        ((kThreeUnitNodeValueLead-kMinTwoUnitNodeValueLead)<<10)-1;  // 0xfdffff
   1.556 +
   1.557 +    // Compact delta integers.
   1.558 +    static const int32_t kMaxOneUnitDelta=0xfbff;
   1.559 +    static const int32_t kMinTwoUnitDeltaLead=kMaxOneUnitDelta+1;  // 0xfc00
   1.560 +    static const int32_t kThreeUnitDeltaLead=0xffff;
   1.561 +
   1.562 +    static const int32_t kMaxTwoUnitDelta=((kThreeUnitDeltaLead-kMinTwoUnitDeltaLead)<<16)-1;  // 0x03feffff
   1.563 +
   1.564 +    UChar *ownedArray_;
   1.565 +
   1.566 +    // Fixed value referencing the UCharsTrie words.
   1.567 +    const UChar *uchars_;
   1.568 +
   1.569 +    // Iterator variables.
   1.570 +
   1.571 +    // Pointer to next trie unit to read. NULL if no more matches.
   1.572 +    const UChar *pos_;
   1.573 +    // Remaining length of a linear-match node, minus 1. Negative if not in such a node.
   1.574 +    int32_t remainingMatchLength_;
   1.575 +};
   1.576 +
   1.577 +U_NAMESPACE_END
   1.578 +
   1.579 +#endif  // __UCHARSTRIE_H__

mercurial