001: /*
002: *******************************************************************************
003: * Copyright (C) 2001-2005, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007: package com.ibm.icu.text;
008:
009: import com.ibm.icu.impl.Utility;
010:
011: class Quantifier implements UnicodeMatcher {
012:
013: private UnicodeMatcher matcher;
014:
015: private int minCount;
016:
017: private int maxCount;
018:
019: /**
020: * Maximum count a quantifier can have.
021: */
022: public static final int MAX = Integer.MAX_VALUE;
023:
024: public Quantifier(UnicodeMatcher theMatcher, int theMinCount,
025: int theMaxCount) {
026: if (theMatcher == null || minCount < 0 || maxCount < 0
027: || minCount > maxCount) {
028: throw new IllegalArgumentException();
029: }
030: matcher = theMatcher;
031: minCount = theMinCount;
032: maxCount = theMaxCount;
033: }
034:
035: /**
036: * Implement UnicodeMatcher API.
037: */
038: public int matches(Replaceable text, int[] offset, int limit,
039: boolean incremental) {
040: int start = offset[0];
041: int count = 0;
042: while (count < maxCount) {
043: int pos = offset[0];
044: int m = matcher.matches(text, offset, limit, incremental);
045: if (m == U_MATCH) {
046: ++count;
047: if (pos == offset[0]) {
048: // If offset has not moved we have a zero-width match.
049: // Don't keep matching it infinitely.
050: break;
051: }
052: } else if (incremental && m == U_PARTIAL_MATCH) {
053: return U_PARTIAL_MATCH;
054: } else {
055: break;
056: }
057: }
058: if (incremental && offset[0] == limit) {
059: return U_PARTIAL_MATCH;
060: }
061: if (count >= minCount) {
062: return U_MATCH;
063: }
064: offset[0] = start;
065: return U_MISMATCH;
066: }
067:
068: /**
069: * Implement UnicodeMatcher API
070: */
071: public String toPattern(boolean escapeUnprintable) {
072: StringBuffer result = new StringBuffer();
073: result.append(matcher.toPattern(escapeUnprintable));
074: if (minCount == 0) {
075: if (maxCount == 1) {
076: return result.append('?').toString();
077: } else if (maxCount == MAX) {
078: return result.append('*').toString();
079: }
080: // else fall through
081: } else if (minCount == 1 && maxCount == MAX) {
082: return result.append('+').toString();
083: }
084: result.append('{');
085: Utility.appendNumber(result, minCount);
086: result.append(',');
087: if (maxCount != MAX) {
088: Utility.appendNumber(result, maxCount);
089: }
090: result.append('}');
091: return result.toString();
092: }
093:
094: /**
095: * Implement UnicodeMatcher API
096: */
097: public boolean matchesIndexValue(int v) {
098: return (minCount == 0) || matcher.matchesIndexValue(v);
099: }
100:
101: /**
102: * Implementation of UnicodeMatcher API. Union the set of all
103: * characters that may be matched by this object into the given
104: * set.
105: * @param toUnionTo the set into which to union the source characters
106: * @returns a reference to toUnionTo
107: */
108: public void addMatchSetTo(UnicodeSet toUnionTo) {
109: if (maxCount > 0) {
110: matcher.addMatchSetTo(toUnionTo);
111: }
112: }
113: }
114:
115: //eof
|