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 | #include "unicode/utypes.h" |
11 | |
12 | #if !UCONFIG_NO_FORMATTING |
13 | |
14 | #include "fphdlimp.h" |
15 | #include "uvectr32.h" |
16 | |
17 | U_NAMESPACE_BEGIN |
18 | |
19 | // utility FieldPositionHandler |
20 | // base class, null implementation |
21 | |
22 | FieldPositionHandler::~FieldPositionHandler() { |
23 | } |
24 | |
25 | void FieldPositionHandler::setShift(int32_t delta) { |
26 | fShift = delta; |
27 | } |
28 | |
29 | |
30 | // utility subclass FieldPositionOnlyHandler |
31 | |
32 | FieldPositionOnlyHandler::FieldPositionOnlyHandler(FieldPosition& _pos) |
33 | : pos(_pos) { |
34 | } |
35 | |
36 | FieldPositionOnlyHandler::~FieldPositionOnlyHandler() { |
37 | } |
38 | |
39 | void |
40 | FieldPositionOnlyHandler::addAttribute(int32_t id, int32_t start, int32_t limit) { |
41 | if (pos.getField() == id && (!acceptFirstOnly || !seenFirst)) { |
42 | seenFirst = TRUE; |
43 | pos.setBeginIndex(start + fShift); |
44 | pos.setEndIndex(limit + fShift); |
45 | } |
46 | } |
47 | |
48 | void |
49 | FieldPositionOnlyHandler::shiftLast(int32_t delta) { |
50 | if (delta != 0 && pos.getField() != FieldPosition::DONT_CARE && pos.getBeginIndex() != -1) { |
51 | pos.setBeginIndex(delta + pos.getBeginIndex()); |
52 | pos.setEndIndex(delta + pos.getEndIndex()); |
53 | } |
54 | } |
55 | |
56 | UBool |
57 | FieldPositionOnlyHandler::isRecording(void) const { |
58 | return pos.getField() != FieldPosition::DONT_CARE; |
59 | } |
60 | |
61 | void FieldPositionOnlyHandler::setAcceptFirstOnly(UBool acceptFirstOnly) { |
62 | this->acceptFirstOnly = acceptFirstOnly; |
63 | } |
64 | |
65 | |
66 | // utility subclass FieldPositionIteratorHandler |
67 | |
68 | FieldPositionIteratorHandler::FieldPositionIteratorHandler(FieldPositionIterator* posIter, |
69 | UErrorCode& _status) |
70 | : iter(posIter), vec(NULL), status(_status), fCategory(UFIELD_CATEGORY_UNDEFINED) { |
71 | if (iter && U_SUCCESS(status)) { |
72 | vec = new UVector32(status); |
73 | } |
74 | } |
75 | |
76 | FieldPositionIteratorHandler::FieldPositionIteratorHandler( |
77 | UVector32* vec, |
78 | UErrorCode& status) |
79 | : iter(nullptr), vec(vec), status(status), fCategory(UFIELD_CATEGORY_UNDEFINED) { |
80 | } |
81 | |
82 | FieldPositionIteratorHandler::~FieldPositionIteratorHandler() { |
83 | // setData adopts the vec regardless of status, so it's safe to null it |
84 | if (iter) { |
85 | iter->setData(vec, status); |
86 | } |
87 | // if iter is null, we never allocated vec, so no need to free it |
88 | vec = NULL; |
89 | } |
90 | |
91 | void |
92 | FieldPositionIteratorHandler::addAttribute(int32_t id, int32_t start, int32_t limit) { |
93 | if (vec && U_SUCCESS(status) && start < limit) { |
94 | int32_t size = vec->size(); |
95 | vec->addElement(fCategory, status); |
96 | vec->addElement(id, status); |
97 | vec->addElement(start + fShift, status); |
98 | vec->addElement(limit + fShift, status); |
99 | if (!U_SUCCESS(status)) { |
100 | vec->setSize(size); |
101 | } |
102 | } |
103 | } |
104 | |
105 | void |
106 | FieldPositionIteratorHandler::shiftLast(int32_t delta) { |
107 | if (U_SUCCESS(status) && delta != 0) { |
108 | int32_t i = vec->size(); |
109 | if (i > 0) { |
110 | --i; |
111 | vec->setElementAt(delta + vec->elementAti(i), i); |
112 | --i; |
113 | vec->setElementAt(delta + vec->elementAti(i), i); |
114 | } |
115 | } |
116 | } |
117 | |
118 | UBool |
119 | FieldPositionIteratorHandler::isRecording(void) const { |
120 | return U_SUCCESS(status); |
121 | } |
122 | |
123 | U_NAMESPACE_END |
124 | |
125 | #endif /* !UCONFIG_NO_FORMATTING */ |
126 | |