ff87f0d2eeccfa75ecb91dde8aa764ef6a22fb87
[yangtools.git] / common / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / Uint8.java
1 /*
2  * Copyright (c) 2015 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.common;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import java.io.Serial;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.yangtools.concepts.Either;
18
19 /**
20  * Dedicated type for YANG's 'type uint8' type.
21  *
22  * @author Robert Varga
23  */
24 @Beta
25 @NonNullByDefault
26 public class Uint8 extends Number implements CanonicalValue<Uint8> {
27     public static final class Support extends AbstractCanonicalValueSupport<Uint8> {
28         public Support() {
29             super(Uint8.class);
30         }
31
32         @Override
33         public Either<Uint8, CanonicalValueViolation> fromString(final String str) {
34             try {
35                 return Either.ofFirst(Uint8.valueOf(str));
36             } catch (IllegalArgumentException e) {
37                 return CanonicalValueViolation.variantOf(e);
38             }
39         }
40     }
41
42     private static final CanonicalValueSupport<Uint8> SUPPORT = new Support();
43
44     private static final short MAX_VALUE_SHORT = 255;
45     private static final String MAX_VALUE_STR = "255";
46
47     @Serial
48     private static final long serialVersionUID = 1L;
49
50     private static final @NonNull Uint8[] CACHE;
51
52     static {
53         final Uint8[] c = new Uint8[MAX_VALUE_SHORT + 1];
54         for (int i = 0; i <= MAX_VALUE_SHORT; ++i) {
55             c[i] = new Uint8((byte)i);
56         }
57         CACHE = c;
58     }
59
60     /**
61      * Value of {@code 0}.
62      */
63     public static final Uint8 ZERO = valueOf(0);
64     /**
65      * Value of {@code 1}.
66      */
67     public static final Uint8 ONE = valueOf(1);
68     /**
69      * Value of {@code 2}.
70      */
71     public static final Uint8 TWO = valueOf(2);
72     /**
73      * Value of {@code 10}.
74      */
75     public static final Uint8 TEN = valueOf(10);
76     /**
77      * Value of {@code 255}.
78      */
79     public static final Uint8 MAX_VALUE = valueOf(MAX_VALUE_SHORT);
80
81     private final byte value;
82
83     private Uint8(final byte value) {
84         this.value = value;
85     }
86
87     protected Uint8(final Uint8 other) {
88         this(other.value);
89     }
90
91     private static Uint8 instanceFor(final byte value) {
92         return CACHE[Byte.toUnsignedInt(value)];
93     }
94
95     /**
96      * Returns an {@code Uint8} corresponding to a given bit representation. The argument is interpreted as an
97      * unsigned 8-bit value.
98      *
99      * @param bits unsigned bit representation
100      * @return A Uint8 instance
101      */
102     public static Uint8 fromByteBits(final byte bits) {
103         return instanceFor(bits);
104     }
105
106     /**
107      * Returns an {@code Uint8} corresponding to a given {@code byteVal}. The inverse operation is {@link #byteValue()}.
108      *
109      * @param byteVal byte value
110      * @return A Uint8 instance
111      * @throws IllegalArgumentException if byteVal is less than zero
112      */
113     public static Uint8 valueOf(final byte byteVal) {
114         UintConversions.checkNonNegative(byteVal, MAX_VALUE_STR);
115         return instanceFor(byteVal);
116     }
117
118     /**
119      * Returns an {@code Uint8} corresponding to a given {@code shortVal}. The inverse operation is
120      * {@link #shortValue()}.
121      *
122      * @param shortVal short value
123      * @return A Uint8 instance
124      * @throws IllegalArgumentException if shortVal is less than zero or greater than 255.
125      */
126     public static Uint8 valueOf(final short shortVal) {
127         UintConversions.checkRange(shortVal, MAX_VALUE_SHORT);
128         return instanceFor((byte)shortVal);
129     }
130
131     /**
132      * Returns an {@code Uint8} corresponding to a given {@code intVal}. The inverse operation is {@link #intValue()}.
133      *
134      * @param intVal int value
135      * @return A Uint8 instance
136      * @throws IllegalArgumentException if intVal is less than zero or greater than 255.
137      */
138     public static Uint8 valueOf(final int intVal) {
139         UintConversions.checkRange(intVal, MAX_VALUE_SHORT);
140         return instanceFor((byte)intVal);
141     }
142
143     /**
144      * Returns an {@code Uint8} corresponding to a given {@code longVal}. The inverse operation is
145      * {@link #longValue()}.
146      *
147      * @param longVal long value
148      * @return A Uint8 instance
149      * @throws IllegalArgumentException if intVal is less than zero or greater than 255.
150      */
151     public static Uint8 valueOf(final long longVal) {
152         UintConversions.checkRange(longVal, MAX_VALUE_SHORT);
153         return instanceFor((byte)longVal);
154     }
155
156     /**
157      * Returns an {@code Uint8} corresponding to a given {@code uint}.
158      *
159      * @param uint Uint16 value
160      * @return A Uint8 instance
161      * @throws NullPointerException if uint is null
162      * @throws IllegalArgumentException if uint is greater than 255.
163      */
164     public static Uint8 valueOf(final Uint16 uint) {
165         return valueOf(uint.intValue());
166     }
167
168     /**
169      * Returns an {@code Uint8} corresponding to a given {@code uint}.
170      *
171      * @param uint Uint32 value
172      * @return A Uint8 instance
173      * @throws NullPointerException if uint is null
174      * @throws IllegalArgumentException if uint is greater than 255.
175      */
176     public static Uint8 valueOf(final Uint32 uint) {
177         return valueOf(uint.longValue());
178     }
179
180     /**
181      * Returns an {@code Uint8} corresponding to a given {@code uint}.
182      *
183      * @param uint Uint64 value
184      * @return A Uint8 instance
185      * @throws NullPointerException if uint is null
186      * @throws IllegalArgumentException if uint is greater than 255.
187      */
188     public static Uint8 valueOf(final Uint64 uint) {
189         return valueOf(uint.longValue());
190     }
191
192     /**
193      * Returns an {@code Uint8} holding the value of the specified {@code String}, parsed as an unsigned {@code short}
194      * value.
195      *
196      * @param string String to parse
197      * @return A Uint8 instance
198      * @throws NullPointerException if string is null
199      * @throws IllegalArgumentException if the parsed value is less than zero or greater than 255
200      * @throws NumberFormatException if the string does not contain a parsable unsigned {@code short} value.
201      */
202     public static Uint8 valueOf(final String string) {
203         return valueOf(string, 10);
204     }
205
206     /**
207      * Returns an {@code Uint8} holding the value of the specified {@code String}, parsed as an unsigned {@code short}
208      * value.
209      *
210      * @param string String to parse
211      * @param radix Radix to use
212      * @return A Uint8 instance
213      * @throws NullPointerException if string is null
214      * @throws IllegalArgumentException if the parsed value is less than zero or greater than 255
215      * @throws NumberFormatException if the string does not contain a parsable unsigned {@code short} value, or if the
216      *                               {@code radix} is outside of allowed range.
217      */
218     public static Uint8 valueOf(final String string, final int radix) {
219         return valueOf(Short.parseShort(requireNonNull(string), radix));
220     }
221
222     /**
223      * Returns an {@code Uint8} corresponding to a given {@code byteVal} if it is representable. If the value is
224      * negative {@link #ZERO} will be returned.
225      *
226      * @param byteVal byte value
227      * @return A Uint8 instance
228      */
229     public static Uint8 saturatedOf(final byte byteVal) {
230         return byteVal <= 0 ? Uint8.ZERO : instanceFor(byteVal);
231     }
232
233     /**
234      * Returns an {@code Uint8} corresponding to a given {@code shortVal} if it is representable. If the value is
235      * negative {@link #ZERO} will be returned. If the value is greater than 255, {@link #MAX_VALUE} will be returned.
236      *
237      * @param shortVal short value
238      * @return A Uint8 instance
239      */
240     public static Uint8 saturatedOf(final short shortVal) {
241         if (shortVal <= 0) {
242             return Uint8.ZERO;
243         }
244         if (shortVal >= MAX_VALUE_SHORT) {
245             return Uint8.MAX_VALUE;
246         }
247         return instanceFor((byte) shortVal);
248     }
249
250     /**
251      * Returns an {@code Uint8} corresponding to a given {@code intVal} if it is representable. If the value is
252      * negative {@link #ZERO} will be returned. If the value is greater than 255, {@link #MAX_VALUE} will be returned.
253      *
254      * @param intVal int value
255      * @return A Uint8 instance
256      */
257     public static Uint8 saturatedOf(final int intVal) {
258         if (intVal <= 0) {
259             return Uint8.ZERO;
260         }
261         if (intVal >= MAX_VALUE_SHORT) {
262             return Uint8.MAX_VALUE;
263         }
264         return instanceFor((byte) intVal);
265     }
266
267     /**
268      * Returns an {@code Uint8} corresponding to a given {@code longVal} if it is representable. If the value is
269      * negative {@link #ZERO} will be returned. If the value is greater than 255, {@link #MAX_VALUE} will be returned.
270      *
271      * @param longVal long value
272      * @return A Uint8 instance
273      */
274     public static Uint8 saturatedOf(final long longVal) {
275         if (longVal <= 0) {
276             return Uint8.ZERO;
277         }
278         if (longVal >= MAX_VALUE_SHORT) {
279             return Uint8.MAX_VALUE;
280         }
281         return instanceFor((byte) longVal);
282     }
283
284     /**
285      * {@inheritDoc}
286      *
287      * <p>
288      * The inverse operation is {@link #fromByteBits(byte)}. In case this value is greater than {@link Byte#MAX_VALUE},
289      * the returned value will be equal to {@code this - 2^8}.
290      */
291     @Override
292     public final byte byteValue() {
293         return value;
294     }
295
296     @Override
297     public final int intValue() {
298         return Byte.toUnsignedInt(value);
299     }
300
301     @Override
302     public final long longValue() {
303         return Byte.toUnsignedLong(value);
304     }
305
306     @Override
307     public final float floatValue() {
308         return intValue();
309     }
310
311     @Override
312     public final double doubleValue() {
313         return intValue();
314     }
315
316     @Override
317     @SuppressWarnings("checkstyle:parameterName")
318     public final int compareTo(final Uint8 o) {
319         return Byte.compareUnsigned(value, o.value);
320     }
321
322     @Override
323     public final String toCanonicalString() {
324         return Integer.toString(intValue());
325     }
326
327     @Override
328     public final CanonicalValueSupport<Uint8> support() {
329         return SUPPORT;
330     }
331
332     /**
333      * Convert this value to a {@code short}.
334      *
335      * @return A short
336      */
337     public final short toJava() {
338         return shortValue();
339     }
340
341     /**
342      * Convert this value to a {@code Uint16}.
343      *
344      * @return A Uint16
345      */
346     public final Uint16 toUint16() {
347         return Uint16.fromShortBits(shortValue());
348     }
349
350     /**
351      * Convert this value to a {@code Uint32}.
352      *
353      * @return A Uint32
354      */
355     public final Uint32 toUint32() {
356         return Uint32.fromIntBits(intValue());
357     }
358
359     /**
360      * Convert this value to a {@code Uint64}.
361      *
362      * @return A Uint64
363      */
364     public final Uint64 toUint64() {
365         return Uint64.fromLongBits(longValue());
366     }
367
368     @Override
369     public final int hashCode() {
370         return Byte.hashCode(value);
371     }
372
373     @Override
374     public final boolean equals(final @Nullable Object obj) {
375         return this == obj || obj instanceof Uint8 other && value == other.value;
376     }
377
378     /**
379      * A slightly faster version of {@link #equals(Object)}.
380      *
381      * @param obj Uint8 object
382      * @return {@code true} if this object is the same as the obj argument; {@code false} otherwise.
383      */
384     public final boolean equals(final @Nullable Uint8 obj) {
385         return this == obj || obj != null && value == obj.value;
386     }
387
388     @Override
389     public final String toString() {
390         return toCanonicalString();
391     }
392
393     @Serial
394     private Object readResolve() {
395         return instanceFor(value);
396     }
397 }