xref: /aosp_15_r20/external/icu/icu4c/source/i18n/fpositer.cpp (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker /*
4*0e209d39SAndroid Build Coastguard Worker ******************************************************************************
5*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 2009-2012, International Business Machines Corporation and
6*0e209d39SAndroid Build Coastguard Worker * others. All Rights Reserved.
7*0e209d39SAndroid Build Coastguard Worker ******************************************************************************
8*0e209d39SAndroid Build Coastguard Worker *   Date        Name        Description
9*0e209d39SAndroid Build Coastguard Worker *   12/14/09    doug        Creation.
10*0e209d39SAndroid Build Coastguard Worker ******************************************************************************
11*0e209d39SAndroid Build Coastguard Worker */
12*0e209d39SAndroid Build Coastguard Worker 
13*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h"
14*0e209d39SAndroid Build Coastguard Worker 
15*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_FORMATTING
16*0e209d39SAndroid Build Coastguard Worker 
17*0e209d39SAndroid Build Coastguard Worker #include "unicode/fpositer.h"
18*0e209d39SAndroid Build Coastguard Worker #include "cmemory.h"
19*0e209d39SAndroid Build Coastguard Worker #include "uvectr32.h"
20*0e209d39SAndroid Build Coastguard Worker 
21*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN
22*0e209d39SAndroid Build Coastguard Worker 
~FieldPositionIterator()23*0e209d39SAndroid Build Coastguard Worker FieldPositionIterator::~FieldPositionIterator() {
24*0e209d39SAndroid Build Coastguard Worker   delete data;
25*0e209d39SAndroid Build Coastguard Worker   data = nullptr;
26*0e209d39SAndroid Build Coastguard Worker   pos = -1;
27*0e209d39SAndroid Build Coastguard Worker }
28*0e209d39SAndroid Build Coastguard Worker 
FieldPositionIterator()29*0e209d39SAndroid Build Coastguard Worker FieldPositionIterator::FieldPositionIterator()
30*0e209d39SAndroid Build Coastguard Worker     : data(nullptr), pos(-1) {
31*0e209d39SAndroid Build Coastguard Worker }
32*0e209d39SAndroid Build Coastguard Worker 
FieldPositionIterator(const FieldPositionIterator & rhs)33*0e209d39SAndroid Build Coastguard Worker FieldPositionIterator::FieldPositionIterator(const FieldPositionIterator &rhs)
34*0e209d39SAndroid Build Coastguard Worker   : UObject(rhs), data(nullptr), pos(rhs.pos) {
35*0e209d39SAndroid Build Coastguard Worker 
36*0e209d39SAndroid Build Coastguard Worker   if (rhs.data) {
37*0e209d39SAndroid Build Coastguard Worker     UErrorCode status = U_ZERO_ERROR;
38*0e209d39SAndroid Build Coastguard Worker     data = new UVector32(status);
39*0e209d39SAndroid Build Coastguard Worker     data->assign(*rhs.data, status);
40*0e209d39SAndroid Build Coastguard Worker     if (status != U_ZERO_ERROR) {
41*0e209d39SAndroid Build Coastguard Worker       delete data;
42*0e209d39SAndroid Build Coastguard Worker       data = nullptr;
43*0e209d39SAndroid Build Coastguard Worker       pos = -1;
44*0e209d39SAndroid Build Coastguard Worker     }
45*0e209d39SAndroid Build Coastguard Worker   }
46*0e209d39SAndroid Build Coastguard Worker }
47*0e209d39SAndroid Build Coastguard Worker 
operator ==(const FieldPositionIterator & rhs) const48*0e209d39SAndroid Build Coastguard Worker bool FieldPositionIterator::operator==(const FieldPositionIterator &rhs) const {
49*0e209d39SAndroid Build Coastguard Worker   if (&rhs == this) {
50*0e209d39SAndroid Build Coastguard Worker     return true;
51*0e209d39SAndroid Build Coastguard Worker   }
52*0e209d39SAndroid Build Coastguard Worker   if (pos != rhs.pos) {
53*0e209d39SAndroid Build Coastguard Worker     return false;
54*0e209d39SAndroid Build Coastguard Worker   }
55*0e209d39SAndroid Build Coastguard Worker   if (!data) {
56*0e209d39SAndroid Build Coastguard Worker     return rhs.data == nullptr;
57*0e209d39SAndroid Build Coastguard Worker   }
58*0e209d39SAndroid Build Coastguard Worker   return rhs.data ? data->operator==(*rhs.data) : false;
59*0e209d39SAndroid Build Coastguard Worker }
60*0e209d39SAndroid Build Coastguard Worker 
setData(UVector32 * adopt,UErrorCode & status)61*0e209d39SAndroid Build Coastguard Worker void FieldPositionIterator::setData(UVector32 *adopt, UErrorCode& status) {
62*0e209d39SAndroid Build Coastguard Worker   // Verify that adopt has valid data, and update status if it doesn't.
63*0e209d39SAndroid Build Coastguard Worker   if (U_SUCCESS(status)) {
64*0e209d39SAndroid Build Coastguard Worker     if (adopt) {
65*0e209d39SAndroid Build Coastguard Worker       if (adopt->size() == 0) {
66*0e209d39SAndroid Build Coastguard Worker         delete adopt;
67*0e209d39SAndroid Build Coastguard Worker         adopt = nullptr;
68*0e209d39SAndroid Build Coastguard Worker       } else if ((adopt->size() % 4) != 0) {
69*0e209d39SAndroid Build Coastguard Worker         status = U_ILLEGAL_ARGUMENT_ERROR;
70*0e209d39SAndroid Build Coastguard Worker       } else {
71*0e209d39SAndroid Build Coastguard Worker         for (int i = 2; i < adopt->size(); i += 4) {
72*0e209d39SAndroid Build Coastguard Worker           if (adopt->elementAti(i) >= adopt->elementAti(i+1)) {
73*0e209d39SAndroid Build Coastguard Worker             status = U_ILLEGAL_ARGUMENT_ERROR;
74*0e209d39SAndroid Build Coastguard Worker             break;
75*0e209d39SAndroid Build Coastguard Worker           }
76*0e209d39SAndroid Build Coastguard Worker         }
77*0e209d39SAndroid Build Coastguard Worker       }
78*0e209d39SAndroid Build Coastguard Worker     }
79*0e209d39SAndroid Build Coastguard Worker   }
80*0e209d39SAndroid Build Coastguard Worker 
81*0e209d39SAndroid Build Coastguard Worker   // We own the data, even if status is in error, so we need to delete it now
82*0e209d39SAndroid Build Coastguard Worker   // if we're not keeping track of it.
83*0e209d39SAndroid Build Coastguard Worker   if (!U_SUCCESS(status)) {
84*0e209d39SAndroid Build Coastguard Worker     delete adopt;
85*0e209d39SAndroid Build Coastguard Worker     return;
86*0e209d39SAndroid Build Coastguard Worker   }
87*0e209d39SAndroid Build Coastguard Worker 
88*0e209d39SAndroid Build Coastguard Worker   delete data;
89*0e209d39SAndroid Build Coastguard Worker   data = adopt;
90*0e209d39SAndroid Build Coastguard Worker   pos = adopt == nullptr ? -1 : 0;
91*0e209d39SAndroid Build Coastguard Worker }
92*0e209d39SAndroid Build Coastguard Worker 
next(FieldPosition & fp)93*0e209d39SAndroid Build Coastguard Worker UBool FieldPositionIterator::next(FieldPosition& fp) {
94*0e209d39SAndroid Build Coastguard Worker   if (pos == -1) {
95*0e209d39SAndroid Build Coastguard Worker     return false;
96*0e209d39SAndroid Build Coastguard Worker   }
97*0e209d39SAndroid Build Coastguard Worker 
98*0e209d39SAndroid Build Coastguard Worker   // Ignore the first element of the tetrad: used for field category
99*0e209d39SAndroid Build Coastguard Worker   pos++;
100*0e209d39SAndroid Build Coastguard Worker   fp.setField(data->elementAti(pos++));
101*0e209d39SAndroid Build Coastguard Worker   fp.setBeginIndex(data->elementAti(pos++));
102*0e209d39SAndroid Build Coastguard Worker   fp.setEndIndex(data->elementAti(pos++));
103*0e209d39SAndroid Build Coastguard Worker 
104*0e209d39SAndroid Build Coastguard Worker   if (pos == data->size()) {
105*0e209d39SAndroid Build Coastguard Worker     pos = -1;
106*0e209d39SAndroid Build Coastguard Worker   }
107*0e209d39SAndroid Build Coastguard Worker 
108*0e209d39SAndroid Build Coastguard Worker   return true;
109*0e209d39SAndroid Build Coastguard Worker }
110*0e209d39SAndroid Build Coastguard Worker 
111*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END
112*0e209d39SAndroid Build Coastguard Worker 
113*0e209d39SAndroid Build Coastguard Worker #endif /* #if !UCONFIG_NO_FORMATTING */
114*0e209d39SAndroid Build Coastguard Worker 
115