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