intl/icu/source/i18n/quant.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/i18n/quant.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,149 @@
     1.4 +/*
     1.5 +**********************************************************************
     1.6 +*   Copyright (C) 2001-2012, International Business Machines
     1.7 +*   Corporation and others.  All Rights Reserved.
     1.8 +**********************************************************************
     1.9 +*   Date        Name        Description
    1.10 +*   07/26/01    aliu        Creation.
    1.11 +**********************************************************************
    1.12 +*/
    1.13 +
    1.14 +#include "unicode/utypes.h"
    1.15 +
    1.16 +#if !UCONFIG_NO_TRANSLITERATION
    1.17 +
    1.18 +#include "quant.h"
    1.19 +#include "unicode/unistr.h"
    1.20 +#include "util.h"
    1.21 +
    1.22 +U_NAMESPACE_BEGIN
    1.23 +
    1.24 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier)
    1.25 +
    1.26 +Quantifier::Quantifier(UnicodeFunctor *adoptedMatcher,
    1.27 +                       uint32_t _minCount, uint32_t _maxCount) {
    1.28 +    // assert(adopted != 0);
    1.29 +    // assert(minCount <= maxCount);
    1.30 +    matcher = adoptedMatcher;
    1.31 +    this->minCount = _minCount;
    1.32 +    this->maxCount = _maxCount;
    1.33 +}
    1.34 +
    1.35 +Quantifier::Quantifier(const Quantifier& o) :
    1.36 +    UnicodeFunctor(o),
    1.37 +    UnicodeMatcher(o),
    1.38 +    matcher(o.matcher->clone()),
    1.39 +    minCount(o.minCount),
    1.40 +    maxCount(o.maxCount)
    1.41 +{
    1.42 +}
    1.43 +
    1.44 +Quantifier::~Quantifier() {
    1.45 +    delete matcher;
    1.46 +}
    1.47 +
    1.48 +/**
    1.49 + * Implement UnicodeFunctor
    1.50 + */
    1.51 +UnicodeFunctor* Quantifier::clone() const {
    1.52 +    return new Quantifier(*this);
    1.53 +}
    1.54 +
    1.55 +/**
    1.56 + * UnicodeFunctor API.  Cast 'this' to a UnicodeMatcher* pointer
    1.57 + * and return the pointer.
    1.58 + */
    1.59 +UnicodeMatcher* Quantifier::toMatcher() const {
    1.60 +  Quantifier  *nonconst_this = const_cast<Quantifier *>(this);
    1.61 +  UnicodeMatcher *nonconst_base = static_cast<UnicodeMatcher *>(nonconst_this);
    1.62 +  
    1.63 +  return nonconst_base;
    1.64 +}
    1.65 +
    1.66 +UMatchDegree Quantifier::matches(const Replaceable& text,
    1.67 +                                 int32_t& offset,
    1.68 +                                 int32_t limit,
    1.69 +                                 UBool incremental) {
    1.70 +    int32_t start = offset;
    1.71 +    uint32_t count = 0;
    1.72 +    while (count < maxCount) {
    1.73 +        int32_t pos = offset;
    1.74 +        UMatchDegree m = matcher->toMatcher()->matches(text, offset, limit, incremental);
    1.75 +        if (m == U_MATCH) {
    1.76 +            ++count;
    1.77 +            if (pos == offset) {
    1.78 +                // If offset has not moved we have a zero-width match.
    1.79 +                // Don't keep matching it infinitely.
    1.80 +                break;
    1.81 +            }
    1.82 +        } else if (incremental && m == U_PARTIAL_MATCH) {
    1.83 +            return U_PARTIAL_MATCH;
    1.84 +        } else {
    1.85 +            break;
    1.86 +        }
    1.87 +    }
    1.88 +    if (incremental && offset == limit) {
    1.89 +        return U_PARTIAL_MATCH;
    1.90 +    }
    1.91 +    if (count >= minCount) {
    1.92 +        return U_MATCH;
    1.93 +    }
    1.94 +    offset = start;
    1.95 +    return U_MISMATCH;
    1.96 +}
    1.97 +
    1.98 +/**
    1.99 + * Implement UnicodeMatcher
   1.100 + */
   1.101 +UnicodeString& Quantifier::toPattern(UnicodeString& result,
   1.102 +                                     UBool escapeUnprintable) const {
   1.103 +	result.truncate(0);
   1.104 +    matcher->toMatcher()->toPattern(result, escapeUnprintable);
   1.105 +    if (minCount == 0) {
   1.106 +        if (maxCount == 1) {
   1.107 +            return result.append((UChar)63); /*?*/
   1.108 +        } else if (maxCount == MAX) {
   1.109 +            return result.append((UChar)42); /***/
   1.110 +        }
   1.111 +        // else fall through
   1.112 +    } else if (minCount == 1 && maxCount == MAX) {
   1.113 +        return result.append((UChar)43); /*+*/
   1.114 +    }
   1.115 +    result.append((UChar)123); /*{*/
   1.116 +    ICU_Utility::appendNumber(result, minCount);
   1.117 +    result.append((UChar)44); /*,*/
   1.118 +    if (maxCount != MAX) {
   1.119 +        ICU_Utility::appendNumber(result, maxCount);
   1.120 +    }
   1.121 +    result.append((UChar)125); /*}*/
   1.122 +    return result;
   1.123 +}
   1.124 +
   1.125 +/**
   1.126 + * Implement UnicodeMatcher
   1.127 + */
   1.128 +UBool Quantifier::matchesIndexValue(uint8_t v) const {
   1.129 +    return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
   1.130 +}
   1.131 +
   1.132 +/**
   1.133 + * Implement UnicodeMatcher
   1.134 + */
   1.135 +void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
   1.136 +    if (maxCount > 0) {
   1.137 +        matcher->toMatcher()->addMatchSetTo(toUnionTo);
   1.138 +    }
   1.139 +}
   1.140 +
   1.141 +/**
   1.142 + * Implement UnicodeFunctor
   1.143 + */
   1.144 +void Quantifier::setData(const TransliterationRuleData* d) {
   1.145 +		matcher->setData(d);
   1.146 +}
   1.147 +
   1.148 +U_NAMESPACE_END
   1.149 +
   1.150 +#endif /* #if !UCONFIG_NO_TRANSLITERATION */
   1.151 +
   1.152 +//eof

mercurial