blob: aaa5702ad18594fa6587fe04d73e4b23bcf367a4 [file] [log] [blame]
/*
*****************************************************************************************
* *
* 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