Add Uint saturated converters 61/92861/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 28 Sep 2020 16:57:15 +0000 (18:57 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 2 Oct 2020 14:45:33 +0000 (16:45 +0200)
There are a number of places where we need to perform a saturated
conversion, i.e. when we have a 'long' count and need to put it into
a Uint32 field. Add methods to deal with that.

JIRA: YANGTOOLS-1135
Change-Id: Ia0bb2e9f0400d975ce1f4b150704dcf526d3bc82
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 254b2d0b480ae2ddec8b5db9b97cb5fef084d93c)

yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint16.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint32.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint64.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/Uint8.java
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/Uint16Test.java
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/Uint32Test.java
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/Uint64Test.java
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/Uint8Test.java

index 491559859ded67b3e474b3d455eac3bbaf6a6c7c..d9b6ad974be2dd0f6295977b8875f3d44ae2ce98 100644 (file)
@@ -234,6 +234,62 @@ public class Uint16 extends Number implements CanonicalValue<Uint16> {
         return valueOf(Integer.parseInt(requireNonNull(string), radix));
     }
 
+    /**
+     * Returns an {@code Uint16} corresponding to a given {@code byteVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param byteVal byte value
+     * @return A Uint16 instance
+     */
+    public static Uint16 saturatedOf(final byte byteVal) {
+        return byteVal < 0 ? Uint16.ZERO : instanceFor(byteVal);
+    }
+
+    /**
+     * Returns an {@code Uint16} corresponding to a given {@code shortVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param shortVal short value
+     * @return A Uint16 instance
+     */
+    public static Uint16 saturatedOf(final short shortVal) {
+        return shortVal < 0 ? Uint16.ZERO : instanceFor(shortVal);
+    }
+
+    /**
+     * Returns an {@code Uint16} corresponding to a given {@code intVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 65535, {@link #MAX_VALUE} will be returned.
+     *
+     * @param intVal int value
+     * @return A Uint16 instance
+     */
+    public static Uint16 saturatedOf(final int intVal) {
+        if (intVal < 0) {
+            return Uint16.ZERO;
+        }
+        if (intVal >= MAX_VALUE_INT) {
+            return Uint16.MAX_VALUE;
+        }
+        return instanceFor((short) intVal);
+    }
+
+    /**
+     * Returns an {@code Uint16} corresponding to a given {@code longVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 65535, {@link #MAX_VALUE} will be returned.
+     *
+     * @param longVal long value
+     * @return A Uint16 instance
+     */
+    public static Uint16 saturatedOf(final long longVal) {
+        if (longVal < 0) {
+            return Uint16.ZERO;
+        }
+        if (longVal >= MAX_VALUE_INT) {
+            return Uint16.MAX_VALUE;
+        }
+        return instanceFor((short) longVal);
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -328,6 +384,10 @@ public class Uint16 extends Number implements CanonicalValue<Uint16> {
         return Uint64.fromLongBits(longValue());
     }
 
+    public final Uint8 toSaturatedUint8() {
+        return Uint8.saturatedOf(toJava());
+    }
+
     @Override
     public final int hashCode() {
         return Short.hashCode(value);
index 6b3b39291483b9ce191b953a49d74709480a3bd4..5fa071378de0f3c5f47b163984ebecea9f9c46ad 100644 (file)
@@ -245,6 +245,57 @@ public class Uint32 extends Number implements CanonicalValue<Uint32> {
         return instanceFor(Integer.parseUnsignedInt(requireNonNull(string), radix));
     }
 
+    /**
+     * Returns an {@code Uint32} corresponding to a given {@code byteVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param byteVal byte value
+     * @return A Uint32 instance
+     */
+    public static Uint32 saturatedOf(final byte byteVal) {
+        return byteVal < 0 ? Uint32.ZERO : instanceFor(byteVal);
+    }
+
+    /**
+     * Returns an {@code Uint32} corresponding to a given {@code shortVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param shortVal short value
+     * @return A Uint32 instance
+     */
+    public static Uint32 saturatedOf(final short shortVal) {
+        return shortVal < 0 ? Uint32.ZERO : instanceFor(shortVal);
+    }
+
+    /**
+     * Returns an {@code Uint32} corresponding to a given {@code intVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param intVal int value
+     * @return A Uint32 instance
+     */
+    public static Uint32 saturatedOf(final int intVal) {
+        return intVal < 0 ? Uint32.ZERO : instanceFor(intVal);
+    }
+
+    /**
+     * Returns an {@code Uint32} corresponding to a given {@code longVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 4294967295, {@link #MAX_VALUE} will be
+     * returned.
+     *
+     * @param longVal long value
+     * @return A Uint32 instance
+     */
+    public static Uint32 saturatedOf(final long longVal) {
+        if (longVal < 0) {
+            return Uint32.ZERO;
+        }
+        if (longVal >= MAX_VALUE_LONG) {
+            return Uint32.MAX_VALUE;
+        }
+        return instanceFor((int) longVal);
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -344,6 +395,16 @@ public class Uint32 extends Number implements CanonicalValue<Uint32> {
         return Uint64.fromLongBits(longValue());
     }
 
+    public final Uint8 toSaturatedUint8() {
+        return Uint8.saturatedOf(toJava());
+    }
+
+    public final Uint16 toSaturatedUint16() {
+        return Uint16.saturatedOf(toJava());
+    }
+
+    // FIXME: more saturated conversions
+
     @Override
     public final int hashCode() {
         return Integer.hashCode(value);
index 6d537fd009ac49f27c1ae05d35b4a7c4afd29ea0..6ff71de790a101b6f2692a847b16f514dd550695 100644 (file)
@@ -260,6 +260,66 @@ public class Uint64 extends Number implements CanonicalValue<Uint64> {
         return instanceFor(Long.parseUnsignedLong(requireNonNull(string), radix));
     }
 
+    /**
+     * Returns an {@code Uint64} corresponding to a given {@code byteVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param byteVal byte value
+     * @return A Uint64 instance
+     */
+    public static Uint64 saturatedOf(final byte byteVal) {
+        return byteVal < 0 ? Uint64.ZERO : instanceFor(byteVal);
+    }
+
+    /**
+     * Returns an {@code Uint32} corresponding to a given {@code shortVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param shortVal short value
+     * @return A Uint32 instance
+     */
+    public static Uint64 saturatedOf(final short shortVal) {
+        return shortVal < 0 ? Uint64.ZERO : instanceFor(shortVal);
+    }
+
+    /**
+     * Returns an {@code Uint64} corresponding to a given {@code intVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param intVal int value
+     * @return A Uint64 instance
+     */
+    public static Uint64 saturatedOf(final int intVal) {
+        return intVal < 0 ? Uint64.ZERO : instanceFor(intVal);
+    }
+
+    /**
+     * Returns an {@code Uint64} corresponding to a given {@code longVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param longVal long value
+     * @return A Uint64 instance
+     */
+    public static Uint64 saturatedOf(final long longVal) {
+        return longVal < 0 ? Uint64.ZERO : instanceFor(longVal);
+    }
+
+    /**
+     * Returns an {@code Uint64} corresponding to a given {@code longVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 18446744073709551615, {@link #MAX_VALUE}
+     * will be returned.
+     *
+     * @param bigInt BigInteger value
+     * @return A Uint64 instance
+     * @throws NullPointerException if bigInt is null
+     */
+    public static Uint64 saturatedOf(final BigInteger bigInt) {
+        if (bigInt.signum() < 0) {
+            return Uint64.ZERO;
+        }
+        return bigInt.bitLength() > Long.SIZE ? Uint64.MAX_VALUE : instanceFor(bigInt.longValue());
+    }
+
     @Override
     public final int intValue() {
         return (int)value;
index 99548c3327b6c7ee01b2893eb2731ac28446cf69..7766d5e4cc10e71914d1c6dc77959e65b35708b0 100644 (file)
@@ -217,6 +217,68 @@ public class Uint8 extends Number implements CanonicalValue<Uint8> {
         return valueOf(Short.parseShort(requireNonNull(string), radix));
     }
 
+    /**
+     * Returns an {@code Uint8} corresponding to a given {@code byteVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned.
+     *
+     * @param byteVal byte value
+     * @return A Uint8 instance
+     */
+    public static Uint8 saturatedOf(final byte byteVal) {
+        return byteVal < 0 ? Uint8.ZERO : instanceFor(byteVal);
+    }
+
+    /**
+     * Returns an {@code Uint8} corresponding to a given {@code shortVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 255, {@link #MAX_VALUE} will be returned.
+     *
+     * @param shortVal short value
+     * @return A Uint8 instance
+     */
+    public static Uint8 saturatedOf(final short shortVal) {
+        if (shortVal < 0) {
+            return Uint8.ZERO;
+        }
+        if (shortVal >= MAX_VALUE_SHORT) {
+            return Uint8.MAX_VALUE;
+        }
+        return instanceFor((byte) shortVal);
+    }
+
+    /**
+     * Returns an {@code Uint8} corresponding to a given {@code intVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 255, {@link #MAX_VALUE} will be returned.
+     *
+     * @param intVal int value
+     * @return A Uint8 instance
+     */
+    public static Uint8 saturatedOf(final int intVal) {
+        if (intVal < 0) {
+            return Uint8.ZERO;
+        }
+        if (intVal >= MAX_VALUE_SHORT) {
+            return Uint8.MAX_VALUE;
+        }
+        return instanceFor((byte) intVal);
+    }
+
+    /**
+     * Returns an {@code Uint8} corresponding to a given {@code longVal} if it is representable. If the value is
+     * negative {@link #ZERO} will be returned. If the value is greater than 255, {@link #MAX_VALUE} will be returned.
+     *
+     * @param longVal long value
+     * @return A Uint8 instance
+     */
+    public static Uint8 saturatedOf(final long longVal) {
+        if (longVal < 0) {
+            return Uint8.ZERO;
+        }
+        if (longVal >= MAX_VALUE_SHORT) {
+            return Uint8.MAX_VALUE;
+        }
+        return instanceFor((byte) longVal);
+    }
+
     /**
      * {@inheritDoc}
      *
index 17f7ec2976feeecdfb1982123881486ebeeda349..fc9f7a59fc03f1b6858839331cbd232f680be516 100644 (file)
@@ -33,6 +33,18 @@ public class Uint16Test {
         assertEquals(0, Uint16.valueOf("0").intValue());
     }
 
+    @Test
+    public void testSaturatedOf() {
+        assertEquals(127, Uint16.saturatedOf((byte) 127).byteValue());
+        assertEquals(127, Uint16.saturatedOf((short) 127).byteValue());
+        assertEquals(127, Uint16.saturatedOf(127).byteValue());
+        assertEquals(127, Uint16.saturatedOf(127L).byteValue());
+
+        assertEquals(255, Uint16.saturatedOf((short) 255).intValue());
+        assertEquals(255, Uint16.saturatedOf(255).intValue());
+        assertEquals(255L, Uint16.saturatedOf(255L).longValue());
+    }
+
     @Test
     public void testCompareTo() {
         final Uint16 five = Uint16.valueOf(5);
@@ -128,12 +140,20 @@ public class Uint16Test {
         assertThrows(IllegalArgumentException.class, () -> Uint16.valueOf((short)-1));
         assertThrows(IllegalArgumentException.class, () -> Uint16.valueOf(-1));
         assertThrows(IllegalArgumentException.class, () -> Uint16.valueOf(-1L));
+
+        assertEquals(Uint16.ZERO, Uint16.saturatedOf((byte)-1));
+        assertEquals(Uint16.ZERO, Uint16.saturatedOf((short)-1));
+        assertEquals(Uint16.ZERO, Uint16.saturatedOf(-1));
+        assertEquals(Uint16.ZERO, Uint16.saturatedOf(-1L));
     }
 
     @Test
     public void testLargeValues() {
         assertThrows(IllegalArgumentException.class, () -> Uint16.valueOf(65536));
         assertThrows(IllegalArgumentException.class, () -> Uint16.valueOf(65536L));
+
+        assertEquals(Uint16.MAX_VALUE, Uint16.saturatedOf(65536));
+        assertEquals(Uint16.MAX_VALUE, Uint16.saturatedOf(65536L));
     }
 
     @Test
index b1a122647a1f007c9ca31e23749614842a0817d0..1eb936886c0f95d17cc91497de241998cf6e4b3d 100644 (file)
@@ -31,6 +31,18 @@ public class Uint32Test {
         assertEquals(0, Uint32.valueOf("0").intValue());
     }
 
+    @Test
+    public void testSaturatedOf() {
+        assertEquals(127, Uint32.saturatedOf((byte) 127).byteValue());
+        assertEquals(127, Uint32.saturatedOf((short) 127).byteValue());
+        assertEquals(127, Uint32.saturatedOf(127).byteValue());
+        assertEquals(127, Uint32.saturatedOf(127L).byteValue());
+
+        assertEquals(255, Uint32.saturatedOf((short) 255).intValue());
+        assertEquals(255, Uint32.saturatedOf(255).intValue());
+        assertEquals(255L, Uint32.saturatedOf(255L).longValue());
+    }
+
     @Test
     public void testCompareTo() {
         final Uint32 five = Uint32.valueOf(5);
@@ -134,11 +146,18 @@ public class Uint32Test {
         assertThrows(IllegalArgumentException.class, () -> Uint32.valueOf((short)-1));
         assertThrows(IllegalArgumentException.class, () -> Uint32.valueOf(-1));
         assertThrows(IllegalArgumentException.class, () -> Uint32.valueOf(-1L));
+
+        assertEquals(Uint32.ZERO, Uint32.saturatedOf((byte)-1));
+        assertEquals(Uint32.ZERO, Uint32.saturatedOf((short)-1));
+        assertEquals(Uint32.ZERO, Uint32.saturatedOf(-1));
+        assertEquals(Uint32.ZERO, Uint32.saturatedOf(-1L));
     }
 
     @Test
     public void testLargeValues() {
         assertThrows(IllegalArgumentException.class, () -> Uint32.valueOf(4294967296L));
+
+        assertEquals(Uint32.MAX_VALUE, Uint32.saturatedOf(4294967296L));
     }
 
     @Test
index 521eb33690df0a449a620af4b7a279900081b836..cc79d621c02c12c0d8bccee631f580295f902856 100644 (file)
@@ -34,6 +34,19 @@ public class Uint64Test {
         assertEquals(2170205184637009920L, Uint64.valueOf(new BigInteger("2170205184637009920")).longValue());
     }
 
+    @Test
+    public void testSaturatedOf() {
+        assertEquals(127, Uint64.saturatedOf((byte) 127).byteValue());
+        assertEquals(127, Uint64.saturatedOf((short) 127).byteValue());
+        assertEquals(127, Uint64.saturatedOf(127).byteValue());
+        assertEquals(127, Uint64.saturatedOf(127L).byteValue());
+
+        assertEquals(255, Uint64.saturatedOf((short) 255).intValue());
+        assertEquals(255, Uint64.saturatedOf(255).intValue());
+        assertEquals(255L, Uint64.saturatedOf(255L).longValue());
+        assertEquals(2170205184637009920L, Uint64.saturatedOf(new BigInteger("2170205184637009920")).longValue());
+    }
+
     @Test
     public void testCompareTo() {
         final Uint64 five = Uint64.valueOf(5);
@@ -144,12 +157,20 @@ public class Uint64Test {
         assertThrows(IllegalArgumentException.class, () -> Uint64.valueOf(-1));
         assertThrows(IllegalArgumentException.class, () -> Uint64.valueOf(-1L));
         assertThrows(IllegalArgumentException.class, () -> Uint64.valueOf(new BigInteger("-1")));
+
+        assertEquals(Uint64.ZERO, Uint64.saturatedOf((byte)-1));
+        assertEquals(Uint64.ZERO, Uint64.saturatedOf((short)-1));
+        assertEquals(Uint64.ZERO, Uint64.saturatedOf(-1));
+        assertEquals(Uint64.ZERO, Uint64.saturatedOf(-1L));
+        assertEquals(Uint64.ZERO, Uint64.saturatedOf(new BigInteger("-1")));
     }
 
     @Test
     public void testLargeValues() {
         final BigInteger big = new BigInteger("10000000000000000", 16);
         assertThrows(IllegalArgumentException.class, () -> Uint64.valueOf(big));
+
+        assertEquals(Uint64.MAX_VALUE, Uint64.saturatedOf(big));
     }
 
     @Test
index 83c516ceeabb72220201a57d043b05fd7b55ea01..2e316d1a0388d95bf577502848f4006e1bc178c7 100644 (file)
@@ -29,6 +29,18 @@ public class Uint8Test {
         assertEquals(0, Uint8.valueOf("0").intValue());
     }
 
+    @Test
+    public void testSaturatedOf() {
+        assertEquals(127, Uint8.saturatedOf((byte) 127).byteValue());
+        assertEquals(127, Uint8.saturatedOf((short) 127).byteValue());
+        assertEquals(127, Uint8.saturatedOf(127).byteValue());
+        assertEquals(127, Uint8.saturatedOf(127L).byteValue());
+
+        assertEquals(255, Uint8.saturatedOf((short) 255).intValue());
+        assertEquals(255, Uint8.saturatedOf(255).intValue());
+        assertEquals(255L, Uint8.saturatedOf(255L).longValue());
+    }
+
     @Test
     public void testCompareTo() {
         final Uint8 five = Uint8.valueOf(5);
@@ -119,6 +131,11 @@ public class Uint8Test {
         assertThrows(IllegalArgumentException.class, () -> Uint8.valueOf((short)-1));
         assertThrows(IllegalArgumentException.class, () -> Uint8.valueOf(-1));
         assertThrows(IllegalArgumentException.class, () -> Uint8.valueOf(-1L));
+
+        assertEquals(Uint8.ZERO, Uint8.saturatedOf((byte)-1));
+        assertEquals(Uint8.ZERO, Uint8.saturatedOf((short)-1));
+        assertEquals(Uint8.ZERO, Uint8.saturatedOf(-1));
+        assertEquals(Uint8.ZERO, Uint8.saturatedOf(-1L));
     }
 
     @Test
@@ -126,6 +143,10 @@ public class Uint8Test {
         assertThrows(IllegalArgumentException.class, () -> Uint8.valueOf((short)256));
         assertThrows(IllegalArgumentException.class, () -> Uint8.valueOf(256));
         assertThrows(IllegalArgumentException.class, () -> Uint8.valueOf(256L));
+
+        assertEquals(Uint8.MAX_VALUE, Uint8.saturatedOf(Short.MAX_VALUE));
+        assertEquals(Uint8.MAX_VALUE, Uint8.saturatedOf(Integer.MAX_VALUE));
+        assertEquals(Uint8.MAX_VALUE, Uint8.saturatedOf(Long.MAX_VALUE));
     }
 
     @Test