void CharIterTest::TestUCharIterator() { // test string of length 8 UnicodeString s=UnicodeString("a \\U00010001b\\U0010fffdz", "").unescape(); const char *const moves= "0+++++++++" // 10 moves per line "----0-----" ">>|>>>>>>>" "<<|<<<<<<<" "22+>8>-8+2"; StringCharacterIterator sci(s), compareCI(s); UCharIterator sIter, cIter, rIter; uiter_setString(&sIter, s.getBuffer(), s.length()); uiter_setCharacterIterator(&cIter, &sci); uiter_setReplaceable(&rIter, &s); TestUCharIterator(&sIter, compareCI, moves, "uiter_setString"); compareCI.setIndex(0); TestUCharIterator(&cIter, compareCI, moves, "uiter_setCharacterIterator"); compareCI.setIndex(0); TestUCharIterator(&rIter, compareCI, moves, "uiter_setReplaceable"); // test move & getIndex some more sIter.start=2; sIter.index=3; sIter.limit=5; if( sIter.getIndex(&sIter, UITER_ZERO)!=0 || sIter.getIndex(&sIter, UITER_START)!=2 || sIter.getIndex(&sIter, UITER_CURRENT)!=3 || sIter.getIndex(&sIter, UITER_LIMIT)!=5 || sIter.getIndex(&sIter, UITER_LENGTH)!=s.length() ) { errln("error: UCharIterator(string).getIndex returns wrong index"); } if( sIter.move(&sIter, 4, UITER_ZERO)!=4 || sIter.move(&sIter, 1, UITER_START)!=3 || sIter.move(&sIter, 3, UITER_CURRENT)!=5 || sIter.move(&sIter, -1, UITER_LIMIT)!=4 || sIter.move(&sIter, -5, UITER_LENGTH)!=3 || sIter.move(&sIter, 0, UITER_CURRENT)!=sIter.getIndex(&sIter, UITER_CURRENT) || sIter.getIndex(&sIter, UITER_CURRENT)!=3 ) { errln("error: UCharIterator(string).move sets/returns wrong index"); } sci=StringCharacterIterator(s, 2, 5, 3); uiter_setCharacterIterator(&cIter, &sci); if( cIter.getIndex(&cIter, UITER_ZERO)!=0 || cIter.getIndex(&cIter, UITER_START)!=2 || cIter.getIndex(&cIter, UITER_CURRENT)!=3 || cIter.getIndex(&cIter, UITER_LIMIT)!=5 || cIter.getIndex(&cIter, UITER_LENGTH)!=s.length() ) { errln("error: UCharIterator(character iterator).getIndex returns wrong index"); } if( cIter.move(&cIter, 4, UITER_ZERO)!=4 || cIter.move(&cIter, 1, UITER_START)!=3 || cIter.move(&cIter, 3, UITER_CURRENT)!=5 || cIter.move(&cIter, -1, UITER_LIMIT)!=4 || cIter.move(&cIter, -5, UITER_LENGTH)!=3 || cIter.move(&cIter, 0, UITER_CURRENT)!=cIter.getIndex(&cIter, UITER_CURRENT) || cIter.getIndex(&cIter, UITER_CURRENT)!=3 ) { errln("error: UCharIterator(character iterator).move sets/returns wrong index"); } if(cIter.getIndex(&cIter, (enum UCharIteratorOrigin)-1) != -1) { errln("error: UCharIterator(char iter).getIndex did not return error value"); } if(cIter.move(&cIter, 0, (enum UCharIteratorOrigin)-1) != -1) { errln("error: UCharIterator(char iter).move did not return error value"); } if(rIter.getIndex(&rIter, (enum UCharIteratorOrigin)-1) != -1) { errln("error: UCharIterator(repl iter).getIndex did not return error value"); } if(rIter.move(&rIter, 0, (enum UCharIteratorOrigin)-1) != -1) { errln("error: UCharIterator(repl iter).move did not return error value"); } if(sIter.getIndex(&sIter, (enum UCharIteratorOrigin)-1) != -1) { errln("error: UCharIterator(string iter).getIndex did not return error value"); } if(sIter.move(&sIter, 0, (enum UCharIteratorOrigin)-1) != -1) { errln("error: UCharIterator(string iter).move did not return error value"); } /* Testing function coverage on bad input */ UErrorCode status = U_ZERO_ERROR; uiter_setString(&sIter, NULL, 1); uiter_setState(&sIter, 1, &status); if (status != U_UNSUPPORTED_ERROR) { errln("error: uiter_setState returned %s instead of U_UNSUPPORTED_ERROR", u_errorName(status)); } status = U_ZERO_ERROR; uiter_setState(NULL, 1, &status); if (status != U_ILLEGAL_ARGUMENT_ERROR) { errln("error: uiter_setState returned %s instead of U_ILLEGAL_ARGUMENT_ERROR", u_errorName(status)); } if (uiter_getState(&sIter) != UITER_NO_STATE) { errln("error: uiter_getState did not return UITER_NO_STATE on bad input"); } }
/* * Test the iterator's getState() and setState() functions. * iter1 and iter2 must be set up for the same iterator type and the same string * but may be physically different structs (different addresses). * * Assume that the text is not empty and that * iteration start==0 and iteration limit==length. * It must be 2<=middle<=length-2. */ static void testIteratorState(UCharIterator *iter1, UCharIterator *iter2, const char *n, int32_t middle) { UChar32 u[4]; UErrorCode errorCode; UChar32 c; uint32_t state; int32_t i, j; /* get four UChars from the middle of the string */ iter1->move(iter1, middle-2, UITER_ZERO); for(i=0; i<4; ++i) { c=iter1->next(iter1); if(c<0) { /* the test violates the assumptions, see comment above */ log_err("test error: %s[%d]=%d\n", n, middle-2+i, c); return; } u[i]=c; } /* move to the middle and get the state */ iter1->move(iter1, -2, UITER_CURRENT); state=uiter_getState(iter1); /* set the state into the second iterator and compare the results */ errorCode=U_ZERO_ERROR; uiter_setState(iter2, state, &errorCode); if(U_FAILURE(errorCode)) { log_err("%s->setState(0x%x) failed: %s\n", n, state, u_errorName(errorCode)); return; } c=iter2->current(iter2); if(c!=u[2]) { log_err("%s->current(at %d)=U+%04x!=U+%04x\n", n, middle, c, u[2]); } c=iter2->previous(iter2); if(c!=u[1]) { log_err("%s->previous(at %d)=U+%04x!=U+%04x\n", n, middle-1, c, u[1]); } iter2->move(iter2, 2, UITER_CURRENT); c=iter2->next(iter2); if(c!=u[3]) { log_err("%s->next(at %d)=U+%04x!=U+%04x\n", n, middle+1, c, u[3]); } iter2->move(iter2, -3, UITER_CURRENT); c=iter2->previous(iter2); if(c!=u[0]) { log_err("%s->previous(at %d)=U+%04x!=U+%04x\n", n, middle-2, c, u[0]); } /* move the second iterator back to the middle */ iter2->move(iter2, 1, UITER_CURRENT); iter2->next(iter2); /* check that both are in the middle */ i=iter1->getIndex(iter1, UITER_CURRENT); j=iter2->getIndex(iter2, UITER_CURRENT); if(i!=middle) { log_err("%s->getIndex(current)=%d!=%d as expected\n", n, i, middle); } if(i!=j) { log_err("%s->getIndex(current)=%d!=%d after setState()\n", n, j, i); } /* compare lengths */ i=iter1->getIndex(iter1, UITER_LENGTH); j=iter2->getIndex(iter2, UITER_LENGTH); if(i!=j) { log_err("%s->getIndex(length)=%d!=%d before/after setState()\n", n, i, j); } }