quant.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. **********************************************************************
  5. * Copyright (C) 2001-2012, International Business Machines
  6. * Corporation and others. All Rights Reserved.
  7. **********************************************************************
  8. * Date Name Description
  9. * 07/26/01 aliu Creation.
  10. **********************************************************************
  11. */
  12. #include "unicode/utypes.h"
  13. #if !UCONFIG_NO_TRANSLITERATION
  14. #include "quant.h"
  15. #include "unicode/unistr.h"
  16. #include "util.h"
  17. U_NAMESPACE_BEGIN
  18. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Quantifier)
  19. Quantifier::Quantifier(UnicodeFunctor *adoptedMatcher,
  20. uint32_t _minCount, uint32_t _maxCount) {
  21. // assert(adopted != 0);
  22. // assert(minCount <= maxCount);
  23. matcher = adoptedMatcher;
  24. this->minCount = _minCount;
  25. this->maxCount = _maxCount;
  26. }
  27. Quantifier::Quantifier(const Quantifier& o) :
  28. UnicodeFunctor(o),
  29. UnicodeMatcher(o),
  30. matcher(o.matcher->clone()),
  31. minCount(o.minCount),
  32. maxCount(o.maxCount)
  33. {
  34. }
  35. Quantifier::~Quantifier() {
  36. delete matcher;
  37. }
  38. /**
  39. * Implement UnicodeFunctor
  40. */
  41. Quantifier* Quantifier::clone() const {
  42. return new Quantifier(*this);
  43. }
  44. /**
  45. * UnicodeFunctor API. Cast 'this' to a UnicodeMatcher* pointer
  46. * and return the pointer.
  47. */
  48. UnicodeMatcher* Quantifier::toMatcher() const {
  49. Quantifier *nonconst_this = const_cast<Quantifier *>(this);
  50. UnicodeMatcher *nonconst_base = static_cast<UnicodeMatcher *>(nonconst_this);
  51. return nonconst_base;
  52. }
  53. UMatchDegree Quantifier::matches(const Replaceable& text,
  54. int32_t& offset,
  55. int32_t limit,
  56. UBool incremental) {
  57. int32_t start = offset;
  58. uint32_t count = 0;
  59. while (count < maxCount) {
  60. int32_t pos = offset;
  61. UMatchDegree m = matcher->toMatcher()->matches(text, offset, limit, incremental);
  62. if (m == U_MATCH) {
  63. ++count;
  64. if (pos == offset) {
  65. // If offset has not moved we have a zero-width match.
  66. // Don't keep matching it infinitely.
  67. break;
  68. }
  69. } else if (incremental && m == U_PARTIAL_MATCH) {
  70. return U_PARTIAL_MATCH;
  71. } else {
  72. break;
  73. }
  74. }
  75. if (incremental && offset == limit) {
  76. return U_PARTIAL_MATCH;
  77. }
  78. if (count >= minCount) {
  79. return U_MATCH;
  80. }
  81. offset = start;
  82. return U_MISMATCH;
  83. }
  84. /**
  85. * Implement UnicodeMatcher
  86. */
  87. UnicodeString& Quantifier::toPattern(UnicodeString& result,
  88. UBool escapeUnprintable) const {
  89. result.truncate(0);
  90. matcher->toMatcher()->toPattern(result, escapeUnprintable);
  91. if (minCount == 0) {
  92. if (maxCount == 1) {
  93. return result.append((char16_t)63); /*?*/
  94. } else if (maxCount == MAX) {
  95. return result.append((char16_t)42); /***/
  96. }
  97. // else fall through
  98. } else if (minCount == 1 && maxCount == MAX) {
  99. return result.append((char16_t)43); /*+*/
  100. }
  101. result.append((char16_t)123); /*{*/
  102. ICU_Utility::appendNumber(result, minCount);
  103. result.append((char16_t)44); /*,*/
  104. if (maxCount != MAX) {
  105. ICU_Utility::appendNumber(result, maxCount);
  106. }
  107. result.append((char16_t)125); /*}*/
  108. return result;
  109. }
  110. /**
  111. * Implement UnicodeMatcher
  112. */
  113. UBool Quantifier::matchesIndexValue(uint8_t v) const {
  114. return (minCount == 0) || matcher->toMatcher()->matchesIndexValue(v);
  115. }
  116. /**
  117. * Implement UnicodeMatcher
  118. */
  119. void Quantifier::addMatchSetTo(UnicodeSet& toUnionTo) const {
  120. if (maxCount > 0) {
  121. matcher->toMatcher()->addMatchSetTo(toUnionTo);
  122. }
  123. }
  124. /**
  125. * Implement UnicodeFunctor
  126. */
  127. void Quantifier::setData(const TransliterationRuleData* d) {
  128. matcher->setData(d);
  129. }
  130. U_NAMESPACE_END
  131. #endif /* #if !UCONFIG_NO_TRANSLITERATION */
  132. //eof