235 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| // © 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<UConstrainedFieldPosition, UConstrainedFieldPositionImpl, 0x55434600> {
 | |
|     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 UChar* 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 */
 |