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