formattedvalue.cpp (6875B)
1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #include "unicode/utypes.h" 5 6 #if !UCONFIG_NO_FORMATTING 7 8 #include "unicode/formattedvalue.h" 9 #include "formattedval_impl.h" 10 #include "capi_helper.h" 11 12 U_NAMESPACE_BEGIN 13 14 15 ConstrainedFieldPosition::ConstrainedFieldPosition() {} 16 17 ConstrainedFieldPosition::~ConstrainedFieldPosition() {} 18 19 void ConstrainedFieldPosition::reset() { 20 fContext = 0LL; 21 fField = 0; 22 fStart = 0; 23 fLimit = 0; 24 fConstraint = UCFPOS_CONSTRAINT_NONE; 25 fCategory = UFIELD_CATEGORY_UNDEFINED; 26 } 27 28 void ConstrainedFieldPosition::constrainCategory(int32_t category) { 29 fConstraint = UCFPOS_CONSTRAINT_CATEGORY; 30 fCategory = category; 31 } 32 33 void ConstrainedFieldPosition::constrainField(int32_t category, int32_t field) { 34 fConstraint = UCFPOS_CONSTRAINT_FIELD; 35 fCategory = category; 36 fField = field; 37 } 38 39 void ConstrainedFieldPosition::setInt64IterationContext(int64_t context) { 40 fContext = context; 41 } 42 43 UBool ConstrainedFieldPosition::matchesField(int32_t category, int32_t field) const { 44 switch (fConstraint) { 45 case UCFPOS_CONSTRAINT_NONE: 46 return true; 47 case UCFPOS_CONSTRAINT_CATEGORY: 48 return fCategory == category; 49 case UCFPOS_CONSTRAINT_FIELD: 50 return fCategory == category && fField == field; 51 default: 52 UPRV_UNREACHABLE_EXIT; 53 } 54 } 55 56 void ConstrainedFieldPosition::setState( 57 int32_t category, 58 int32_t field, 59 int32_t start, 60 int32_t limit) { 61 fCategory = category; 62 fField = field; 63 fStart = start; 64 fLimit = limit; 65 } 66 67 68 FormattedValue::~FormattedValue() = default; 69 70 71 /////////////////////// 72 /// C API FUNCTIONS /// 73 /////////////////////// 74 75 struct UConstrainedFieldPositionImpl : public UMemory, 76 // Magic number as ASCII == "UCF" 77 public IcuCApiHelper<UConstrainedFieldPosition, UConstrainedFieldPositionImpl, 0x55434600> { 78 ConstrainedFieldPosition fImpl; 79 }; 80 81 U_CAPI UConstrainedFieldPosition* U_EXPORT2 82 ucfpos_open(UErrorCode* ec) { 83 auto* impl = new UConstrainedFieldPositionImpl(); 84 if (impl == nullptr) { 85 *ec = U_MEMORY_ALLOCATION_ERROR; 86 return nullptr; 87 } 88 return impl->exportForC(); 89 } 90 91 U_CAPI void U_EXPORT2 92 ucfpos_reset(UConstrainedFieldPosition* ptr, UErrorCode* ec) { 93 auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 94 if (U_FAILURE(*ec)) { 95 return; 96 } 97 impl->fImpl.reset(); 98 } 99 100 U_CAPI void U_EXPORT2 101 ucfpos_constrainCategory(UConstrainedFieldPosition* ptr, int32_t category, UErrorCode* ec) { 102 auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 103 if (U_FAILURE(*ec)) { 104 return; 105 } 106 impl->fImpl.constrainCategory(category); 107 } 108 109 U_CAPI void U_EXPORT2 110 ucfpos_constrainField(UConstrainedFieldPosition* ptr, int32_t category, int32_t field, UErrorCode* ec) { 111 auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 112 if (U_FAILURE(*ec)) { 113 return; 114 } 115 impl->fImpl.constrainField(category, field); 116 } 117 118 U_CAPI int32_t U_EXPORT2 119 ucfpos_getCategory(const UConstrainedFieldPosition* ptr, UErrorCode* ec) { 120 const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 121 if (U_FAILURE(*ec)) { 122 return UFIELD_CATEGORY_UNDEFINED; 123 } 124 return impl->fImpl.getCategory(); 125 } 126 127 U_CAPI int32_t U_EXPORT2 128 ucfpos_getField(const UConstrainedFieldPosition* ptr, UErrorCode* ec) { 129 const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 130 if (U_FAILURE(*ec)) { 131 return 0; 132 } 133 return impl->fImpl.getField(); 134 } 135 136 U_CAPI void U_EXPORT2 137 ucfpos_getIndexes(const UConstrainedFieldPosition* ptr, int32_t* pStart, int32_t* pLimit, UErrorCode* ec) { 138 const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 139 if (U_FAILURE(*ec)) { 140 return; 141 } 142 *pStart = impl->fImpl.getStart(); 143 *pLimit = impl->fImpl.getLimit(); 144 } 145 146 U_CAPI int64_t U_EXPORT2 147 ucfpos_getInt64IterationContext(const UConstrainedFieldPosition* ptr, UErrorCode* ec) { 148 const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 149 if (U_FAILURE(*ec)) { 150 return 0; 151 } 152 return impl->fImpl.getInt64IterationContext(); 153 } 154 155 U_CAPI void U_EXPORT2 156 ucfpos_setInt64IterationContext(UConstrainedFieldPosition* ptr, int64_t context, UErrorCode* ec) { 157 auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 158 if (U_FAILURE(*ec)) { 159 return; 160 } 161 impl->fImpl.setInt64IterationContext(context); 162 } 163 164 U_CAPI UBool U_EXPORT2 165 ucfpos_matchesField(const UConstrainedFieldPosition* ptr, int32_t category, int32_t field, UErrorCode* ec) { 166 const auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 167 if (U_FAILURE(*ec)) { 168 return 0; 169 } 170 return impl->fImpl.matchesField(category, field); 171 } 172 173 U_CAPI void U_EXPORT2 174 ucfpos_setState( 175 UConstrainedFieldPosition* ptr, 176 int32_t category, 177 int32_t field, 178 int32_t start, 179 int32_t limit, 180 UErrorCode* ec) { 181 auto* impl = UConstrainedFieldPositionImpl::validate(ptr, *ec); 182 if (U_FAILURE(*ec)) { 183 return; 184 } 185 impl->fImpl.setState(category, field, start, limit); 186 } 187 188 U_CAPI void U_EXPORT2 189 ucfpos_close(UConstrainedFieldPosition* ptr) { 190 UErrorCode localStatus = U_ZERO_ERROR; 191 auto* impl = UConstrainedFieldPositionImpl::validate(ptr, localStatus); 192 delete impl; 193 } 194 195 196 // -Wreturn-local-addr first found in https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Warning-Options.html#Warning-Options 197 #if U_GCC_MAJOR_MINOR >= 409 198 #pragma GCC diagnostic push 199 #pragma GCC diagnostic ignored "-Wreturn-local-addr" 200 #endif 201 U_CAPI const char16_t* U_EXPORT2 202 ufmtval_getString( 203 const UFormattedValue* ufmtval, 204 int32_t* pLength, 205 UErrorCode* ec) { 206 const auto* impl = UFormattedValueApiHelper::validate(ufmtval, *ec); 207 if (U_FAILURE(*ec)) { 208 return nullptr; 209 } 210 UnicodeString readOnlyAlias = impl->fFormattedValue->toTempString(*ec); 211 if (U_FAILURE(*ec)) { 212 return nullptr; 213 } 214 if (pLength != nullptr) { 215 *pLength = readOnlyAlias.length(); 216 } 217 // Note: this line triggers -Wreturn-local-addr, but it is safe because toTempString is 218 // defined to return memory owned by the ufmtval argument. 219 return readOnlyAlias.getBuffer(); 220 } 221 #if U_GCC_MAJOR_MINOR >= 409 222 #pragma GCC diagnostic pop 223 #endif 224 225 226 U_CAPI UBool U_EXPORT2 227 ufmtval_nextPosition( 228 const UFormattedValue* ufmtval, 229 UConstrainedFieldPosition* ucfpos, 230 UErrorCode* ec) { 231 const auto* fmtval = UFormattedValueApiHelper::validate(ufmtval, *ec); 232 auto* cfpos = UConstrainedFieldPositionImpl::validate(ucfpos, *ec); 233 if (U_FAILURE(*ec)) { 234 return false; 235 } 236 return fmtval->fFormattedValue->nextPosition(cfpos->fImpl, *ec); 237 } 238 239 240 U_NAMESPACE_END 241 242 #endif /* #if !UCONFIG_NO_FORMATTING */