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