1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4*******************************************************************************
5* Copyright (C) 2009-2015, International Business Machines Corporation and *
6* others. All Rights Reserved. *
7*******************************************************************************
8*/
9
10#ifndef FPHDLIMP_H
11#define FPHDLIMP_H
12
13#include "unicode/utypes.h"
14
15#if !UCONFIG_NO_FORMATTING
16
17#include "unicode/fieldpos.h"
18#include "unicode/fpositer.h"
19#include "unicode/formattedvalue.h"
20
21U_NAMESPACE_BEGIN
22
23// utility FieldPositionHandler
24// base class, null implementation
25
26class U_I18N_API FieldPositionHandler: public UMemory {
27 protected:
28 int32_t fShift = 0;
29
30 public:
31 virtual ~FieldPositionHandler();
32 virtual void addAttribute(int32_t id, int32_t start, int32_t limit) = 0;
33 virtual void shiftLast(int32_t delta) = 0;
34 virtual UBool isRecording(void) const = 0;
35
36 void setShift(int32_t delta);
37};
38
39
40// utility subclass FieldPositionOnlyHandler
41
42class FieldPositionOnlyHandler : public FieldPositionHandler {
43 FieldPosition& pos;
44 UBool acceptFirstOnly = FALSE;
45 UBool seenFirst = FALSE;
46
47 public:
48 FieldPositionOnlyHandler(FieldPosition& pos);
49 virtual ~FieldPositionOnlyHandler();
50
51 void addAttribute(int32_t id, int32_t start, int32_t limit) U_OVERRIDE;
52 void shiftLast(int32_t delta) U_OVERRIDE;
53 UBool isRecording(void) const U_OVERRIDE;
54
55 /**
56 * Enable this option to lock in the FieldPosition value after seeing the
57 * first occurrence of the field. The default behavior is to take the last
58 * occurrence.
59 */
60 void setAcceptFirstOnly(UBool acceptFirstOnly);
61};
62
63
64// utility subclass FieldPositionIteratorHandler
65
66class FieldPositionIteratorHandler : public FieldPositionHandler {
67 FieldPositionIterator* iter; // can be NULL
68 UVector32* vec;
69 UErrorCode status;
70 UFieldCategory fCategory;
71
72 // Note, we keep a reference to status, so if status is on the stack, we have
73 // to be destroyed before status goes out of scope. Easiest thing is to
74 // allocate us on the stack in the same (or narrower) scope as status has.
75 // This attempts to encourage that by blocking heap allocation.
76 static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete;
77 static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete;
78#if U_HAVE_PLACEMENT_NEW
79 static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete;
80#endif
81
82 public:
83 FieldPositionIteratorHandler(FieldPositionIterator* posIter, UErrorCode& status);
84 /** If using this constructor, you must call getError() when done formatting! */
85 FieldPositionIteratorHandler(UVector32* vec, UErrorCode& status);
86 ~FieldPositionIteratorHandler();
87
88 void addAttribute(int32_t id, int32_t start, int32_t limit) U_OVERRIDE;
89 void shiftLast(int32_t delta) U_OVERRIDE;
90 UBool isRecording(void) const U_OVERRIDE;
91
92 /** Copies a failed error code into _status. */
93 inline void getError(UErrorCode& _status) {
94 if (U_SUCCESS(_status) && U_FAILURE(status)) {
95 _status = status;
96 }
97 }
98
99 inline void setCategory(UFieldCategory category) {
100 fCategory = category;
101 }
102};
103
104U_NAMESPACE_END
105
106#endif /* !UCONFIG_NO_FORMATTING */
107
108#endif /* FPHDLIMP_H */
109