home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / i18n / simtxbd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-16  |  9.7 KB  |  363 lines

  1. /*
  2. *****************************************************************************************
  3. *                                                                                       *
  4. * COPYRIGHT:                                                                            *
  5. *   (C) Copyright Taligent, Inc.,  1997                                                 *
  6. *   (C) Copyright International Business Machines Corporation,  1997-1998                    *
  7. *   Licensed Material - Program-Property of IBM - All Rights Reserved.                  *
  8. *   US Government Users Restricted Rights - Use, duplication, or disclosure             *
  9. *   restricted by GSA ADP Schedule Contract with IBM Corp.                              *
  10. *                                                                                       *
  11. *****************************************************************************************
  12. *
  13. * File SIMTXBD.CPP
  14. *
  15. * Modification History:
  16. *
  17. *   Date        Name        Description
  18. *   02/18/97    aliu        Converted from OpenClass.  Converted offset_type
  19. *                           to UTextOffset.
  20. *   05/06/97    aliu        Modified previousSafePosition to check for 0 offset.  Not
  21. *                           sure why this wasn't there before. (?)
  22. *   08/11/98    helena      Sync-up JDK1.2.
  23. *****************************************************************************************
  24. */
  25.  
  26. // *****************************************************************************
  27. // This file was generated from the java source file SimpleTextBoundary.java
  28. // *****************************************************************************
  29.  
  30. #include "simtxbd.h"
  31. #include "wdbktbl.h"
  32. #include "unicdcm.h"
  33. #include "schriter.h"
  34. #ifdef _DEBUG
  35. #include "unistrm.h"
  36. #endif
  37.  
  38. // *****************************************************************************
  39. // class SimpleTextBoundary
  40. // This class is an implementation of the BreakIterator
  41. // protocol.  SimpleTextBoundary uses a state machine to compute breaks.
  42. // There are currently several subclasses of SimpleTextBoundary that
  43. // compute breaks for sentences, words, lines, and characters.
  44. // *****************************************************************************
  45.  
  46. char SimpleTextBoundary::fgClassID = 0; // Value is irrelevant
  47. const UChar SimpleTextBoundary::kEND_OF_STRING = 0xFFFF;
  48.  
  49. // Creates a simple text boundary instance with the text boundary data.
  50. SimpleTextBoundary::SimpleTextBoundary(const TextBoundaryData* data)
  51.   : fData(data), fText(0), fPos(0)
  52. {
  53.     fForward = fData->forward();
  54.     fBackward = fData->backward();
  55.     fMap = fData->map();
  56. }
  57.  
  58. // -------------------------------------
  59.  
  60. SimpleTextBoundary::~SimpleTextBoundary()
  61. {
  62. }
  63.  
  64. // -------------------------------------
  65. // copy constructor
  66.  
  67. SimpleTextBoundary::SimpleTextBoundary(const SimpleTextBoundary& rhs)
  68.   : fData(rhs.fData), fText(rhs.fText), fPos(rhs.fPos)
  69. {
  70.     fForward = fData->forward();
  71.     fBackward = fData->backward();
  72.     fMap = fData->map();
  73. }
  74.  
  75. // -------------------------------------
  76.  
  77. BreakIterator*
  78. SimpleTextBoundary::clone() const
  79. {
  80.   return new SimpleTextBoundary(*this);
  81. }
  82.  
  83. // -------------------------------------
  84.  
  85. bool_t
  86. SimpleTextBoundary::operator==(const BreakIterator& rhs) const
  87. {
  88.     const SimpleTextBoundary* other = (const SimpleTextBoundary*)&rhs;
  89.  
  90.     return (this == &rhs) ||
  91.         (rhs.getDynamicClassID() == getStaticClassID() &&
  92.         // Pointer equality on fData sufficices since these are singletons
  93.         fData == other->fData &&
  94.         fPos == other->fPos &&
  95.         ((fText == other->fText) // This handles the case when both ptrs are 0
  96.          || (fText != 0 && other->fText != 0 && *fText == *other->fText)));
  97. }
  98.  
  99. // -------------------------------------
  100. // Gets the target text.
  101.  
  102. CharacterIterator*
  103. SimpleTextBoundary::createText() const
  104. {
  105.     return fText->clone();
  106. }
  107.  
  108. // -------------------------------------
  109. // Sets the target text.
  110.  
  111. void
  112. SimpleTextBoundary::setText(const UnicodeString* text)
  113. {
  114.     delete fText;
  115.     fText = 0;
  116.     fText = new StringCharacterIterator(*text);
  117.     fPos = 0;
  118. }
  119.  
  120. // -------------------------------------
  121. // Sets the target text.
  122.  
  123. void
  124. SimpleTextBoundary::adoptText(CharacterIterator* text)
  125. {
  126.     delete fText;
  127.     fText = 0;
  128.     fText = text;
  129.     fPos = 0;
  130. }
  131.  
  132. // -------------------------------------
  133. // Gets the first text offset of the target text.
  134.  
  135. UTextOffset
  136. SimpleTextBoundary::first()
  137. {
  138.     fPos = fText->startIndex();
  139.     return fPos;
  140. }
  141.  
  142. // -------------------------------------
  143. // Gets the last text offset of the target text.
  144.  
  145. UTextOffset
  146. SimpleTextBoundary::last()
  147. {
  148.     fPos = (fText == 0) ? 0 : fText->endIndex();
  149.     return fPos;
  150. }
  151.  
  152. // -------------------------------------
  153. // Gets the next offset of the target text after the cursor increment.
  154.  
  155. UTextOffset
  156. SimpleTextBoundary::next(int32_t increment)
  157. {
  158.     UTextOffset result = current();
  159.  
  160.     // If increment is negative, step backwards until the beginning
  161.     // of string is reached.
  162.     if (increment < 0) {
  163.         for (int32_t i = increment; (i < 0) && (result != DONE); ++i) {
  164.             result = previous();
  165.         }
  166.     } else {
  167.         for (int32_t i = increment; (i > 0) && (result != DONE); --i) {
  168.             result = next();
  169.         }
  170.     }
  171.  
  172.     return result;
  173. }
  174.  
  175. // -------------------------------------
  176. // Gets the previous offset of the target at the cursor.
  177.  
  178. UTextOffset
  179. SimpleTextBoundary::previous()
  180. {
  181.   if (fPos > fText->startIndex()) { // != 0, DON'T need to check for != DONE as well
  182.     UTextOffset startBoundary = fPos;
  183.     // finds the previous safe position to backtrack to
  184.     fPos = previousSafePosition(fPos - 1);
  185.     UTextOffset prevPos = fPos;
  186.     UTextOffset nextPos = next();
  187.     // if the next position does not point to the start of a text boundary,
  188.     // finds the next start point.
  189.     while (nextPos < startBoundary && nextPos != DONE) {
  190.         prevPos = nextPos;
  191.         nextPos = next();
  192.     }
  193.     fPos = prevPos;
  194.     return fPos;
  195.   }
  196.   // already at the beginning of the target text
  197.   else {
  198.     return DONE;
  199.   }
  200. }
  201.  
  202. // -------------------------------------
  203. // Gets the next offset of the target at the cursor.
  204.  
  205. UTextOffset
  206. SimpleTextBoundary::next()
  207. {
  208.     UTextOffset result = fPos;
  209.  
  210.     // Finds the next position of the end of string is not reached.
  211.     if (fPos < ((fText == 0) ? 0 : fText->endIndex())) {
  212.         fPos = nextPosition(fPos);
  213.         result = fPos;
  214.     }
  215.     else {
  216.         result = DONE;
  217.     }
  218.  
  219.     return result;
  220. }
  221.  
  222. // -------------------------------------
  223. // Finds the offset of the next text boundary after the specified offset.
  224.  
  225. UTextOffset
  226. SimpleTextBoundary::following(UTextOffset offset)
  227. {
  228.     if (offset >= ((fText == 0) ? 0 : fText->endIndex()))
  229.     {
  230.         fPos = (fText == 0) ? 0 : fText->endIndex();
  231.         return DONE;
  232.     }
  233.     else if (offset < fText->startIndex())
  234.     {
  235.         fPos = 0;
  236.         return 0;
  237.     }
  238.  
  239.     fPos = previousSafePosition(offset);
  240.     UTextOffset result;
  241.     do {
  242.         result = next();
  243.     }
  244.     while (result <= offset && result != DONE);
  245.  
  246.     return result;
  247. }
  248.  
  249. // -------------------------------------
  250. // Finds the offset of the next text boundary before the specified offset.
  251.  
  252. UTextOffset
  253. SimpleTextBoundary::preceding(UTextOffset offset)
  254. {
  255.     if (offset <= fText->startIndex())
  256.     {
  257.         fPos = 0;
  258.         return DONE;
  259.     }
  260.     else if (offset > ((fText == 0) ? 0 : fText->endIndex()))
  261.     {
  262.         fPos = (fText == 0) ? 0 : fText->endIndex();
  263.         return fPos;
  264.     }
  265.  
  266.     fPos = previousSafePosition(offset);
  267.     UTextOffset p = fPos;
  268.     UTextOffset last;
  269.     do {
  270.         last = p;
  271.         p = next();
  272.     }
  273.     while (p < offset && p != DONE);
  274.  
  275.     fPos = last;
  276.     return last;
  277. }
  278.  
  279. bool_t
  280. SimpleTextBoundary::isBoundary(UTextOffset offset)
  281. {
  282.     UTextOffset begin = fText->startIndex();
  283.     if (offset < begin || offset >= ((fText == 0) ? 0 : fText->endIndex())) {
  284.         return FALSE;
  285.     } if (offset == begin) {
  286.         return TRUE;
  287.     } else {
  288.         return following(offset - 1) == offset;
  289.     }
  290. }
  291.      
  292.  
  293. // -------------------------------------
  294. // Returns the current text offset.
  295.  
  296. UTextOffset
  297. SimpleTextBoundary::current() const
  298. {
  299.     return fPos;
  300. }
  301.  
  302. // -------------------------------------
  303. // Finds the previous safe position; stepping backwards in the target text 
  304. // until the end state is reached.
  305.  
  306. UTextOffset
  307. SimpleTextBoundary::previousSafePosition(UTextOffset offset)
  308. {
  309.     UTextOffset result = fText->startIndex();
  310.  
  311.     // Stepping the target text backwards to find the previous safe spot.
  312.     TextBoundaryData::Node state = fBackward->initialState();
  313.     UChar c;
  314.  
  315.     if (offset == result) 
  316.       ++offset;
  317.  
  318.     for (c = fText->setIndex(offset - 1);
  319.     c != CharacterIterator::DONE && !fBackward->isEndState(state);
  320.         c = fText->previous()) {
  321.  
  322.         state = fBackward->get(state, fMap->mappedChar(c));
  323.         if (fBackward->isMarkState(state)) {
  324.             result = fText->getIndex();
  325.         }
  326.     }
  327.     return result;
  328. }
  329.  
  330. // -------------------------------------
  331. // Finds the next position; stepping forwards in the target text 
  332. // until the end state is reached.
  333.  
  334. UTextOffset
  335. SimpleTextBoundary::nextPosition(UTextOffset offset)
  336. {
  337.     UTextOffset endIndex = (fText == 0) ? 0 : fText->endIndex();
  338.  
  339.     TextBoundaryData::Node state = fForward->initialState();
  340.     UTextOffset p = offset;
  341.     UChar c;
  342.  
  343.     for (c = fText->setIndex(offset);
  344.          c != CharacterIterator::DONE && !fForward->isEndState(state);
  345.          c = fText->next()) {
  346.         state = fForward->get(state, fMap->mappedChar(c));
  347.         if (fForward->isMarkState(state)) {
  348.             endIndex = fText->getIndex();
  349.         }
  350.     }
  351.     if (fForward->isEndState(state))
  352.         return endIndex;
  353.     else {
  354.         state = fForward->get(state, fMap->mappedChar(kEND_OF_STRING));
  355.         if (fForward->isMarkState(state))
  356.             return ((fText == 0) ? 0 : fText->endIndex());
  357.         else
  358.             return endIndex;
  359.     }
  360. }
  361.  
  362. //eof
  363.