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