X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/46f4442e9a5a4f3b98b7c1083586332f6a8a99a4..f3c0d7a59d99c2a94c6b8822291f0e42be3773c9:/icuSources/i18n/brktrans.cpp diff --git a/icuSources/i18n/brktrans.cpp b/icuSources/i18n/brktrans.cpp index ca55ace7..ab5a8038 100644 --- a/icuSources/i18n/brktrans.cpp +++ b/icuSources/i18n/brktrans.cpp @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** -* Copyright (C) 2008, International Business Machines +* Copyright (C) 2008-2015, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Date Name Description @@ -12,13 +14,15 @@ #if !UCONFIG_NO_TRANSLITERATION && !UCONFIG_NO_BREAK_ITERATION -#include "unicode/unifilt.h" +#include "unicode/brkiter.h" +#include "unicode/localpointer.h" #include "unicode/uchar.h" +#include "unicode/unifilt.h" #include "unicode/uniset.h" -#include "unicode/brkiter.h" + #include "brktrans.h" -#include "unicode/uchar.h" #include "cmemory.h" +#include "mutex.h" #include "uprops.h" #include "uinvchar.h" #include "util.h" @@ -36,11 +40,8 @@ static const UChar SPACE = 32; // ' ' * '}'. */ BreakTransliterator::BreakTransliterator(UnicodeFilter* adoptedFilter) : - Transliterator(UNICODE_STRING("Any-BreakInternal", 17), adoptedFilter), - fInsertion(SPACE) { - bi = NULL; - UErrorCode status = U_ZERO_ERROR; - boundaries = new UVector32(status); + Transliterator(UNICODE_STRING("Any-BreakInternal", 17), adoptedFilter), + cachedBI(NULL), cachedBoundaries(NULL), fInsertion(SPACE) { } @@ -48,25 +49,14 @@ BreakTransliterator::BreakTransliterator(UnicodeFilter* adoptedFilter) : * Destructor. */ BreakTransliterator::~BreakTransliterator() { - delete bi; - bi = NULL; - delete boundaries; - boundaries = NULL; } /** * Copy constructor. */ BreakTransliterator::BreakTransliterator(const BreakTransliterator& o) : - Transliterator(o) { - bi = NULL; - if (o.bi != NULL) { - bi = o.bi->clone(); - } - fInsertion = o.fInsertion; - UErrorCode status = U_ZERO_ERROR; - boundaries = new UVector32(status); - } + Transliterator(o), cachedBI(NULL), cachedBoundaries(NULL), fInsertion(o.fInsertion) { +} /** @@ -83,9 +73,27 @@ void BreakTransliterator::handleTransliterate(Replaceable& text, UTransPosition& UBool isIncremental ) const { UErrorCode status = U_ZERO_ERROR; + LocalPointer bi; + LocalPointer boundaries; + + { + Mutex m; + BreakTransliterator *nonConstThis = const_cast(this); + boundaries.moveFrom(nonConstThis->cachedBoundaries); + bi.moveFrom(nonConstThis->cachedBI); + } + if (bi.isNull()) { + bi.adoptInstead(BreakIterator::createWordInstance(Locale::getEnglish(), status)); + } + if (boundaries.isNull()) { + boundaries.adoptInstead(new UVector32(status)); + } + + if (bi.isNull() || boundaries.isNull() || U_FAILURE(status)) { + return; + } + boundaries->removeAllElements(); - BreakTransliterator *nonConstThis = (BreakTransliterator *)this; - nonConstThis->getBreakIterator(); // Lazy-create it if necessary UnicodeString sText = replaceableAsString(text); bi->setText(sText); bi->preceding(offsets.start); @@ -109,7 +117,7 @@ void BreakTransliterator::handleTransliterate(Replaceable& text, UTransPosition& if ((U_MASK(type) & (U_GC_L_MASK | U_GC_M_MASK)) == 0) continue; boundaries->addElement(boundary, status); - //System.out.println(boundary); + // printf("Boundary at %d\n", boundary); } int delta = 0; @@ -132,6 +140,18 @@ void BreakTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets.limit += delta; offsets.start = isIncremental ? lastBoundary + delta : offsets.limit; + // Return break iterator & boundaries vector to the cache. + { + Mutex m; + BreakTransliterator *nonConstThis = const_cast(this); + if (nonConstThis->cachedBI.isNull()) { + nonConstThis->cachedBI.moveFrom(bi); + } + if (nonConstThis->cachedBoundaries.isNull()) { + nonConstThis->cachedBoundaries.moveFrom(boundaries); + } + } + // TODO: do something with U_FAILURE(status); // (need to look at transliterators overall, not just here.) } @@ -146,25 +166,10 @@ const UnicodeString &BreakTransliterator::getInsertion() const { // // setInsertion() // -void BreakTransliterator::setInsertsion(const UnicodeString &insertion) { +void BreakTransliterator::setInsertion(const UnicodeString &insertion) { this->fInsertion = insertion; } -// -// getBreakIterator Lazily create the break iterator if it does -// not already exist. Copied from Java, probably -// better to just create it in the constructor. -// -BreakIterator *BreakTransliterator::getBreakIterator() { - UErrorCode status = U_ZERO_ERROR; - if (bi == NULL) { - // Note: Thai breaking behavior is universal, it is not - // tied to the Thai locale. - bi = BreakIterator::createWordInstance(Locale::getEnglish(), status); - } - return bi; -} - // // replaceableAsString Hack to let break iterators work // on the replaceable text from transliterators. @@ -173,11 +178,13 @@ BreakIterator *BreakTransliterator::getBreakIterator() { // will normally be efficient. // UnicodeString BreakTransliterator::replaceableAsString(Replaceable &r) { - if (r.getDynamicClassID() == UnicodeString::getStaticClassID()) { - return (UnicodeString &) r; - } UnicodeString s; - r.extractBetween(0, r.length(), s); + UnicodeString *rs = dynamic_cast(&r); + if (rs != NULL) { + s = *rs; + } else { + r.extractBetween(0, r.length(), s); + } return s; }