X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..6de34a005df0e4a02d88750703b950237b77d9c8:/icuSources/common/dbbi.cpp diff --git a/icuSources/common/dbbi.cpp b/icuSources/common/dbbi.cpp index def45650..2f83f6c3 100644 --- a/icuSources/common/dbbi.cpp +++ b/icuSources/common/dbbi.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 1999-2001 IBM Corp. All rights reserved. +* Copyright (C) 1999-2004 IBM Corp. All rights reserved. ********************************************************************** * Date Name Description * 12/1/99 rgillam Complete port from Java. @@ -17,17 +17,18 @@ #include "dbbi_tbl.h" #include "uvector.h" #include "cmemory.h" +#include "uassert.h" U_NAMESPACE_BEGIN -const char DictionaryBasedBreakIterator::fgClassID = 0; +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DictionaryBasedBreakIterator) -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // // constructors // -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ DictionaryBasedBreakIterator::DictionaryBasedBreakIterator() : RuleBasedBreakIterator() { @@ -43,17 +44,18 @@ DictionaryBasedBreakIterator::DictionaryBasedBreakIterator(UDataMemory* rbbiData init(); if (U_FAILURE(status)) {return;}; fTables = new DictionaryBasedBreakIteratorTables(dictionaryFilename, status); + if (U_FAILURE(status)) { + if (fTables != NULL) { + fTables->removeReference(); + fTables = NULL; + } + return; + } /* test for NULL */ if(fTables == 0) { status = U_MEMORY_ALLOCATION_ERROR; return; } - - if (U_FAILURE(status)) { - fTables->removeReference(); - fTables = NULL; - return; - } } @@ -70,11 +72,11 @@ RuleBasedBreakIterator(other) -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // // Destructor // -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ DictionaryBasedBreakIterator::~DictionaryBasedBreakIterator() { uprv_free(cachedBreakPositions); @@ -82,12 +84,12 @@ DictionaryBasedBreakIterator::~DictionaryBasedBreakIterator() if (fTables != NULL) {fTables->removeReference();}; } -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // // Assignment operator. Sets this iterator to have the same behavior, // and iterate over the same text, as the one passed in. // -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ DictionaryBasedBreakIterator& DictionaryBasedBreakIterator::operator=(const DictionaryBasedBreakIterator& that) { if (this == &that) { @@ -103,12 +105,12 @@ DictionaryBasedBreakIterator::operator=(const DictionaryBasedBreakIterator& that return *this; } -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // // Clone() Returns a newly-constructed RuleBasedBreakIterator with the same // behavior, and iterating over the same text, as this one. // -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ BreakIterator* DictionaryBasedBreakIterator::clone() const { return new DictionaryBasedBreakIterator(*this); @@ -141,7 +143,14 @@ DictionaryBasedBreakIterator::previous() reset(); int32_t result = RuleBasedBreakIterator::previous(); if (cachedBreakPositions != NULL) { - positionInCache = numCachedBreakPositions - 2; + for (positionInCache=0; + cachedBreakPositions[positionInCache] != result; + positionInCache++); + U_ASSERT(positionInCache < numCachedBreakPositions); + if (positionInCache >= numCachedBreakPositions) { + // Something has gone wrong. Dump the cache. + reset(); + } } return result; } @@ -256,8 +265,13 @@ DictionaryBasedBreakIterator::handleNext() // for the new range if (fDictionaryCharCount > 1 && result - startPos > 1) { divideUpDictionaryRange(startPos, result, status); + U_ASSERT(U_SUCCESS(status)); if (U_FAILURE(status)) { - return -9999; // SHOULD NEVER GET HERE! + // Something went badly wrong, an internal error. + // We have no way from here to report it to caller. + // Treat as if this is if the dictionary did not apply to range. + reset(); + return result; } } @@ -292,11 +306,11 @@ DictionaryBasedBreakIterator::reset() -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // // init() Common initialization routine, for use by constructors, etc. // -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ void DictionaryBasedBreakIterator::init() { cachedBreakPositions = NULL; fTables = NULL; @@ -306,11 +320,11 @@ void DictionaryBasedBreakIterator::init() { } -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // // BufferClone // -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ BreakIterator * DictionaryBasedBreakIterator::createBufferClone(void *stackBuffer, int32_t &bufferSize, UErrorCode &status) @@ -396,6 +410,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t c = fText->next(); } + if (U_FAILURE(status)) { + return; // UStack below overwrites the status error codes + } // initialize. We maintain two stacks: currentBreakPositions contains // the list of break positions that will be returned if we successfully @@ -412,7 +429,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t // further, this saves us from having to follow each possible path // through the text all the way to the error (hopefully avoiding many // future recursive calls as well). - UStack currentBreakPositions(status); + // there can be only one kind of error in UStack and UVector, so we'll + // just let the error fall through + UStack currentBreakPositions(status); UStack possibleBreakPositions(status); UVector wrongBreakPositions(status); @@ -445,6 +464,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t // the possible-break-positions stack if (fTables->fDictionary->at(state, (int32_t)0) == -1) { possibleBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } } // look up the new state to transition to in the dictionary @@ -456,6 +478,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t // of the loop. if (state == -1) { currentBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } break; } @@ -501,6 +526,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t currentBreakPositions.removeAllElements(); for (int32_t i = 0; i < bestBreakPositions.size(); i++) { currentBreakPositions.push(bestBreakPositions.elementAti(i), status); + if (U_FAILURE(status)) { + return; + } } bestBreakPositions.removeAllElements(); if (farthestEndPoint < endPos) { @@ -515,9 +543,15 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t || currentBreakPositions.peeki() != fText->getIndex()) && fText->getIndex() != startPos) { currentBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } } fText->next(); currentBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } } } @@ -561,6 +595,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t currentBreakPositions.popi(); } currentBreakPositions.push(endPos, status); + if (U_FAILURE(status)) { + return; + } // create a regular array to hold the break positions and copy // the break positions from the stack to the array (in addition,