summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java
downloadcbb-gcc-4.6.4-upstream.tar.bz2
cbb-gcc-4.6.4-upstream.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java')
-rw-r--r--libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java436
1 files changed, 436 insertions, 0 deletions
diff --git a/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java b/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java
new file mode 100644
index 000000000..b1e0af1a7
--- /dev/null
+++ b/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java
@@ -0,0 +1,436 @@
+/* SetOfIntegerSyntax.java --
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.print.attribute;
+
+import java.io.Serializable;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * <code>SetOfIntegerSyntax</code> is the abstract base class of all attribute
+ * classes which provide a set of non-negative integers as value (e.g. the
+ * page ranges to print) represented as single values or ranges of values.
+ * <p>
+ * A <code>SetOfIntegerSyntax</code> instance consists of an integer array of
+ * ranges. Ranges may have the same lower and upper bound representing a single
+ * integer value. Ranges with a lower bound greater than the upper bound are
+ * null ranges and discarded. Ranges may overlap in their values. In no case
+ * negative integers are allowed.
+ * </p>
+ * <p>
+ * There are several constructors available:
+ * <ul>
+ * <li><code>SetOfIntegerSyntax(int member)</code><br>
+ * Constructor for an instance with only one integer value.
+ * </li><br>
+ * <li><code>SetOfIntegerSyntax(int lowerBound, int upperBound)</code><br>
+ * Constructor for an instance with one range of integer values.
+ * </li><br>
+ * <li><code>SetOfIntegerSyntax(int[][] members)</code><br>
+ * Flexible constructor for an instance with several single integer values
+ * and/or several ranges of integer values. The allowed array form is an
+ * array of integer arrays of length one or two. Examples are:
+ * <code>int[0][]</code> for empty set of integers, <code>int[][] {{1}}</code>
+ * , <code>int[][] {{1,5}}</code>, <code>int[][] {{1,5},{7,9}}</code>,
+ * <code>int[][] {{3,7},{19}}</code>.
+ * </li><br>
+ * <li><code>SetOfIntegerSyntax(String s)</code><br>
+ * Flexible constructor for an instance with several single integer values
+ * and/or several ranges of integer values. The allowed String instance have
+ * to be a String with comma separated ranges of integer values or single
+ * values. Ranges are represented by two integer with a hypen (-) or colon (:)
+ * between the lower and upper bound value. Whitespace characters are ignored.
+ * Examples are: <code>""</code> for an empty set of integers,
+ * <code>"1"</code>, <code>"1-5"</code>, <code>"1-5,7-9"</code>,
+ * <code>"3-7,19"</code> and <code>"1:2,4"</code>.
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * <b>Internal storage:</b><br>
+ * The set of integers are stored internally in a normalized array form.
+ * In the normalized array form the set of integer ranges are represented
+ * in as few ranges as possible and overlapping ranges are merged. The ranges
+ * are always represented as an integer array of length two with ranges
+ * stored in {lower bound, upper bound} form. The ranges are stored in
+ * ascending order, without any null ranges.
+ * </p>
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+public abstract class SetOfIntegerSyntax
+ implements Cloneable, Serializable
+{
+ private static final long serialVersionUID = 3666874174847632203L;
+
+ private int[][] members;
+
+ private static int[][] normalize(int[][] values, int size)
+ {
+ // Sort into increasing order. First the first index is
+ // compared, then the second.
+ Arrays.sort(values, 0, size, new Comparator()
+ {
+ public int compare(Object o1, Object o2)
+ {
+ int[] v1 = (int[]) o1;
+ int[] v2 = (int[]) o2;
+ if (v1[0] == v2[0])
+ return v1[1] - v2[1];
+ return v1[0] - v2[0];
+ }
+ });
+
+ // Now coalesce overlapping ranges.
+ int outIndex = 0;
+ for (int i = 0; i < size; ++i)
+ {
+ // Note that we compare with values[i][1]+1, since
+ // we can coalesce {0,1} with {2,x}.
+ int save = i;
+ while (i + 1 < size && values[i + 1][0] <= values[i][1] + 1)
+ {
+ values[i][1] = Math.max(values[i][1], values[i + 1][1]);
+ ++i;
+ }
+ values[outIndex++] = values[save];
+ }
+
+ int[][] result = new int[outIndex][];
+ System.arraycopy(values, 0, result, 0, outIndex);
+
+ return result;
+ }
+
+ /**
+ * Creates a <code>SetOfIntegerSyntax</code> object.
+ *
+ * @param member the member value
+ *
+ * @exception IllegalArgumentException if member is &lt; 0
+ */
+ protected SetOfIntegerSyntax(int member)
+ {
+ if (member < 0)
+ throw new IllegalArgumentException("member may not be less than 0");
+
+ this.members = new int[][]{{member, member}};
+ }
+
+ /**
+ * Creates a <code>SetOfIntegerSyntax</code> object.
+ *
+ * @param members the members to use in this set. If
+ * <code>null</code> an empty set is created.
+ *
+ * @exception IllegalArgumentException if any element is invalid
+ * @exception NullPointerException if any element of members is null
+ */
+ protected SetOfIntegerSyntax(int[][] members)
+ {
+ int[][] newMembers;
+ int outIndex = 0;
+ if (members == null)
+ newMembers = new int[0][];
+ else
+ {
+ newMembers = new int[members.length][];
+ for (int index = 0; index < members.length; index++)
+ {
+ int lower;
+ int upper;
+
+ if (members[index].length == 1)
+ {
+ lower = members[index][0];
+ upper = members[index][0];
+ }
+ else if (members[index].length == 2)
+ {
+ lower = members[index][0];
+ upper = members[index][1];
+ }
+ else
+ throw new IllegalArgumentException("invalid member element");
+
+ // We only want to reject non-null ranges where lower<0.
+ if (lower <= upper && lower < 0)
+ throw new IllegalArgumentException("invalid member element");
+
+ if (lower <= upper)
+ {
+ int[] range = new int[2];
+ range[0] = lower;
+ range[1] = upper;
+ newMembers[outIndex++] = range;
+ }
+ }
+ }
+
+ this.members = normalize(newMembers, outIndex);
+ }
+
+ private boolean skipWhitespace(StringCharacterIterator i)
+ {
+ while (Character.isWhitespace(i.current()))
+ i.next();
+ return i.current() == CharacterIterator.DONE;
+ }
+
+ private boolean skipNumber(StringCharacterIterator i)
+ {
+ boolean readAny = false;
+ while (Character.isDigit(i.current()))
+ {
+ readAny = true;
+ i.next();
+ }
+ return readAny;
+ }
+
+ /**
+ * Creates a <code>SetOfIntegerSyntax</code> object.
+ *
+ * @param s the members to use in this set in string form. If
+ * <code>null</code> an empty set is created.
+ *
+ * @exception IllegalArgumentException if any element is invalid
+ */
+ protected SetOfIntegerSyntax(String s)
+ {
+ if (s == null)
+ this.members = normalize(new int[0][], 0);
+ else
+ {
+ ArrayList vals = new ArrayList();
+
+ StringCharacterIterator it = new StringCharacterIterator(s);
+
+ while (true)
+ {
+ // Skip whitespace.
+ if (skipWhitespace(it))
+ break;
+
+ // Parse integer.
+ int index = it.getIndex();
+ if (! skipNumber(it))
+ throw new IllegalArgumentException();
+ int[] item = new int[2];
+ item[0] = Integer.parseInt(s.substring(index, it.getIndex()));
+
+ if (! skipWhitespace(it))
+ {
+ char c = it.current();
+ if (c == ':' || c == '-')
+ {
+ it.next();
+ if (skipWhitespace(it))
+ throw new IllegalArgumentException();
+ index = it.getIndex();
+ if (! skipNumber(it))
+ throw new IllegalArgumentException();
+ item[1] = Integer.parseInt(s.substring(index, it.getIndex()));
+ }
+ else
+ item[1] = item[0];
+ }
+ else
+ item[1] = item[0];
+
+ if (item[0] <= item[1])
+ vals.add(item);
+
+ if (skipWhitespace(it))
+ break;
+ if (it.current() != ',')
+ throw new IllegalArgumentException();
+ it.next();
+ }
+
+ members = normalize((int[][]) vals.toArray(new int[0][]), vals.size());
+ }
+ }
+
+ /**
+ * Creates a <code>SetOfIntegerSyntax</code> object.
+ *
+ * @param lowerBound the lower bound value
+ * @param upperBound the upper bound value
+ *
+ * @exception IllegalArgumentException if lowerBound &lt;= upperbound
+ * and lowerBound &lt; 0
+ */
+ protected SetOfIntegerSyntax(int lowerBound, int upperBound)
+ {
+ // We only want to reject non-null ranges where lower<0.
+ if (lowerBound <= upperBound
+ && lowerBound < 0)
+ throw new IllegalArgumentException();
+
+ members = (lowerBound <= upperBound ? new int[][]{{lowerBound, upperBound}}
+ : new int[0][]);
+ }
+
+ /**
+ * Checks if this set contains the given value.
+ *
+ * @param value the value to test for
+ *
+ * @return true if this set contains value, false otherwise
+ */
+ public boolean contains(int value)
+ {
+ // This only works on a normalized member array.
+ for (int index = 0; index < members.length; index++)
+ {
+ if (value < members[index][0])
+ return false;
+ else if (value <= members[index][1])
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if this set contains the given value.
+ *
+ * @param value the value to test for
+ *
+ * @return true if this set contains value, false otherwise
+ */
+ public boolean contains(IntegerSyntax value)
+ {
+ return contains(value.getValue());
+ }
+
+ /**
+ * Tests if the given object is equal to this object.
+ *
+ * @param obj the object to test
+ *
+ * @return true if both objects are equal, false otherwise.
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof SetOfIntegerSyntax))
+ return false;
+ SetOfIntegerSyntax other = (SetOfIntegerSyntax) obj;
+ if (other.members.length != members.length)
+ return false;
+ for (int i = 0; i < members.length; ++i)
+ {
+ if (members[i][0] != other.members[i][0]
+ || members[i][1] != other.members[i][1])
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns an array describing the members included in this set.
+ *
+ * @return The members in normalized array form.
+ */
+ public int[][] getMembers()
+ {
+ return (int[][]) members.clone();
+ }
+
+ /**
+ * Returns the hashcode for this object.
+ *
+ * @return The hashcode.
+ */
+ public int hashCode()
+ {
+ int result = 0;
+ for (int i = 0; i < members.length; ++i)
+ result += members[i][0] + members[i][1];
+ return result;
+ }
+
+ /**
+ * Returns the smallest value that is greater than x which is in this set.
+ *
+ * @param x an integer value
+ *
+ * @return The next smallest integer value, or <code>-1</code> if there
+ * is no greater integer in the set.
+ */
+ public int next(int x)
+ {
+ for (int i = 0; i < members.length; ++i)
+ {
+ if (x >= members[i][1])
+ continue;
+ if (x < members[i][0])
+ return members[i][0];
+ // X is in this range.
+ return x + 1;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the string representation for this object.
+ * The value is a zero length string for an empty set, or a comma seperated
+ * list of ranges and single values in the form <code>"1-2,5-7,10"</code>.
+ *
+ * @return The string representation.
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < members.length; ++i)
+ {
+ if (i > 0)
+ sb.append(',');
+ sb.append(members[i][0]);
+ if (members[i][0] != members[i][1])
+ {
+ sb.append('-');
+ sb.append(members[i][1]);
+ }
+ }
+ return sb.toString();
+ }
+}