Logo Search packages:      
Sourcecode: icu version File versions  Download package

void RuleBasedTransliterator::handleTransliterate ( Replaceable text,
UTransPosition index,
UBool  isIncremental 
) const [protected, virtual]

Implements Transliterator#handleTransliterate.

For internal use only.

Use transliterator factory methods instead since this class will be removed in that release.

Implements Transliterator#handleTransliterate.

Implements Transliterator.

Definition at line 201 of file rbt.cpp.

References FALSE, fData, isDataOwned, UTransPosition::limit, TransliterationRuleData::ruleSet, UTransPosition::start, TransliterationRuleSet::transliterate(), and TRUE.

                                                                        {
    /* We keep contextStart and contextLimit fixed the entire time,
     * relative to the text -- contextLimit may move numerically if
     * text is inserted or removed.  The start offset moves toward
     * limit, with replacements happening under it.
     *
     * Example: rules 1. ab>x|y
     *                2. yc>z
     *
     * |eabcd   begin - no match, advance start
     * e|abcd   match rule 1 - change text & adjust start
     * ex|ycd   match rule 2 - change text & adjust start
     * exz|d    no match, advance start
     * exzd|    done
     */

    /* A rule like
     *   a>b|a
     * creates an infinite loop. To prevent that, we put an arbitrary
     * limit on the number of iterations that we take, one that is
     * high enough that any reasonable rules are ok, but low enough to
     * prevent a server from hanging.  The limit is 16 times the
     * number of characters n, unless n is so large that 16n exceeds a
     * uint32_t.
     */
    uint32_t loopCount = 0;
    uint32_t loopLimit = index.limit - index.start;
    if (loopLimit >= 0x10000000) {
        loopLimit = 0xFFFFFFFF;
    } else {
        loopLimit <<= 4;
    }

    // Transliterator locking.  Rule-based Transliterators are not thread safe; concurrent
    //   operations must be prevented.  
    // A Complication: compound transliterators can result in recursive entries to this
    //   function, sometimes with different "This" objects, always with the same text. 
    //   Double-locking must be prevented in these cases.
    //   

    // If the transliteration data is exclusively owned by this transliterator object,
    //   we don't need to do any locking.  No sharing between transliterators is possible,
    //   so no concurrent access from multiple threads is possible.
    UBool    lockedMutexAtThisLevel = FALSE;
    if (isDataOwned == FALSE) {
        // Test whether this request is operating on the same text string as some
        //   some other transliteration that is still in progress and holding the 
        //   transliteration mutex.  If so, do not lock the transliteration
        //    mutex again.
        UBool needToLock;
        UMTX_CHECK(NULL, (&text != gLockedText), needToLock);
        if (needToLock) {
            umtx_lock(&transliteratorDataMutex);
            gLockedText = &text;
            lockedMutexAtThisLevel = TRUE;
        }
    }
    
    // Check to make sure we don't dereference a null pointer.
    if (fData != NULL) {
          while (index.start < index.limit &&
                 loopCount <= loopLimit &&
                 fData->ruleSet.transliterate(text, index, isIncremental)) {
              ++loopCount;
          }
    }
    if (lockedMutexAtThisLevel) {
        gLockedText = NULL;
        umtx_unlock(&transliteratorDataMutex);
    }
}


Generated by  Doxygen 1.6.0   Back to index