/** * Set the iterator to analyze a new piece of text. This function resets the current iteration * position to the beginning of the text. * * @param newText An iterator over the text to analyze. */ @Override public void setText(CharacterIterator newText) { // Test iterator to see if we need to wrap it in a SafeCharIterator. // The correct behavior for CharacterIterators is to allow the // position to be set to the endpoint of the iterator. Many // CharacterIterators do not uphold this, so this is a workaround // to permit them to use this class. int end = newText.getEndIndex(); boolean goodIterator; try { newText.setIndex(end); // some buggy iterators throw an exception here goodIterator = newText.getIndex() == end; } catch (IllegalArgumentException e) { goodIterator = false; } if (goodIterator) { text = newText; } else { text = new SafeCharIterator(newText); } text.first(); cachedLastKnownBreak = BreakIterator.DONE; }
/** Returns the position of next character. */ private int getNextIndex() { int index = text.getIndex() + getCurrentCodePointCount(); int endIndex = text.getEndIndex(); if (index > endIndex) { return endIndex; } else { return index; } }
/** Returns next character */ int getNext() { int index = text.getIndex(); int endIndex = text.getEndIndex(); if (index == endIndex || (index += getCurrentCodePointCount()) >= endIndex) { return CharacterIterator.DONE; } text.setIndex(index); return getCurrent(); }
/** * Sets the current iteration position to the end of the text. (i.e., the CharacterIterator's * ending offset). * * @return The text's past-the-end offset. */ @Override public int last() { CharacterIterator t = getText(); // I'm not sure why, but t.last() returns the offset of the last character, // rather than the past-the-end offset t.setIndex(t.getEndIndex()); return t.getIndex(); }
/** Returns the count of next character. */ private int getCurrentCodePointCount() { char c1 = text.current(); if (Character.isHighSurrogate(c1) && text.getIndex() < text.getEndIndex()) { char c2 = text.next(); text.previous(); if (Character.isLowSurrogate(c2)) { return 2; } } return 1; }
/** Returns current character */ int getCurrent() { char c1 = text.current(); if (Character.isHighSurrogate(c1) && text.getIndex() < text.getEndIndex()) { char c2 = text.next(); text.previous(); if (Character.isLowSurrogate(c2)) { return Character.toCodePoint(c1, c2); } } return (int) c1; }
public void selectionDone(SelectionEvent evt) { if (!useUnixTextSelection) return; Object o = evt.getSelection(); if (!(o instanceof CharacterIterator)) return; CharacterIterator iter = (CharacterIterator) o; // first see if we can access the clipboard SecurityManager securityManager; securityManager = System.getSecurityManager(); if (securityManager != null) { try { securityManager.checkSystemClipboardAccess(); } catch (SecurityException e) { return; // Can't access clipboard. } } int sz = iter.getEndIndex() - iter.getBeginIndex(); if (sz == 0) return; char[] cbuff = new char[sz]; cbuff[0] = iter.first(); for (int i = 1; i < cbuff.length; ++i) { cbuff[i] = iter.next(); } final String strSel = new String(cbuff); // HACK: getSystemClipboard sometimes deadlocks on // linux when called from the AWT Thread. The Thread // creation prevents that. new Thread() { public void run() { Clipboard cb; cb = Toolkit.getDefaultToolkit().getSystemClipboard(); StringSelection sel; sel = new StringSelection(strSel); cb.setContents(sel, sel); } }.start(); }
public int getLength() { return (iterator.getEndIndex() - iterator.getBeginIndex()); }
private char next() { if (it.getIndex() == it.getEndIndex()) throw new RuntimeException("Reached end of input at the " + it.getIndex() + "th character."); c = it.next(); return c; }
/** * This method is the actual implementation of the next() method. All iteration vectors through * here. This method initializes the state machine to state 1 and advances through the text * character by character until we reach the end of the text or the state machine transitions to * state 0. We update our return value every time the state machine passes through a possible end * state. */ protected int handleNext() { // if we're already at the end of the text, return DONE. CharacterIterator text = getText(); if (text.getIndex() == text.getEndIndex()) { return BreakIterator.DONE; } // no matter what, we always advance at least one character forward int result = getNextIndex(); int lookaheadResult = 0; // begin in state 1 int state = START_STATE; int category; int c = getCurrent(); // loop until we reach the end of the text or transition to state 0 while (c != CharacterIterator.DONE && state != STOP_STATE) { // look up the current character's character category (which tells us // which column in the state table to look at) category = lookupCategory(c); // if the character isn't an ignore character, look up a state // transition in the state table if (category != IGNORE) { state = lookupState(state, category); } // if the state we've just transitioned to is a lookahead state, // (but not also an end state), save its position. If it's // both a lookahead state and an end state, update the break position // to the last saved lookup-state position if (lookaheadStates[state]) { if (endStates[state]) { result = lookaheadResult; } else { lookaheadResult = getNextIndex(); } } // otherwise, if the state we've just transitioned to is an accepting // state, update the break position to be the current iteration position else { if (endStates[state]) { result = getNextIndex(); } } c = getNext(); } // if we've run off the end of the text, and the very last character took us into // a lookahead state, advance the break position to the lookahead position // (the theory here is that if there are no characters at all after the lookahead // position, that always matches the lookahead criteria) if (c == CharacterIterator.DONE && lookaheadResult == text.getEndIndex()) { result = lookaheadResult; } text.setIndex(result); return result; }
/** Throw IllegalArgumentException unless begin <= offset < end. */ protected static final void checkOffset(int offset, CharacterIterator text) { if (offset < text.getBeginIndex() || offset > text.getEndIndex()) { throw new IllegalArgumentException("offset out of bounds"); } }
SafeCharIterator(CharacterIterator base) { this.base = base; this.rangeStart = base.getBeginIndex(); this.rangeLimit = base.getEndIndex(); this.currentIndex = base.getIndex(); }