All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.icu.impl.FormattedValueFieldPositionIteratorImpl Maven / Gradle / Ivy

Go to download

International Component for Unicode for Java (ICU4J) is a mature, widely used Java library providing Unicode and Globalization support

There is a newer version: 76.1
Show newest version
// © 2019 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl;

import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.FieldPosition;
import java.text.Format;
import java.util.List;

import com.ibm.icu.text.ConstrainedFieldPosition;

/**
 * Implementation of FormattedValue based on FieldPositionIterator.
 *
 * In C++, this implements FormattedValue. In Java, it is a stateless
 * collection of static functions to avoid having to use nested objects.
 */
public class FormattedValueFieldPositionIteratorImpl {

    /** Do not construct instances of this class */
    private FormattedValueFieldPositionIteratorImpl() {}

    /** Helper class to keep track of fields with values in Java */
    private static class FieldWithValue extends Format.Field {
        private static final long serialVersionUID = -3850076447157793465L;

        public final Format.Field field;
        public final int value;

        public FieldWithValue(Format.Field field, int value) {
            super(field.toString());
            this.field = field;
            this.value = value;
        }
    }

    public static boolean nextPosition(List attributes, ConstrainedFieldPosition cfpos) {
        int numFields = attributes.size();
        int i = (int) cfpos.getInt64IterationContext();
        for (; i < numFields; i++) {
            FieldPosition fpos = attributes.get(i);
            Format.Field field = fpos.getFieldAttribute();
            Object value = null;
            if (field instanceof FieldWithValue) {
                value = ((FieldWithValue) field).value;
                field = ((FieldWithValue) field).field;
            }
            if (cfpos.matchesField(field, value)) {
                int start = fpos.getBeginIndex();
                int limit = fpos.getEndIndex();
                cfpos.setState(field, value, start, limit);
                break;
            }
        }
        cfpos.setInt64IterationContext(i == numFields ? i : i + 1);
        return i < numFields;
    }

    public static AttributedCharacterIterator toCharacterIterator(CharSequence cs, List attributes) {
        AttributedString as = new AttributedString(cs.toString());

        // add attributes to the AttributedString
        for (int i = 0; i < attributes.size(); i++) {
            FieldPosition fp = attributes.get(i);
            Format.Field field = fp.getFieldAttribute();
            Object value = field;
            if (field instanceof FieldWithValue) {
                value = ((FieldWithValue) field).value;
                field = ((FieldWithValue) field).field;
            }
            as.addAttribute(field, value, fp.getBeginIndex(), fp.getEndIndex());
        }

        // return the CharacterIterator from AttributedString
        return as.getIterator();
    }

    public static void addOverlapSpans(List attributes, Format.Field spanField, int firstIndex) {
        // In order to avoid fancy data structures, this is an O(N^2) algorithm,
        // which should be fine for all real-life applications of this function.
        int s1a = Integer.MAX_VALUE;
        int s1b = 0;
        int s2a = Integer.MAX_VALUE;
        int s2b = 0;
        int numFields = attributes.size();
        for (int i = 0; i attributes) {
        // Use bubble sort, O(N^2) but easy and no fancy data structures.
        int numFields = attributes.size();
        while (true) {
            boolean isSorted = true;
            for (int i=0; i higher rank
                    comparison = fp2.getBeginIndex() - fp1.getBeginIndex();
                } else if (fp1.getEndIndex() != fp2.getEndIndex()) {
                    // Higher length (end index) -> lower rank
                    comparison = fp1.getEndIndex() - fp2.getEndIndex();
                } else if (fp1.getFieldAttribute() != fp2.getFieldAttribute()) {
                    // Span category -> lower rank
                    // Pick other orders arbitrarily
                    boolean fp1isSpan = fp1.getFieldAttribute() instanceof FieldWithValue;
                    boolean fp2isSpan = fp2.getFieldAttribute() instanceof FieldWithValue;
                    if (fp1isSpan && !fp2isSpan) {
                        comparison = 1;
                    } else if (fp2isSpan && !fp1isSpan) {
                        comparison = -1;
                    } else {
                        comparison = fp1.hashCode() - fp2.hashCode();
                    }
                }
                if (comparison < 0) {
                    // Perform a swap
                    isSorted = false;
                    attributes.set(i, fp2);
                    attributes.set(i + 1, fp1);
                }
            }
            if (isSorted) {
                break;
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy