1/* 2********************************************************************** 3* Copyright (c) 2002-2006, International Business Machines 4* Corporation and others. All Rights Reserved. 5********************************************************************** 6*/ 7#include "unicode/usetiter.h" 8#include "unicode/uniset.h" 9#include "unicode/unistr.h" 10#include "uvector.h" 11 12U_NAMESPACE_BEGIN 13 14UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeSetIterator) 15 16/** 17 * Create an iterator 18 * @param set set to iterate over 19 */ 20UnicodeSetIterator::UnicodeSetIterator(const UnicodeSet& uSet) { 21 cpString = NULL; 22 reset(uSet); 23} 24 25/** 26 * Create an iterator. Convenience for when the contents are to be set later. 27 */ 28UnicodeSetIterator::UnicodeSetIterator() { 29 this->set = NULL; 30 cpString = NULL; 31 reset(); 32} 33 34UnicodeSetIterator::~UnicodeSetIterator() { 35 delete cpString; 36} 37 38/** 39 * Returns the next element in the set. 40 * @return true if there was another element in the set. 41 * if so, if codepoint == IS_STRING, the value is a string in the string field 42 * else the value is a single code point in the codepoint field. 43 * <br>You are guaranteed that the codepoints are in sorted order, and the strings are in sorted order, 44 * and that all code points are returned before any strings are returned. 45 * <br>Note also that the codepointEnd is undefined after calling this method. 46 */ 47UBool UnicodeSetIterator::next() { 48 if (nextElement <= endElement) { 49 codepoint = codepointEnd = nextElement++; 50 string = NULL; 51 return TRUE; 52 } 53 if (range < endRange) { 54 loadRange(++range); 55 codepoint = codepointEnd = nextElement++; 56 string = NULL; 57 return TRUE; 58 } 59 60 if (nextString >= stringCount) return FALSE; 61 codepoint = (UChar32)IS_STRING; // signal that value is actually a string 62 string = (const UnicodeString*) set->strings->elementAt(nextString++); 63 return TRUE; 64} 65 66/** 67 * @return true if there was another element in the set. 68 * if so, if codepoint == IS_STRING, the value is a string in the string field 69 * else the value is a range of codepoints in the <codepoint, codepointEnd> fields. 70 * <br>Note that the codepoints are in sorted order, and the strings are in sorted order, 71 * and that all code points are returned before any strings are returned. 72 * <br>You are guaranteed that the ranges are in sorted order, and the strings are in sorted order, 73 * and that all ranges are returned before any strings are returned. 74 * <br>You are also guaranteed that ranges are disjoint and non-contiguous. 75 * <br>Note also that the codepointEnd is undefined after calling this method. 76 */ 77UBool UnicodeSetIterator::nextRange() { 78 string = NULL; 79 if (nextElement <= endElement) { 80 codepointEnd = endElement; 81 codepoint = nextElement; 82 nextElement = endElement+1; 83 return TRUE; 84 } 85 if (range < endRange) { 86 loadRange(++range); 87 codepointEnd = endElement; 88 codepoint = nextElement; 89 nextElement = endElement+1; 90 return TRUE; 91 } 92 93 if (nextString >= stringCount) return FALSE; 94 codepoint = (UChar32)IS_STRING; // signal that value is actually a string 95 string = (const UnicodeString*) set->strings->elementAt(nextString++); 96 return TRUE; 97} 98 99/** 100 *@param set the set to iterate over. This allows reuse of the iterator. 101 */ 102void UnicodeSetIterator::reset(const UnicodeSet& uSet) { 103 this->set = &uSet; 104 reset(); 105} 106 107/** 108 * Resets to the start, to allow the iteration to start over again. 109 */ 110void UnicodeSetIterator::reset() { 111 if (set == NULL) { 112 // Set up indices to empty iteration 113 endRange = -1; 114 stringCount = 0; 115 } else { 116 endRange = set->getRangeCount() - 1; 117 stringCount = set->strings->size(); 118 } 119 range = 0; 120 endElement = -1; 121 nextElement = 0; 122 if (endRange >= 0) { 123 loadRange(range); 124 } 125 nextString = 0; 126 string = NULL; 127} 128 129void UnicodeSetIterator::loadRange(int32_t iRange) { 130 nextElement = set->getRangeStart(iRange); 131 endElement = set->getRangeEnd(iRange); 132} 133 134 135const UnicodeString& UnicodeSetIterator::getString() { 136 if (string==NULL && codepoint!=(UChar32)IS_STRING) { 137 if (cpString == NULL) { 138 cpString = new UnicodeString(); 139 } 140 if (cpString != NULL) { 141 cpString->setTo((UChar32)codepoint); 142 } 143 string = cpString; 144 } 145 return *string; 146} 147 148U_NAMESPACE_END 149 150//eof 151