// © 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 #include "unicode/formattedvalue.h" #include "formattedval_impl.h" #include "capi_helper.h" U_NAMESPACE_BEGIN ConstrainedFieldPosition::ConstrainedFieldPosition() {} ConstrainedFieldPosition::~ConstrainedFieldPosition() {} void ConstrainedFieldPosition::reset() { fContext = 0LL; fField = 0; fStart = 0; fLimit = 0; fConstraint = UCFPOS_CONSTRAINT_NONE; fCategory = UFIELD_CATEGORY_UNDEFINED; } void ConstrainedFieldPosition::constrainCategory(int32_t category) { fConstraint = UCFPOS_CONSTRAINT_CATEGORY; fCategory = category; } void ConstrainedFieldPosition::constrainField(int32_t category, int32_t field) { fConstraint = UCFPOS_CONSTRAINT_FIELD; fCategory = category; fField = field; } void ConstrainedFieldPosition::setInt64IterationContext(int64_t context) { fContext = context; } UBool ConstrainedFieldPosition::matchesField(int32_t category, int32_t field) const { switch (fConstraint) { case UCFPOS_CONSTRAINT_NONE: return true; case UCFPOS_CONSTRAINT_CATEGORY: return fCategory == category; case UCFPOS_CONSTRAINT_FIELD: return fCategory == category && fField == field; default: UPRV_UNREACHABLE_EXIT; } } void ConstrainedFieldPosition::setState( int32_t category, int32_t field, int32_t start, int32_t limit) { fCategory = category; fField = field; fStart = start; fLimit = limit; } FormattedValue::~FormattedValue() = default; /////////////////////// /// C API FUNCTIONS /// /////////////////////// struct UConstrainedFieldPositionImpl : public UMemory, // Magic number as ASCII == "UCF" public IcuCApiHelper { ConstrainedFieldPosition fImpl; }; U_CAPI UConstrainedFieldPosition* U_EXPORT2 ucfpos_open(UErrorCode* ec) { auto* impl = new UConstrainedFieldPositionImpl(); if (impl == nullptr) { *ec = U_MEMORY_ALLOCATION_ERROR; return nullptr; } return impl->exportForC(); } U_CAPI void U_EXPORT2 ucfpos_reset(UConstrainedFieldPosition* ptr, UErrorCode* ec) { auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return; } impl->fImpl.reset(); } U_CAPI void U_EXPORT2 ucfpos_constrainCategory(UConstrainedFieldPosition* ptr, int32_t category, UErrorCode* ec) { auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return; } impl->fImpl.constrainCategory(category); } U_CAPI void U_EXPORT2 ucfpos_constrainField(UConstrainedFieldPosition* ptr, int32_t category, int32_t field, UErrorCode* ec) { auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return; } impl->fImpl.constrainField(category, field); } U_CAPI int32_t U_EXPORT2 ucfpos_getCategory(const UConstrainedFieldPosition* ptr, UErrorCode* ec) { const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return UFIELD_CATEGORY_UNDEFINED; } return impl->fImpl.getCategory(); } U_CAPI int32_t U_EXPORT2 ucfpos_getField(const UConstrainedFieldPosition* ptr, UErrorCode* ec) { const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return 0; } return impl->fImpl.getField(); } U_CAPI void U_EXPORT2 ucfpos_getIndexes(const UConstrainedFieldPosition* ptr, int32_t* pStart, int32_t* pLimit, UErrorCode* ec) { const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return; } *pStart = impl->fImpl.getStart(); *pLimit = impl->fImpl.getLimit(); } U_CAPI int64_t U_EXPORT2 ucfpos_getInt64IterationContext(const UConstrainedFieldPosition* ptr, UErrorCode* ec) { const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return 0; } return impl->fImpl.getInt64IterationContext(); } U_CAPI void U_EXPORT2 ucfpos_setInt64IterationContext(UConstrainedFieldPosition* ptr, int64_t context, UErrorCode* ec) { auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return; } impl->fImpl.setInt64IterationContext(context); } U_CAPI UBool U_EXPORT2 ucfpos_matchesField(const UConstrainedFieldPosition* ptr, int32_t category, int32_t field, UErrorCode* ec) { const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return 0; } return impl->fImpl.matchesField(category, field); } U_CAPI void U_EXPORT2 ucfpos_setState( UConstrainedFieldPosition* ptr, int32_t category, int32_t field, int32_t start, int32_t limit, UErrorCode* ec) { auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); if (U_FAILURE(*ec)) { return; } impl->fImpl.setState(category, field, start, limit); } U_CAPI void U_EXPORT2 ucfpos_close(UConstrainedFieldPosition* ptr) { UErrorCode localStatus = U_ZERO_ERROR; auto* impl = UConstrainedFieldPositionImpl::validate(ptr, localStatus); delete impl; } U_CAPI const char16_t* U_EXPORT2 ufmtval_getString( const UFormattedValue* ufmtval, int32_t* pLength, UErrorCode* ec) { const auto* impl = UFormattedValueApiHelper::validate(ufmtval, *ec); if (U_FAILURE(*ec)) { return nullptr; } UnicodeString readOnlyAlias = impl->fFormattedValue->toTempString(*ec); if (U_FAILURE(*ec)) { return nullptr; } if (pLength != nullptr) { *pLength = readOnlyAlias.length(); } // Note: this line triggers -Wreturn-local-addr, but it is safe because toTempString is // defined to return memory owned by the ufmtval argument. return readOnlyAlias.getBuffer(); } U_CAPI UBool U_EXPORT2 ufmtval_nextPosition( const UFormattedValue* ufmtval, UConstrainedFieldPosition* ucfpos, UErrorCode* ec) { const auto* fmtval = UFormattedValueApiHelper::validate(ufmtval, *ec); auto* cfpos = UConstrainedFieldPositionImpl::validate(ucfpos, *ec); if (U_FAILURE(*ec)) { return false; } return fmtval->fFormattedValue->nextPosition(cfpos->fImpl, *ec); } U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */