11cb0ef41Sopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
21cb0ef41Sopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
31cb0ef41Sopenharmony_ci/*
41cb0ef41Sopenharmony_ci******************************************************************************
51cb0ef41Sopenharmony_ci* Copyright (C) 2009-2012, International Business Machines Corporation and
61cb0ef41Sopenharmony_ci* others. All Rights Reserved.
71cb0ef41Sopenharmony_ci******************************************************************************
81cb0ef41Sopenharmony_ci*   Date        Name        Description
91cb0ef41Sopenharmony_ci*   12/14/09    doug        Creation.
101cb0ef41Sopenharmony_ci******************************************************************************
111cb0ef41Sopenharmony_ci*/
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include "unicode/utypes.h"
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#if !UCONFIG_NO_FORMATTING
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci#include "unicode/fpositer.h"
181cb0ef41Sopenharmony_ci#include "cmemory.h"
191cb0ef41Sopenharmony_ci#include "uvectr32.h"
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciU_NAMESPACE_BEGIN
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciFieldPositionIterator::~FieldPositionIterator() {
241cb0ef41Sopenharmony_ci  delete data;
251cb0ef41Sopenharmony_ci  data = nullptr;
261cb0ef41Sopenharmony_ci  pos = -1;
271cb0ef41Sopenharmony_ci}
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciFieldPositionIterator::FieldPositionIterator()
301cb0ef41Sopenharmony_ci    : data(nullptr), pos(-1) {
311cb0ef41Sopenharmony_ci}
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciFieldPositionIterator::FieldPositionIterator(const FieldPositionIterator &rhs)
341cb0ef41Sopenharmony_ci  : UObject(rhs), data(nullptr), pos(rhs.pos) {
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci  if (rhs.data) {
371cb0ef41Sopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
381cb0ef41Sopenharmony_ci    data = new UVector32(status);
391cb0ef41Sopenharmony_ci    data->assign(*rhs.data, status);
401cb0ef41Sopenharmony_ci    if (status != U_ZERO_ERROR) {
411cb0ef41Sopenharmony_ci      delete data;
421cb0ef41Sopenharmony_ci      data = nullptr;
431cb0ef41Sopenharmony_ci      pos = -1;
441cb0ef41Sopenharmony_ci    }
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_cibool FieldPositionIterator::operator==(const FieldPositionIterator &rhs) const {
491cb0ef41Sopenharmony_ci  if (&rhs == this) {
501cb0ef41Sopenharmony_ci    return true;
511cb0ef41Sopenharmony_ci  }
521cb0ef41Sopenharmony_ci  if (pos != rhs.pos) {
531cb0ef41Sopenharmony_ci    return false;
541cb0ef41Sopenharmony_ci  }
551cb0ef41Sopenharmony_ci  if (!data) {
561cb0ef41Sopenharmony_ci    return rhs.data == nullptr;
571cb0ef41Sopenharmony_ci  }
581cb0ef41Sopenharmony_ci  return rhs.data ? data->operator==(*rhs.data) : false;
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_civoid FieldPositionIterator::setData(UVector32 *adopt, UErrorCode& status) {
621cb0ef41Sopenharmony_ci  // Verify that adopt has valid data, and update status if it doesn't.
631cb0ef41Sopenharmony_ci  if (U_SUCCESS(status)) {
641cb0ef41Sopenharmony_ci    if (adopt) {
651cb0ef41Sopenharmony_ci      if (adopt->size() == 0) {
661cb0ef41Sopenharmony_ci        delete adopt;
671cb0ef41Sopenharmony_ci        adopt = nullptr;
681cb0ef41Sopenharmony_ci      } else if ((adopt->size() % 4) != 0) {
691cb0ef41Sopenharmony_ci        status = U_ILLEGAL_ARGUMENT_ERROR;
701cb0ef41Sopenharmony_ci      } else {
711cb0ef41Sopenharmony_ci        for (int i = 2; i < adopt->size(); i += 4) {
721cb0ef41Sopenharmony_ci          if (adopt->elementAti(i) >= adopt->elementAti(i+1)) {
731cb0ef41Sopenharmony_ci            status = U_ILLEGAL_ARGUMENT_ERROR;
741cb0ef41Sopenharmony_ci            break;
751cb0ef41Sopenharmony_ci          }
761cb0ef41Sopenharmony_ci        }
771cb0ef41Sopenharmony_ci      }
781cb0ef41Sopenharmony_ci    }
791cb0ef41Sopenharmony_ci  }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  // We own the data, even if status is in error, so we need to delete it now
821cb0ef41Sopenharmony_ci  // if we're not keeping track of it.
831cb0ef41Sopenharmony_ci  if (!U_SUCCESS(status)) {
841cb0ef41Sopenharmony_ci    delete adopt;
851cb0ef41Sopenharmony_ci    return;
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  delete data;
891cb0ef41Sopenharmony_ci  data = adopt;
901cb0ef41Sopenharmony_ci  pos = adopt == nullptr ? -1 : 0;
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciUBool FieldPositionIterator::next(FieldPosition& fp) {
941cb0ef41Sopenharmony_ci  if (pos == -1) {
951cb0ef41Sopenharmony_ci    return false;
961cb0ef41Sopenharmony_ci  }
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  // Ignore the first element of the tetrad: used for field category
991cb0ef41Sopenharmony_ci  pos++;
1001cb0ef41Sopenharmony_ci  fp.setField(data->elementAti(pos++));
1011cb0ef41Sopenharmony_ci  fp.setBeginIndex(data->elementAti(pos++));
1021cb0ef41Sopenharmony_ci  fp.setEndIndex(data->elementAti(pos++));
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  if (pos == data->size()) {
1051cb0ef41Sopenharmony_ci    pos = -1;
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  return true;
1091cb0ef41Sopenharmony_ci}
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ciU_NAMESPACE_END
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci#endif /* #if !UCONFIG_NO_FORMATTING */
1141cb0ef41Sopenharmony_ci
115