| Index: source/i18n/brktrans.cpp
|
| diff --git a/source/i18n/brktrans.cpp b/source/i18n/brktrans.cpp
|
| index 5207266783960f1925f88eaccf5a420908165604..dafac399f855e390b550ddcf52593beeb86116d3 100644
|
| --- a/source/i18n/brktrans.cpp
|
| +++ b/source/i18n/brktrans.cpp
|
| @@ -1,6 +1,6 @@
|
| /*
|
| **********************************************************************
|
| -* Copyright (C) 2008-2010, International Business Machines
|
| +* Copyright (C) 2008-2015, International Business Machines
|
| * Corporation and others. All Rights Reserved.
|
| **********************************************************************
|
| * Date Name Description
|
| @@ -12,13 +12,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 +38,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 +47,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 +71,27 @@ void BreakTransliterator::handleTransliterate(Replaceable& text, UTransPosition&
|
| UBool isIncremental ) const {
|
|
|
| UErrorCode status = U_ZERO_ERROR;
|
| + LocalPointer<BreakIterator> bi;
|
| + LocalPointer<UVector32> boundaries;
|
| +
|
| + {
|
| + Mutex m;
|
| + BreakTransliterator *nonConstThis = const_cast<BreakTransliterator *>(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);
|
| @@ -132,6 +138,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<BreakTransliterator *>(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.)
|
| }
|
| @@ -151,21 +169,6 @@ void BreakTransliterator::setInsertion(const UnicodeString &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.
|
| // In practice, the only real Replaceable type that we
|
|
|