blob: 3ed1aff99eddb23329c06f5b52d642e9655b60e1 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1996-2000, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/UnicodeSetIterator.java,v $
* $Date: 2002/03/20 05:11:17 $
* $Revision: 1.8 $
*
*****************************************************************************************
*/
package com.ibm.icu.text;
import com.ibm.icu.impl.Utility;
//import java.text.*;
import java.util.*;
import java.io.*;
/**
* Class that allows simple iteration over a UnicodeSet.
* @author M. Davis
* @draft
* @internal -- this API is not for general use, and may change at any time.
*/
public final class UnicodeSetIterator {
public static int IS_STRING = -1;
// for results of iteration
public int codepoint;
public int codepointEnd;
public String string;
/**
* Create an iterator
* @param set set to iterate over
*/
public UnicodeSetIterator(UnicodeSet set) {
reset(set);
}
/**
* Create an iterator. Convenience for when the contents are to be set later.
*/
public UnicodeSetIterator() {
reset(new UnicodeSet());
}
/**
* Returns the next element in the set.
* @return true if there was another element in the set.
* if so, if codepoint == IS_STRING, the value is a string in the string field
* else the value is a single code point in the codepoint field.
* <br>You are guaranteed that the codepoints are in sorted order, and the strings are in sorted order,
* and that all code points are returned before any strings are returned.
* <br>Note also that the codepointEnd is undefined after calling this method.
*/
public boolean next() {
if (nextElement <= endElement) {
codepoint = codepointEnd = nextElement++;
return true;
}
if (range < endRange) {
++range;
nextElement = startElement = set.getRangeStart(range);
endElement = set.getRangeEnd(range);
if (abbreviated && (endElement > startElement + 50)) {
endElement = startElement + 50;
}
codepoint = codepointEnd = nextElement++;
return true;
}
// stringIterator == null iff there are no string elements remaining
if (stringIterator == null) return false;
codepoint = IS_STRING; // signal that value is actually a string
string = (String)stringIterator.next();
if (!stringIterator.hasNext()) stringIterator = null;
return true;
}
/**
* @return true if there was another element in the set.
* if so, if codepoint == IS_STRING, the value is a string in the string field
* else the value is a range of codepoints in the <codepoint, codepointEnd> fields.
* <br>Note that the codepoints are in sorted order, and the strings are in sorted order,
* and that all code points are returned before any strings are returned.
* <br>You are guaranteed that the ranges are in sorted order, and the strings are in sorted order,
* and that all ranges are returned before any strings are returned.
* <br>You are also guaranteed that ranges are disjoint and non-contiguous.
* <br>Note also that the codepointEnd is undefined after calling this method.
*/
public boolean nextRange() {
if (nextElement <= endElement) {
codepointEnd = endElement;
codepoint = nextElement;
nextElement = endElement+1;
return true;
}
if (range < endRange) {
++range;
nextElement = startElement = set.getRangeStart(range);
endElement = set.getRangeEnd(range);
if (abbreviated && (endElement > startElement + 50)) {
endElement = startElement + 50;
}
codepointEnd = endElement;
codepoint = nextElement;
nextElement = endElement+1;
return true;
}
// stringIterator == null iff there are no string elements remaining
if (stringIterator == null) return false;
codepoint = IS_STRING; // signal that value is actually a string
string = (String)stringIterator.next();
if (!stringIterator.hasNext()) stringIterator = null;
return true;
}
/**
*@param set the set to iterate over. This allows reuse of the iterator.
*/
public void reset(UnicodeSet set) {
this.set = set;
endRange = set.getRangeCount() - 1;
resetInternal();
}
/**
* Resets to the start, to allow the iteration to start over again.
*/
public void reset() {
endRange = set.getRangeCount() - 1;
resetInternal();
}
/**
* Causes the interation to only to part of long ranges
* @internal -- used only for testing
*/
public void setAbbreviated(boolean abbr) {
abbreviated = abbr;
}
/**
* Causes the interation to only to part of long ranges
* @internal -- used only for testing
*/
public boolean getAbbreviated() {
return abbreviated;
}
// ======================= PRIVATES ===========================
private UnicodeSet set;
private int endRange = 0;
private int range = 0;
private int startElement = 0;
private int endElement;
private int nextElement;
private boolean abbreviated = false;
private Iterator stringIterator = null;
/**
* Invariant: stringIterator is null when there are no (more) strings remaining
*/
private void resetInternal() {
range = 0;
endElement = -1;
nextElement = 0;
if (endRange >= 0) {
nextElement = startElement = set.getRangeStart(range);
endElement = set.getRangeEnd(range);
if (abbreviated && (endElement > startElement + 50)) {
endElement = startElement + 50;
}
}
stringIterator = null;
if (set.strings != null) {
stringIterator = set.strings.iterator();
if (!stringIterator.hasNext()) stringIterator = null;
}
}
}