michael@0: /*
michael@0: **********************************************************************
michael@0: * Copyright (c) 2002-2006, International Business Machines
michael@0: * Corporation and others. All Rights Reserved.
michael@0: **********************************************************************
michael@0: */
michael@0: #include "unicode/usetiter.h"
michael@0: #include "unicode/uniset.h"
michael@0: #include "unicode/unistr.h"
michael@0: #include "uvector.h"
michael@0:
michael@0: U_NAMESPACE_BEGIN
michael@0:
michael@0: UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeSetIterator)
michael@0:
michael@0: /**
michael@0: * Create an iterator
michael@0: * @param set set to iterate over
michael@0: */
michael@0: UnicodeSetIterator::UnicodeSetIterator(const UnicodeSet& uSet) {
michael@0: cpString = NULL;
michael@0: reset(uSet);
michael@0: }
michael@0:
michael@0: /**
michael@0: * Create an iterator. Convenience for when the contents are to be set later.
michael@0: */
michael@0: UnicodeSetIterator::UnicodeSetIterator() {
michael@0: this->set = NULL;
michael@0: cpString = NULL;
michael@0: reset();
michael@0: }
michael@0:
michael@0: UnicodeSetIterator::~UnicodeSetIterator() {
michael@0: delete cpString;
michael@0: }
michael@0:
michael@0: /**
michael@0: * Returns the next element in the set.
michael@0: * @return true if there was another element in the set.
michael@0: * if so, if codepoint == IS_STRING, the value is a string in the string field
michael@0: * else the value is a single code point in the codepoint field.
michael@0: *
You are guaranteed that the codepoints are in sorted order, and the strings are in sorted order,
michael@0: * and that all code points are returned before any strings are returned.
michael@0: *
Note also that the codepointEnd is undefined after calling this method.
michael@0: */
michael@0: UBool UnicodeSetIterator::next() {
michael@0: if (nextElement <= endElement) {
michael@0: codepoint = codepointEnd = nextElement++;
michael@0: string = NULL;
michael@0: return TRUE;
michael@0: }
michael@0: if (range < endRange) {
michael@0: loadRange(++range);
michael@0: codepoint = codepointEnd = nextElement++;
michael@0: string = NULL;
michael@0: return TRUE;
michael@0: }
michael@0:
michael@0: if (nextString >= stringCount) return FALSE;
michael@0: codepoint = (UChar32)IS_STRING; // signal that value is actually a string
michael@0: string = (const UnicodeString*) set->strings->elementAt(nextString++);
michael@0: return TRUE;
michael@0: }
michael@0:
michael@0: /**
michael@0: * @return true if there was another element in the set.
michael@0: * if so, if codepoint == IS_STRING, the value is a string in the string field
michael@0: * else the value is a range of codepoints in the fields.
michael@0: *
Note that the codepoints are in sorted order, and the strings are in sorted order,
michael@0: * and that all code points are returned before any strings are returned.
michael@0: *
You are guaranteed that the ranges are in sorted order, and the strings are in sorted order,
michael@0: * and that all ranges are returned before any strings are returned.
michael@0: *
You are also guaranteed that ranges are disjoint and non-contiguous.
michael@0: *
Note also that the codepointEnd is undefined after calling this method.
michael@0: */
michael@0: UBool UnicodeSetIterator::nextRange() {
michael@0: string = NULL;
michael@0: if (nextElement <= endElement) {
michael@0: codepointEnd = endElement;
michael@0: codepoint = nextElement;
michael@0: nextElement = endElement+1;
michael@0: return TRUE;
michael@0: }
michael@0: if (range < endRange) {
michael@0: loadRange(++range);
michael@0: codepointEnd = endElement;
michael@0: codepoint = nextElement;
michael@0: nextElement = endElement+1;
michael@0: return TRUE;
michael@0: }
michael@0:
michael@0: if (nextString >= stringCount) return FALSE;
michael@0: codepoint = (UChar32)IS_STRING; // signal that value is actually a string
michael@0: string = (const UnicodeString*) set->strings->elementAt(nextString++);
michael@0: return TRUE;
michael@0: }
michael@0:
michael@0: /**
michael@0: *@param set the set to iterate over. This allows reuse of the iterator.
michael@0: */
michael@0: void UnicodeSetIterator::reset(const UnicodeSet& uSet) {
michael@0: this->set = &uSet;
michael@0: reset();
michael@0: }
michael@0:
michael@0: /**
michael@0: * Resets to the start, to allow the iteration to start over again.
michael@0: */
michael@0: void UnicodeSetIterator::reset() {
michael@0: if (set == NULL) {
michael@0: // Set up indices to empty iteration
michael@0: endRange = -1;
michael@0: stringCount = 0;
michael@0: } else {
michael@0: endRange = set->getRangeCount() - 1;
michael@0: stringCount = set->strings->size();
michael@0: }
michael@0: range = 0;
michael@0: endElement = -1;
michael@0: nextElement = 0;
michael@0: if (endRange >= 0) {
michael@0: loadRange(range);
michael@0: }
michael@0: nextString = 0;
michael@0: string = NULL;
michael@0: }
michael@0:
michael@0: void UnicodeSetIterator::loadRange(int32_t iRange) {
michael@0: nextElement = set->getRangeStart(iRange);
michael@0: endElement = set->getRangeEnd(iRange);
michael@0: }
michael@0:
michael@0:
michael@0: const UnicodeString& UnicodeSetIterator::getString() {
michael@0: if (string==NULL && codepoint!=(UChar32)IS_STRING) {
michael@0: if (cpString == NULL) {
michael@0: cpString = new UnicodeString();
michael@0: }
michael@0: if (cpString != NULL) {
michael@0: cpString->setTo((UChar32)codepoint);
michael@0: }
michael@0: string = cpString;
michael@0: }
michael@0: return *string;
michael@0: }
michael@0:
michael@0: U_NAMESPACE_END
michael@0:
michael@0: //eof