1// © 2018 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3
4#ifndef __UFORMATTEDVALUE_H__
5#define __UFORMATTEDVALUE_H__
6
7#include "unicode/utypes.h"
8
9#if !UCONFIG_NO_FORMATTING
10
11#include "unicode/ufieldpositer.h"
12
13/**
14 * \file
15 * \brief C API: Abstract operations for localized strings.
16 *
17 * This file contains declarations for classes that deal with formatted strings. A number
18 * of APIs throughout ICU use these classes for expressing their localized output.
19 */
20
21
22/**
23 * All possible field categories in ICU. Every entry in this enum corresponds
24 * to another enum that exists in ICU.
25 *
26 * In the APIs that take a UFieldCategory, an int32_t type is used. Field
27 * categories having any of the top four bits turned on are reserved as
28 * private-use for external APIs implementing FormattedValue. This means that
29 * categories 2^28 and higher or below zero (with the highest bit turned on)
30 * are private-use and will not be used by ICU in the future.
31 *
32 * @stable ICU 64
33 */
34typedef enum UFieldCategory {
35 /**
36 * For an undefined field category.
37 *
38 * @stable ICU 64
39 */
40 UFIELD_CATEGORY_UNDEFINED = 0,
41
42 /**
43 * For fields in UDateFormatField (udat.h), from ICU 3.0.
44 *
45 * @stable ICU 64
46 */
47 UFIELD_CATEGORY_DATE,
48
49 /**
50 * For fields in UNumberFormatFields (unum.h), from ICU 49.
51 *
52 * @stable ICU 64
53 */
54 UFIELD_CATEGORY_NUMBER,
55
56 /**
57 * For fields in UListFormatterField (ulistformatter.h), from ICU 63.
58 *
59 * @stable ICU 64
60 */
61 UFIELD_CATEGORY_LIST,
62
63 /**
64 * For fields in URelativeDateTimeFormatterField (ureldatefmt.h), from ICU 64.
65 *
66 * @stable ICU 64
67 */
68 UFIELD_CATEGORY_RELATIVE_DATETIME,
69
70 /**
71 * Reserved for possible future fields in UDateIntervalFormatField.
72 *
73 * @internal
74 */
75 UFIELD_CATEGORY_DATE_INTERVAL,
76
77#ifndef U_HIDE_INTERNAL_API
78 /** @internal */
79 UFIELD_CATEGORY_COUNT,
80#endif /* U_HIDE_INTERNAL_API */
81
82 /**
83 * Category for spans in a list.
84 *
85 * @stable ICU 64
86 */
87 UFIELD_CATEGORY_LIST_SPAN = 0x1000 + UFIELD_CATEGORY_LIST,
88
89 /**
90 * Category for spans in a date interval.
91 *
92 * @stable ICU 64
93 */
94 UFIELD_CATEGORY_DATE_INTERVAL_SPAN = 0x1000 + UFIELD_CATEGORY_DATE_INTERVAL,
95
96} UFieldCategory;
97
98
99struct UConstrainedFieldPosition;
100/**
101 * Represents a span of a string containing a given field.
102 *
103 * This struct differs from UFieldPosition in the following ways:
104 *
105 * 1. It has information on the field category.
106 * 2. It allows you to set constraints to use when iterating over field positions.
107 * 3. It is used for the newer FormattedValue APIs.
108 *
109 * @stable ICU 64
110 */
111typedef struct UConstrainedFieldPosition UConstrainedFieldPosition;
112
113
114/**
115 * Creates a new UConstrainedFieldPosition.
116 *
117 * By default, the UConstrainedFieldPosition has no iteration constraints.
118 *
119 * @param ec Set if an error occurs.
120 * @return The new object, or NULL if an error occurs.
121 * @stable ICU 64
122 */
123U_STABLE UConstrainedFieldPosition* U_EXPORT2
124ucfpos_open(UErrorCode* ec);
125
126
127/**
128 * Resets a UConstrainedFieldPosition to its initial state, as if it were newly created.
129 *
130 * Removes any constraints that may have been set on the instance.
131 *
132 * @param ucfpos The instance of UConstrainedFieldPosition.
133 * @param ec Set if an error occurs.
134 * @stable ICU 64
135 */
136U_STABLE void U_EXPORT2
137ucfpos_reset(
138 UConstrainedFieldPosition* ucfpos,
139 UErrorCode* ec);
140
141
142/**
143 * Destroys a UConstrainedFieldPosition and releases its memory.
144 *
145 * @param ucfpos The instance of UConstrainedFieldPosition.
146 * @stable ICU 64
147 */
148U_STABLE void U_EXPORT2
149ucfpos_close(UConstrainedFieldPosition* ucfpos);
150
151
152/**
153 * Sets a constraint on the field category.
154 *
155 * When this instance of UConstrainedFieldPosition is passed to ufmtval_nextPosition,
156 * positions are skipped unless they have the given category.
157 *
158 * Any previously set constraints are cleared.
159 *
160 * For example, to loop over only the number-related fields:
161 *
162 * UConstrainedFieldPosition* ucfpos = ucfpos_open(ec);
163 * ucfpos_constrainCategory(ucfpos, UFIELDCATEGORY_NUMBER_FORMAT, ec);
164 * while (ufmtval_nextPosition(ufmtval, ucfpos, ec)) {
165 * // handle the number-related field position
166 * }
167 * ucfpos_close(ucfpos);
168 *
169 * Changing the constraint while in the middle of iterating over a FormattedValue
170 * does not generally have well-defined behavior.
171 *
172 * @param ucfpos The instance of UConstrainedFieldPosition.
173 * @param category The field category to fix when iterating.
174 * @param ec Set if an error occurs.
175 * @stable ICU 64
176 */
177U_STABLE void U_EXPORT2
178ucfpos_constrainCategory(
179 UConstrainedFieldPosition* ucfpos,
180 int32_t category,
181 UErrorCode* ec);
182
183
184/**
185 * Sets a constraint on the category and field.
186 *
187 * When this instance of UConstrainedFieldPosition is passed to ufmtval_nextPosition,
188 * positions are skipped unless they have the given category and field.
189 *
190 * Any previously set constraints are cleared.
191 *
192 * For example, to loop over all grouping separators:
193 *
194 * UConstrainedFieldPosition* ucfpos = ucfpos_open(ec);
195 * ucfpos_constrainField(ucfpos, UFIELDCATEGORY_NUMBER_FORMAT, UNUM_GROUPING_SEPARATOR_FIELD, ec);
196 * while (ufmtval_nextPosition(ufmtval, ucfpos, ec)) {
197 * // handle the grouping separator position
198 * }
199 * ucfpos_close(ucfpos);
200 *
201 * Changing the constraint while in the middle of iterating over a FormattedValue
202 * does not generally have well-defined behavior.
203 *
204 * @param ucfpos The instance of UConstrainedFieldPosition.
205 * @param category The field category to fix when iterating.
206 * @param field The field to fix when iterating.
207 * @param ec Set if an error occurs.
208 * @stable ICU 64
209 */
210U_STABLE void U_EXPORT2
211ucfpos_constrainField(
212 UConstrainedFieldPosition* ucfpos,
213 int32_t category,
214 int32_t field,
215 UErrorCode* ec);
216
217
218/**
219 * Gets the field category for the current position.
220 *
221 * If a category or field constraint was set, this function returns the constrained
222 * category. Otherwise, the return value is well-defined only after
223 * ufmtval_nextPosition returns TRUE.
224 *
225 * @param ucfpos The instance of UConstrainedFieldPosition.
226 * @param ec Set if an error occurs.
227 * @return The field category saved in the instance.
228 * @stable ICU 64
229 */
230U_STABLE int32_t U_EXPORT2
231ucfpos_getCategory(
232 const UConstrainedFieldPosition* ucfpos,
233 UErrorCode* ec);
234
235
236/**
237 * Gets the field for the current position.
238 *
239 * If a field constraint was set, this function returns the constrained
240 * field. Otherwise, the return value is well-defined only after
241 * ufmtval_nextPosition returns TRUE.
242 *
243 * @param ucfpos The instance of UConstrainedFieldPosition.
244 * @param ec Set if an error occurs.
245 * @return The field saved in the instance.
246 * @stable ICU 64
247 */
248U_STABLE int32_t U_EXPORT2
249ucfpos_getField(
250 const UConstrainedFieldPosition* ucfpos,
251 UErrorCode* ec);
252
253
254/**
255 * Gets the INCLUSIVE start and EXCLUSIVE end index stored for the current position.
256 *
257 * The output values are well-defined only after ufmtval_nextPosition returns TRUE.
258 *
259 * @param ucfpos The instance of UConstrainedFieldPosition.
260 * @param pStart Set to the start index saved in the instance. Ignored if nullptr.
261 * @param pLimit Set to the end index saved in the instance. Ignored if nullptr.
262 * @param ec Set if an error occurs.
263 * @stable ICU 64
264 */
265U_STABLE void U_EXPORT2
266ucfpos_getIndexes(
267 const UConstrainedFieldPosition* ucfpos,
268 int32_t* pStart,
269 int32_t* pLimit,
270 UErrorCode* ec);
271
272
273/**
274 * Gets an int64 that FormattedValue implementations may use for storage.
275 *
276 * The initial value is zero.
277 *
278 * Users of FormattedValue should not need to call this method.
279 *
280 * @param ucfpos The instance of UConstrainedFieldPosition.
281 * @param ec Set if an error occurs.
282 * @return The current iteration context from ucfpos_setInt64IterationContext.
283 * @stable ICU 64
284 */
285U_STABLE int64_t U_EXPORT2
286ucfpos_getInt64IterationContext(
287 const UConstrainedFieldPosition* ucfpos,
288 UErrorCode* ec);
289
290
291/**
292 * Sets an int64 that FormattedValue implementations may use for storage.
293 *
294 * Intended to be used by FormattedValue implementations.
295 *
296 * @param ucfpos The instance of UConstrainedFieldPosition.
297 * @param context The new iteration context.
298 * @param ec Set if an error occurs.
299 * @stable ICU 64
300 */
301U_STABLE void U_EXPORT2
302ucfpos_setInt64IterationContext(
303 UConstrainedFieldPosition* ucfpos,
304 int64_t context,
305 UErrorCode* ec);
306
307
308/**
309 * Determines whether a given field should be included given the
310 * constraints.
311 *
312 * Intended to be used by FormattedValue implementations.
313 *
314 * @param ucfpos The instance of UConstrainedFieldPosition.
315 * @param category The category to test.
316 * @param field The field to test.
317 * @param ec Set if an error occurs.
318 * @stable ICU 64
319 */
320U_STABLE UBool U_EXPORT2
321ucfpos_matchesField(
322 const UConstrainedFieldPosition* ucfpos,
323 int32_t category,
324 int32_t field,
325 UErrorCode* ec);
326
327
328/**
329 * Sets new values for the primary public getters.
330 *
331 * Intended to be used by FormattedValue implementations.
332 *
333 * It is up to the implementation to ensure that the user-requested
334 * constraints are satisfied. This method does not check!
335 *
336 * @param ucfpos The instance of UConstrainedFieldPosition.
337 * @param category The new field category.
338 * @param field The new field.
339 * @param start The new inclusive start index.
340 * @param limit The new exclusive end index.
341 * @param ec Set if an error occurs.
342 * @stable ICU 64
343 */
344U_STABLE void U_EXPORT2
345ucfpos_setState(
346 UConstrainedFieldPosition* ucfpos,
347 int32_t category,
348 int32_t field,
349 int32_t start,
350 int32_t limit,
351 UErrorCode* ec);
352
353
354struct UFormattedValue;
355/**
356 * An abstract formatted value: a string with associated field attributes.
357 * Many formatters format to types compatible with UFormattedValue.
358 *
359 * @stable ICU 64
360 */
361typedef struct UFormattedValue UFormattedValue;
362
363
364/**
365 * Returns a pointer to the formatted string. The pointer is owned by the UFormattedValue. The
366 * return value is valid only as long as the UFormattedValue is present and unchanged in memory.
367 *
368 * The return value is NUL-terminated but could contain internal NULs.
369 *
370 * @param ufmtval
371 * The object containing the formatted string and attributes.
372 * @param pLength Output variable for the length of the string. Ignored if NULL.
373 * @param ec Set if an error occurs.
374 * @return A NUL-terminated char16 string owned by the UFormattedValue.
375 * @stable ICU 64
376 */
377U_STABLE const UChar* U_EXPORT2
378ufmtval_getString(
379 const UFormattedValue* ufmtval,
380 int32_t* pLength,
381 UErrorCode* ec);
382
383
384/**
385 * Iterates over field positions in the UFormattedValue. This lets you determine the position
386 * of specific types of substrings, like a month or a decimal separator.
387 *
388 * To loop over all field positions:
389 *
390 * UConstrainedFieldPosition* ucfpos = ucfpos_open(ec);
391 * while (ufmtval_nextPosition(ufmtval, ucfpos, ec)) {
392 * // handle the field position; get information from ucfpos
393 * }
394 * ucfpos_close(ucfpos);
395 *
396 * @param ufmtval
397 * The object containing the formatted string and attributes.
398 * @param ucfpos
399 * The object used for iteration state; can provide constraints to iterate over only
400 * one specific category or field;
401 * see ucfpos_constrainCategory
402 * and ucfpos_constrainField.
403 * @param ec Set if an error occurs.
404 * @return TRUE if another position was found; FALSE otherwise.
405 * @stable ICU 64
406 */
407U_STABLE UBool U_EXPORT2
408ufmtval_nextPosition(
409 const UFormattedValue* ufmtval,
410 UConstrainedFieldPosition* ucfpos,
411 UErrorCode* ec);
412
413
414#if U_SHOW_CPLUSPLUS_API
415U_NAMESPACE_BEGIN
416
417/**
418 * \class LocalUConstrainedFieldPositionPointer
419 * "Smart pointer" class; closes a UConstrainedFieldPosition via ucfpos_close().
420 * For most methods see the LocalPointerBase base class.
421 *
422 * Usage:
423 *
424 * LocalUConstrainedFieldPositionPointer ucfpos(ucfpos_open(ec));
425 * // no need to explicitly call ucfpos_close()
426 *
427 * @stable ICU 64
428 */
429U_DEFINE_LOCAL_OPEN_POINTER(LocalUConstrainedFieldPositionPointer,
430 UConstrainedFieldPosition,
431 ucfpos_close);
432
433U_NAMESPACE_END
434#endif // U_SHOW_CPLUSPLUS_API
435
436
437#endif /* #if !UCONFIG_NO_FORMATTING */
438#endif // __UFORMATTEDVALUE_H__
439