1/*
2******************************************************************************
3* Copyright (C) 2009-2010, International Business Machines Corporation and
4* others. All Rights Reserved.
5******************************************************************************
6*   Date        Name        Description
7*   12/14/09    doug        Creation.
8******************************************************************************
9*/
10
11#include "unicode/utypes.h"
12
13#if !UCONFIG_NO_FORMATTING
14
15#include "unicode/fpositer.h"
16#include "cmemory.h"
17#include "uvectr32.h"
18
19U_NAMESPACE_BEGIN
20
21UOBJECT_DEFINE_NO_RTTI_IMPLEMENTATION(FieldPositionIterator)
22
23FieldPositionIterator::~FieldPositionIterator() {
24  delete data;
25  data = NULL;
26  pos = -1;
27}
28
29FieldPositionIterator::FieldPositionIterator()
30    : data(NULL), pos(-1) {
31}
32
33FieldPositionIterator::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
48UBool 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
61// BEGIN android-added
62int32_t FieldPositionIterator::getData(int32_t *dest, int32_t capacity) const {
63  int32_t len = data ? data->size() : 0;
64  if (len && dest) {
65    if (capacity < len) {
66      len = -len; // error, insufficient capacity
67    } else {
68      memcpy(dest, data->getBuffer(), len * sizeof(int32_t));
69    }
70  }
71  return len;
72}
73// END android-added
74
75void FieldPositionIterator::setData(UVector32 *adopt, UErrorCode& status) {
76  // Verify that adopt has valid data, and update status if it doesn't.
77  if (U_SUCCESS(status)) {
78    if (adopt) {
79      if ((adopt->size() % 3) != 0) {
80        status = U_ILLEGAL_ARGUMENT_ERROR;
81      } else {
82        for (int i = 1; i < adopt->size(); i += 3) {
83          if (adopt->elementAti(i) >= adopt->elementAti(i+1)) {
84            status = U_ILLEGAL_ARGUMENT_ERROR;
85            break;
86          }
87        }
88      }
89    }
90  }
91
92  // We own the data, even if status is in error, so we need to delete it now
93  // if we're not keeping track of it.
94  if (!U_SUCCESS(status)) {
95    delete adopt;
96    return;
97  }
98
99  delete data;
100  data = adopt;
101  pos = adopt == NULL ? -1 : 0;
102}
103
104UBool FieldPositionIterator::next(FieldPosition& fp) {
105  if (pos == -1) {
106    return FALSE;
107  }
108
109  fp.setField(data->elementAti(pos++));
110  fp.setBeginIndex(data->elementAti(pos++));
111  fp.setEndIndex(data->elementAti(pos++));
112
113  if (pos == data->size()) {
114    pos = -1;
115  }
116
117  return TRUE;
118}
119
120U_NAMESPACE_END
121
122#endif /* #if !UCONFIG_NO_FORMATTING */
123
124