Home | History | Annotate | Download | only in common
      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 
     12 U_NAMESPACE_BEGIN
     13 
     14 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeSetIterator)
     15 
     16 /**
     17  * Create an iterator
     18  * @param set set to iterate over
     19  */
     20 UnicodeSetIterator::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  */
     28 UnicodeSetIterator::UnicodeSetIterator() {
     29     this->set = NULL;
     30     cpString  = NULL;
     31     reset();
     32 }
     33 
     34 UnicodeSetIterator::~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  */
     47 UBool 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  */
     77 UBool 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  */
    102 void 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  */
    110 void 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 
    129 void UnicodeSetIterator::loadRange(int32_t iRange) {
    130     nextElement = set->getRangeStart(iRange);
    131     endElement = set->getRangeEnd(iRange);
    132 }
    133 
    134 
    135 const 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 
    148 U_NAMESPACE_END
    149 
    150 //eof
    151