| /* |
| ***************************************************************************************** |
| * * |
| * COPYRIGHT: * |
| * (C) Copyright Taligent, Inc., 1997 * |
| * (C) Copyright International Business Machines Corporation, 1997-1998 * |
| * Licensed Material - Program-Property of IBM - All Rights Reserved. * |
| * US Government Users Restricted Rights - Use, duplication, or disclosure * |
| * restricted by GSA ADP Schedule Contract with IBM Corp. * |
| * * |
| ***************************************************************************************** |
| * |
| * File SIMTXBD.CPP |
| * |
| * Modification History: |
| * |
| * Date Name Description |
| * 02/18/97 aliu Converted from OpenClass. Converted offset_type |
| * to UTextOffset. |
| * 05/06/97 aliu Modified previousSafePosition to check for 0 offset. Not |
| * sure why this wasn't there before. (?) |
| * 08/11/98 helena Sync-up JDK1.2. |
| ***************************************************************************************** |
| */ |
| |
| // ***************************************************************************** |
| // This file was generated from the java source file SimpleTextBoundary.java |
| // ***************************************************************************** |
| |
| #include "simtxbd.h" |
| #include "wdbktbl.h" |
| #include "unicdcm.h" |
| #include "schriter.h" |
| #ifdef _DEBUG |
| #include "unistrm.h" |
| #endif |
| |
| // ***************************************************************************** |
| // class SimpleTextBoundary |
| // This class is an implementation of the BreakIterator |
| // protocol. SimpleTextBoundary uses a state machine to compute breaks. |
| // There are currently several subclasses of SimpleTextBoundary that |
| // compute breaks for sentences, words, lines, and characters. |
| // ***************************************************************************** |
| |
| char SimpleTextBoundary::fgClassID = 0; // Value is irrelevant |
| const UChar SimpleTextBoundary::kEND_OF_STRING = 0xFFFF; |
| |
| // Creates a simple text boundary instance with the text boundary data. |
| SimpleTextBoundary::SimpleTextBoundary(const TextBoundaryData* data) |
| : fData(data), fText(0), fPos(0) |
| { |
| fForward = fData->forward(); |
| fBackward = fData->backward(); |
| fMap = fData->map(); |
| } |
| |
| // ------------------------------------- |
| |
| SimpleTextBoundary::~SimpleTextBoundary() |
| { |
| } |
| |
| // ------------------------------------- |
| // copy constructor |
| |
| SimpleTextBoundary::SimpleTextBoundary(const SimpleTextBoundary& rhs) |
| : fData(rhs.fData), fText(rhs.fText), fPos(rhs.fPos) |
| { |
| fForward = fData->forward(); |
| fBackward = fData->backward(); |
| fMap = fData->map(); |
| } |
| |
| // ------------------------------------- |
| |
| BreakIterator* |
| SimpleTextBoundary::clone() const |
| { |
| return new SimpleTextBoundary(*this); |
| } |
| |
| // ------------------------------------- |
| |
| bool_t |
| SimpleTextBoundary::operator==(const BreakIterator& rhs) const |
| { |
| const SimpleTextBoundary* other = (const SimpleTextBoundary*)&rhs; |
| |
| return (this == &rhs) || |
| (rhs.getDynamicClassID() == getStaticClassID() && |
| // Pointer equality on fData sufficices since these are singletons |
| fData == other->fData && |
| fPos == other->fPos && |
| ((fText == other->fText) // This handles the case when both ptrs are 0 |
| || (fText != 0 && other->fText != 0 && *fText == *other->fText))); |
| } |
| |
| // ------------------------------------- |
| // Gets the target text. |
| |
| CharacterIterator* |
| SimpleTextBoundary::createText() const |
| { |
| return fText->clone(); |
| } |
| |
| // ------------------------------------- |
| // Sets the target text. |
| |
| void |
| SimpleTextBoundary::setText(const UnicodeString* text) |
| { |
| delete fText; |
| fText = 0; |
| fText = new StringCharacterIterator(*text); |
| fPos = 0; |
| } |
| |
| // ------------------------------------- |
| // Sets the target text. |
| |
| void |
| SimpleTextBoundary::adoptText(CharacterIterator* text) |
| { |
| delete fText; |
| fText = 0; |
| fText = text; |
| fPos = 0; |
| } |
| |
| // ------------------------------------- |
| // Gets the first text offset of the target text. |
| |
| UTextOffset |
| SimpleTextBoundary::first() |
| { |
| fPos = fText->startIndex(); |
| return fPos; |
| } |
| |
| // ------------------------------------- |
| // Gets the last text offset of the target text. |
| |
| UTextOffset |
| SimpleTextBoundary::last() |
| { |
| fPos = (fText == 0) ? 0 : fText->endIndex(); |
| return fPos; |
| } |
| |
| // ------------------------------------- |
| // Gets the next offset of the target text after the cursor increment. |
| |
| UTextOffset |
| SimpleTextBoundary::next(int32_t increment) |
| { |
| UTextOffset result = current(); |
| |
| // If increment is negative, step backwards until the beginning |
| // of string is reached. |
| if (increment < 0) { |
| for (int32_t i = increment; (i < 0) && (result != DONE); ++i) { |
| result = previous(); |
| } |
| } else { |
| for (int32_t i = increment; (i > 0) && (result != DONE); --i) { |
| result = next(); |
| } |
| } |
| |
| return result; |
| } |
| |
| // ------------------------------------- |
| // Gets the previous offset of the target at the cursor. |
| |
| UTextOffset |
| SimpleTextBoundary::previous() |
| { |
| if (fPos > fText->startIndex()) { // != 0, DON'T need to check for != DONE as well |
| UTextOffset startBoundary = fPos; |
| // finds the previous safe position to backtrack to |
| fPos = previousSafePosition(fPos - 1); |
| UTextOffset prevPos = fPos; |
| UTextOffset nextPos = next(); |
| // if the next position does not point to the start of a text boundary, |
| // finds the next start point. |
| while (nextPos < startBoundary && nextPos != DONE) { |
| prevPos = nextPos; |
| nextPos = next(); |
| } |
| fPos = prevPos; |
| return fPos; |
| } |
| // already at the beginning of the target text |
| else { |
| return DONE; |
| } |
| } |
| |
| // ------------------------------------- |
| // Gets the next offset of the target at the cursor. |
| |
| UTextOffset |
| SimpleTextBoundary::next() |
| { |
| UTextOffset result = fPos; |
| |
| // Finds the next position of the end of string is not reached. |
| if (fPos < ((fText == 0) ? 0 : fText->endIndex())) { |
| fPos = nextPosition(fPos); |
| result = fPos; |
| } |
| else { |
| result = DONE; |
| } |
| |
| return result; |
| } |
| |
| // ------------------------------------- |
| // Finds the offset of the next text boundary after the specified offset. |
| |
| UTextOffset |
| SimpleTextBoundary::following(UTextOffset offset) |
| { |
| if (offset >= ((fText == 0) ? 0 : fText->endIndex())) |
| { |
| fPos = (fText == 0) ? 0 : fText->endIndex(); |
| return DONE; |
| } |
| else if (offset < fText->startIndex()) |
| { |
| fPos = 0; |
| return 0; |
| } |
| |
| fPos = previousSafePosition(offset); |
| UTextOffset result; |
| do { |
| result = next(); |
| } |
| while (result <= offset && result != DONE); |
| |
| return result; |
| } |
| |
| // ------------------------------------- |
| // Finds the offset of the next text boundary before the specified offset. |
| |
| UTextOffset |
| SimpleTextBoundary::preceding(UTextOffset offset) |
| { |
| if (offset <= fText->startIndex()) |
| { |
| fPos = 0; |
| return DONE; |
| } |
| else if (offset > ((fText == 0) ? 0 : fText->endIndex())) |
| { |
| fPos = (fText == 0) ? 0 : fText->endIndex(); |
| return fPos; |
| } |
| |
| fPos = previousSafePosition(offset); |
| UTextOffset p = fPos; |
| UTextOffset last; |
| do { |
| last = p; |
| p = next(); |
| } |
| while (p < offset && p != DONE); |
| |
| fPos = last; |
| return last; |
| } |
| |
| bool_t |
| SimpleTextBoundary::isBoundary(UTextOffset offset) |
| { |
| UTextOffset begin = fText->startIndex(); |
| if (offset < begin || offset >= ((fText == 0) ? 0 : fText->endIndex())) { |
| return FALSE; |
| } if (offset == begin) { |
| return TRUE; |
| } else { |
| return following(offset - 1) == offset; |
| } |
| } |
| |
| |
| // ------------------------------------- |
| // Returns the current text offset. |
| |
| UTextOffset |
| SimpleTextBoundary::current() const |
| { |
| return fPos; |
| } |
| |
| // ------------------------------------- |
| // Finds the previous safe position; stepping backwards in the target text |
| // until the end state is reached. |
| |
| UTextOffset |
| SimpleTextBoundary::previousSafePosition(UTextOffset offset) |
| { |
| UTextOffset result = fText->startIndex(); |
| |
| // Stepping the target text backwards to find the previous safe spot. |
| TextBoundaryData::Node state = fBackward->initialState(); |
| UChar c; |
| |
| if (offset == result) |
| ++offset; |
| |
| for (c = fText->setIndex(offset - 1); |
| c != CharacterIterator::DONE && !fBackward->isEndState(state); |
| c = fText->previous()) { |
| |
| state = fBackward->get(state, fMap->mappedChar(c)); |
| if (fBackward->isMarkState(state)) { |
| result = fText->getIndex(); |
| } |
| } |
| return result; |
| } |
| |
| // ------------------------------------- |
| // Finds the next position; stepping forwards in the target text |
| // until the end state is reached. |
| |
| UTextOffset |
| SimpleTextBoundary::nextPosition(UTextOffset offset) |
| { |
| UTextOffset endIndex = (fText == 0) ? 0 : fText->endIndex(); |
| |
| TextBoundaryData::Node state = fForward->initialState(); |
| UTextOffset p = offset; |
| UChar c; |
| |
| for (c = fText->setIndex(offset); |
| c != CharacterIterator::DONE && !fForward->isEndState(state); |
| c = fText->next()) { |
| state = fForward->get(state, fMap->mappedChar(c)); |
| if (fForward->isMarkState(state)) { |
| endIndex = fText->getIndex(); |
| } |
| } |
| if (fForward->isEndState(state)) |
| return endIndex; |
| else { |
| state = fForward->get(state, fMap->mappedChar(kEND_OF_STRING)); |
| if (fForward->isMarkState(state)) |
| return ((fText == 0) ? 0 : fText->endIndex()); |
| else |
| return endIndex; |
| } |
| } |
| |
| //eof |