X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/249c4c5ea9376c24572daf9c2effa7484a282f14..3d1f044b704633e2e541231cd17ae9ecf9ad5c7a:/icuSources/i18n/formattedval_iterimpl.cpp diff --git a/icuSources/i18n/formattedval_iterimpl.cpp b/icuSources/i18n/formattedval_iterimpl.cpp new file mode 100644 index 00000000..75328fae --- /dev/null +++ b/icuSources/i18n/formattedval_iterimpl.cpp @@ -0,0 +1,176 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +// This file contains one implementation of FormattedValue. +// Other independent implementations should go into their own cpp file for +// better dependency modularization. + +#include "formattedval_impl.h" +#include "putilimp.h" + +U_NAMESPACE_BEGIN + + +FormattedValueFieldPositionIteratorImpl::FormattedValueFieldPositionIteratorImpl( + int32_t initialFieldCapacity, + UErrorCode& status) + : fFields(initialFieldCapacity * 4, status) { +} + +FormattedValueFieldPositionIteratorImpl::~FormattedValueFieldPositionIteratorImpl() = default; + +UnicodeString FormattedValueFieldPositionIteratorImpl::toString( + UErrorCode&) const { + return fString; +} + +UnicodeString FormattedValueFieldPositionIteratorImpl::toTempString( + UErrorCode&) const { + // The alias must point to memory owned by this object; + // fastCopyFrom doesn't do this when using a stack buffer. + return UnicodeString(TRUE, fString.getBuffer(), fString.length()); +} + +Appendable& FormattedValueFieldPositionIteratorImpl::appendTo( + Appendable& appendable, + UErrorCode&) const { + appendable.appendString(fString.getBuffer(), fString.length()); + return appendable; +} + +UBool FormattedValueFieldPositionIteratorImpl::nextPosition( + ConstrainedFieldPosition& cfpos, + UErrorCode&) const { + U_ASSERT(fFields.size() % 4 == 0); + int32_t numFields = fFields.size() / 4; + int32_t i = static_cast(cfpos.getInt64IterationContext()); + for (; i < numFields; i++) { + UFieldCategory category = static_cast(fFields.elementAti(i * 4)); + int32_t field = fFields.elementAti(i * 4 + 1); + if (cfpos.matchesField(category, field)) { + int32_t start = fFields.elementAti(i * 4 + 2); + int32_t limit = fFields.elementAti(i * 4 + 3); + cfpos.setState(category, field, start, limit); + break; + } + } + cfpos.setInt64IterationContext(i == numFields ? i : i + 1); + return i < numFields; +} + + +FieldPositionIteratorHandler FormattedValueFieldPositionIteratorImpl::getHandler( + UErrorCode& status) { + return FieldPositionIteratorHandler(&fFields, status); +} + +void FormattedValueFieldPositionIteratorImpl::appendString( + UnicodeString string, + UErrorCode& status) { + if (U_FAILURE(status)) { + return; + } + fString.append(string); + // Make the string NUL-terminated + if (fString.getTerminatedBuffer() == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } +} + + +void FormattedValueFieldPositionIteratorImpl::addOverlapSpans( + UFieldCategory spanCategory, + int8_t firstIndex, + UErrorCode& status) { + // In order to avoid fancy data structures, this is an O(N^2) algorithm, + // which should be fine for all real-life applications of this function. + int32_t s1a = INT32_MAX; + int32_t s1b = 0; + int32_t s2a = INT32_MAX; + int32_t s2b = 0; + int32_t numFields = fFields.size() / 4; + for (int32_t i = 0; i higher rank + comparison = start2 - start1; + } else if (limit1 != limit2) { + // Higher length (end index) -> lower rank + comparison = limit1 - limit2; + } else if (categ1 != categ2) { + // Higher field category -> lower rank + comparison = categ1 - categ2; + } else if (field1 != field2) { + // Higher field -> higher rank + comparison = field2 - field1; + } + if (comparison < 0) { + // Perform a swap + isSorted = false; + fFields.setElementAt(categ2, i*4 + 0); + fFields.setElementAt(field2, i*4 + 1); + fFields.setElementAt(start2, i*4 + 2); + fFields.setElementAt(limit2, i*4 + 3); + fFields.setElementAt(categ1, i*4 + 4); + fFields.setElementAt(field1, i*4 + 5); + fFields.setElementAt(start1, i*4 + 6); + fFields.setElementAt(limit1, i*4 + 7); + } + } + if (isSorted) { + break; + } + } +} + + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_FORMATTING */