com.ibm.icu.text.PluralRanges Maven / Gradle / Ivy
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 2008-2015, Google, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.text;
import java.util.Arrays;
import java.util.EnumSet;
import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.util.Freezable;
import com.ibm.icu.util.Output;
/**
* Utility class for returning the plural category for a range of numbers, such as 1–5, so that appropriate messages can
* be chosen. The rules for determining this value vary widely across locales.
*
* @author markdavis
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public final class PluralRanges implements Freezable, Comparable {
private volatile boolean isFrozen;
private Matrix matrix = new Matrix();
private boolean[] explicit = new boolean[StandardPlural.COUNT];
/**
* Constructor
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public PluralRanges() {
}
/**
* Internal class for mapping from two StandardPluralCategories values to another.
*/
private static final class Matrix implements Comparable, Cloneable {
private byte[] data = new byte[StandardPlural.COUNT * StandardPlural.COUNT];
{
for (int i = 0; i < data.length; ++i) {
data[i] = -1;
}
}
Matrix() {
}
/**
* Internal method for setting.
*/
@SuppressWarnings("unused")
void set(StandardPlural start, StandardPlural end, StandardPlural result) {
data[start.ordinal() * StandardPlural.COUNT + end.ordinal()] = result == null ? (byte) -1
: (byte) result.ordinal();
}
/**
* Internal method for setting; throws exception if already set.
*/
void setIfNew(StandardPlural start, StandardPlural end,
StandardPlural result) {
byte old = data[start.ordinal() * StandardPlural.COUNT + end.ordinal()];
if (old >= 0) {
throw new IllegalArgumentException("Previously set value for <" + start + ", " + end + ", "
+ StandardPlural.VALUES.get(old) + ">");
}
data[start.ordinal() * StandardPlural.COUNT + end.ordinal()] = result == null ? (byte) -1
: (byte) result.ordinal();
}
/**
* Internal method for getting.
*/
StandardPlural get(StandardPlural start, StandardPlural end) {
byte result = data[start.ordinal() * StandardPlural.COUNT + end.ordinal()];
return result < 0 ? null : StandardPlural.VALUES.get(result);
}
/**
* Internal method to see if <*,end> values are all the same.
*/
@SuppressWarnings("unused")
StandardPlural endSame(StandardPlural end) {
StandardPlural first = null;
for (StandardPlural start : StandardPlural.VALUES) {
StandardPlural item = get(start, end);
if (item == null) {
continue;
}
if (first == null) {
first = item;
continue;
}
if (first != item) {
return null;
}
}
return first;
}
/**
* Internal method to see if values are all the same.
*/
@SuppressWarnings("unused")
StandardPlural startSame(StandardPlural start,
EnumSet endDone, Output emit) {
emit.value = false;
StandardPlural first = null;
for (StandardPlural end : StandardPlural.VALUES) {
StandardPlural item = get(start, end);
if (item == null) {
continue;
}
if (first == null) {
first = item;
continue;
}
if (first != item) {
return null;
}
// only emit if we didn't cover with the 'end' values
if (!endDone.contains(end)) {
emit.value = true;
}
}
return first;
}
@Override
public int hashCode() {
int result = 0;
for (int i = 0; i < data.length; ++i) {
result = result * 37 + data[i];
}
return result;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Matrix)) {
return false;
}
return 0 == compareTo((Matrix) other);
}
@Override
public int compareTo(Matrix o) {
for (int i = 0; i < data.length; ++i) {
int diff = data[i] - o.data[i];
if (diff != 0) {
return diff;
}
}
return 0;
}
@Override
public Matrix clone() {
Matrix result = new Matrix();
result.data = data.clone();
return result;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (StandardPlural i : StandardPlural.values()) {
for (StandardPlural j : StandardPlural.values()) {
StandardPlural x = get(i, j);
if (x != null) {
result.append(i + " & " + j + " → " + x + ";\n");
}
}
}
return result.toString();
}
}
/**
* Internal method for building. If the start or end are null, it means everything of that type.
*
* @param rangeStart
* plural category for the start of the range
* @param rangeEnd
* plural category for the end of the range
* @param result
* the resulting plural category
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public void add(StandardPlural rangeStart, StandardPlural rangeEnd,
StandardPlural result) {
if (isFrozen) {
throw new UnsupportedOperationException();
}
explicit[result.ordinal()] = true;
if (rangeStart == null) {
for (StandardPlural rs : StandardPlural.values()) {
if (rangeEnd == null) {
for (StandardPlural re : StandardPlural.values()) {
matrix.setIfNew(rs, re, result);
}
} else {
explicit[rangeEnd.ordinal()] = true;
matrix.setIfNew(rs, rangeEnd, result);
}
}
} else if (rangeEnd == null) {
explicit[rangeStart.ordinal()] = true;
for (StandardPlural re : StandardPlural.values()) {
matrix.setIfNew(rangeStart, re, result);
}
} else {
explicit[rangeStart.ordinal()] = true;
explicit[rangeEnd.ordinal()] = true;
matrix.setIfNew(rangeStart, rangeEnd, result);
}
}
/**
* Returns the appropriate plural category for a range from start to end. If there is no available data, then
* 'end' is returned as an implicit value. (Such an implicit value can be tested for with {@link #isExplicit}.)
*
* @param start
* plural category for the start of the range
* @param end
* plural category for the end of the range
* @return the resulting plural category, or 'end' if there is no data.
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public StandardPlural get(StandardPlural start, StandardPlural end) {
StandardPlural result = matrix.get(start, end);
return result == null ? end : result;
}
/**
* Returns whether the appropriate plural category for a range from start to end
* is explicitly in the data (vs given an implicit value). See also {@link #get}.
*
* @param start
* plural category for the start of the range
* @param end
* plural category for the end of the range
* @return whether the value for (start,end) is explicit or not.
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public boolean isExplicit(StandardPlural start, StandardPlural end) {
return matrix.get(start, end) != null;
}
/**
* Internal method to determines whether the StandardPluralCategories was explicitly used in any add statement.
*
* @param count
* plural category to test
* @return true if set
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public boolean isExplicitlySet(StandardPlural count) {
return explicit[count.ordinal()];
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof PluralRanges)) {
return false;
}
PluralRanges otherPR = (PluralRanges)other;
return matrix.equals(otherPR.matrix) && Arrays.equals(explicit, otherPR.explicit);
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public int hashCode() {
return matrix.hashCode();
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public int compareTo(PluralRanges that) {
return matrix.compareTo(that.matrix);
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public boolean isFrozen() {
return isFrozen;
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public PluralRanges freeze() {
isFrozen = true;
return this;
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public PluralRanges cloneAsThawed() {
PluralRanges result = new PluralRanges();
result.explicit = explicit.clone();
result.matrix = matrix.clone();
return result;
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public String toString() {
return matrix.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy