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  */
34 typedef 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 
99 struct 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  */
111 typedef 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  */
123 U_CAPI UConstrainedFieldPosition* U_EXPORT2
124 ucfpos_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  */
136 U_CAPI void U_EXPORT2
137 ucfpos_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  */
148 U_CAPI void U_EXPORT2
149 ucfpos_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  */
177 U_CAPI void U_EXPORT2
178 ucfpos_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  */
210 U_CAPI void U_EXPORT2
211 ucfpos_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  */
230 U_CAPI int32_t U_EXPORT2
231 ucfpos_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  */
248 U_CAPI int32_t U_EXPORT2
249 ucfpos_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  */
265 U_CAPI void U_EXPORT2
266 ucfpos_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  */
285 U_CAPI int64_t U_EXPORT2
286 ucfpos_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  */
301 U_CAPI void U_EXPORT2
302 ucfpos_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  */
320 U_CAPI UBool U_EXPORT2
321 ucfpos_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  */
344 U_CAPI void U_EXPORT2
345 ucfpos_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 
354 struct 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  */
361 typedef 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  */
377 U_CAPI const UChar* U_EXPORT2
378 ufmtval_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  */
407 U_CAPI UBool U_EXPORT2
408 ufmtval_nextPosition(
409     const UFormattedValue* ufmtval,
410     UConstrainedFieldPosition* ucfpos,
411     UErrorCode* ec);
412 
413 
414 #if U_SHOW_CPLUSPLUS_API
415 U_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  */
429 U_DEFINE_LOCAL_OPEN_POINTER(LocalUConstrainedFieldPositionPointer,
430     UConstrainedFieldPosition,
431     ucfpos_close);
432 
433 U_NAMESPACE_END
434 #endif // U_SHOW_CPLUSPLUS_API
435 
436 
437 #endif /* #if !UCONFIG_NO_FORMATTING */
438 #endif // __UFORMATTEDVALUE_H__
439