blob: 6fcfe51b541a30b49451c796e1414bc643aed062 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.qpid.protonj2.types;
public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
private static final long serialVersionUID = 3042749852724499995L;
private static final UnsignedInteger[] cachedValues = new UnsignedInteger[256];
static {
for (int i = 0; i < 256; i++) {
cachedValues[i] = new UnsignedInteger(i);
}
}
public static final UnsignedInteger ZERO = cachedValues[0];
public static final UnsignedInteger ONE = cachedValues[1];
public static final UnsignedInteger MAX_VALUE = new UnsignedInteger(0xffffffff);
private final int underlying;
public UnsignedInteger(int underlying) {
this.underlying = underlying;
}
@Override
public int intValue() {
return underlying;
}
@Override
public long longValue() {
return Integer.toUnsignedLong(underlying);
}
@Override
public float floatValue() {
return longValue();
}
@Override
public double doubleValue() {
return longValue();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
UnsignedInteger that = (UnsignedInteger) o;
if (underlying != that.underlying) {
return false;
}
return true;
}
/**
* Compares the give integer value to this unsigned integer numerically treating the given value as unsigned.
*
* @param value
* the integer to compare to this unsigned integer instance.
*
* @return the value 0 if this == value; a value less than 0 if this &lt; value as unsigned values; and a value
* greater than 0 if this &gt; value as unsigned values
*/
public int compareTo(int value) {
return Integer.compareUnsigned(underlying, value);
}
/**
* Compares the give long value to this unsigned integer numerically treating the given value as unsigned.
*
* @param value
* the long to compare to this unsigned integer instance.
*
* @return the value 0 if this == value; a value less than 0 if this &lt; value as unsigned values; and a value
* greater than 0 if this &gt; value as unsigned values
*/
public int compareTo(long value) {
return Long.compareUnsigned(longValue(), value);
}
@Override
public int compareTo(UnsignedInteger value) {
return Long.compareUnsigned(longValue(), value.longValue());
}
/**
* Compares two integer values numerically treating the values as unsigned.
*
* @param left
* the left hand side integer to compare
* @param right
* the right hand side integer to compare
*
* @return the value 0 if left == right; a value less than 0 if left &lt; right as unsigned values; and a value
* greater than 0 if left &gt; right as unsigned values
*/
public static int compare(int left, int right) {
return Integer.compareUnsigned(left, right);
}
/**
* Compares two long values numerically treating the values as unsigned.
*
* @param left
* the left hand side long value to compare
* @param right
* the right hand side long value to compare
*
* @return the value 0 if left == right; a value less than 0 if left &lt; right as unsigned values; and a value
* greater than 0 if left &gt; right as unsigned values
*/
public static int compare(long left, long right) {
return Long.compareUnsigned(left, right);
}
@Override
public int hashCode() {
return underlying;
}
@Override
public String toString() {
return String.valueOf(longValue());
}
/**
* Returns an UnsignedInteger instance representing the specified int value. This method always returns
* a cached {@link UnsignedInteger} instance for values in the range [0...255] which can save space and time
* over calling the constructor {@link UnsignedInteger#UnsignedInteger(int)} which will always create a new
* instance of the {@link UnsignedInteger} type.
*
* @param value
* The int value to return as an {@link UnsignedInteger} instance.
*
* @return an {@link UnsignedInteger} instance representing the unsigned view of the given int.
*/
public static UnsignedInteger valueOf(int value) {
if ((value & 0xFFFFFF00) == 0) {
return cachedValues[value];
} else {
return new UnsignedInteger(value);
}
}
/**
* Adds the value of the given {@link UnsignedInteger} to this instance and return a new {@link UnsignedInteger}
* instance that represents the newly computed value.
*
* @param value
* The {@link UnsignedInteger} whose underlying value should be added to this instance's value.
*
* @return a new immutable {@link UnsignedInteger} resulting from the addition of this with the given value.
*/
public UnsignedInteger add(final UnsignedInteger value) {
int val = underlying + value.underlying;
return UnsignedInteger.valueOf(val);
}
/**
* Subtract the value of the given {@link UnsignedInteger} from this instance and return a new {@link UnsignedInteger}
* instance that represents the newly computed value.
*
* @param value
* The {@link UnsignedInteger} whose underlying value should be subtracted to this instance's value.
*
* @return a new immutable {@link UnsignedInteger} resulting from the subtraction the given value from this.
*/
public UnsignedInteger subtract(final UnsignedInteger value) {
int val = underlying - value.underlying;
return UnsignedInteger.valueOf(val);
}
/**
* Returns an {@link UnsignedInteger} instance representing the specified {@link String} value. This method
* always returns a cached {@link UnsignedInteger} instance for values in the range [0...255] which can save
* space and time over calling the constructor {@link UnsignedInteger#UnsignedInteger(int)} which will always
* create a new instance of the {@link UnsignedInteger} type.
*
* @param value
* The String value to return as an {@link UnsignedInteger} instance.
*
* @return an {@link UnsignedInteger} instance representing the unsigned view of the given String.
*
* @throws NumberFormatException if the given value is greater than the max {@link UnsignedInteger} value possible
* or the {@link String} value given cannot be converted to a numeric value.
*/
public static UnsignedInteger valueOf(final String value) {
long longVal = Long.parseLong(value);
return valueOf(longVal);
}
/**
* Returns an UnsignedInteger instance representing the specified long value. This method always returns
* a cached {@link UnsignedInteger} instance for values in the range [0...255] which can save space and time
* over calling the constructor {@link UnsignedInteger#UnsignedInteger(int)} which will always create a new
* instance of the {@link UnsignedInteger} type.
*
* @param value
* The long value to return as an {@link UnsignedInteger} instance.
*
* @return an {@link UnsignedInteger} instance representing the unsigned view of the given long.
*
* @throws NumberFormatException if the given value is greater than the max {@link UnsignedInteger} value possible.
*/
public static UnsignedInteger valueOf(final long value) {
if (value < 0L || value >= (1L << 32)) {
throw new NumberFormatException("Value \"" + value + "\" lies outside the range [" + 0L + "-" + (1L << 32) + ").");
}
return valueOf((int) value);
}
/**
* Returns a {@code long} that represents the unsigned view of the given {@code int} value.
*
* @param value
* The integer whose unsigned value should be converted to a long.
*
* @return a positive long value that represents the given {@code int} as unsigned.
*/
public static long toUnsignedLong(int value) {
return Integer.toUnsignedLong(value);
}
}