2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 Ericsson
4 * Modifications Copyright (C) 2024 OpenInfra Foundation Europe
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 package org.oran.smo.yangtools.parser.model.util;
23 import java.math.BigDecimal;
24 import java.math.BigInteger;
26 import org.oran.smo.yangtools.parser.model.util.DataTypeHelper.YangDataType;
29 * Utility class to deal with numbers in Yang.
31 * @author Mark Hollmann
33 public abstract class NumberHelper {
36 * integer-value = ("-" non-negative-integer-value) / non-negative-integer-value
37 * non-negative-integer-value = "0" / positive-integer-value
38 * positive-integer-value = (non-zero-digit *DIGIT)
39 * non-zero-digit = %x31-39
40 * decimal-value = integer-value ("." zero-integer-value)
41 * zero-integer-value = 1*DIGIT
45 * Extracts a decimal number representing a yang "integer-value" or "decimal-value". Note that a BigDecimal
46 * will be returned even if the underlying number is mathematically integer.
48 public static BigDecimal extractYangIntegerValueOrDecimalValue(final String string) {
49 return new BigDecimal(string);
52 public static final BigDecimal INT8_MIN_VALUE = new BigDecimal("-128");
53 public static final BigDecimal INT16_MIN_VALUE = new BigDecimal("-32768");
54 public static final BigDecimal INT32_MIN_VALUE = new BigDecimal("-2147483648");
55 public static final BigDecimal INT64_MIN_VALUE = new BigDecimal("-9223372036854775808");
57 public static final BigDecimal UINT8_MAX_VALUE = new BigDecimal("255");
58 public static final BigDecimal UINT16_MAX_VALUE = new BigDecimal("65535");
59 public static final BigDecimal UINT32_MAX_VALUE = new BigDecimal("4294967295");
60 public static final BigDecimal UINT64_MAX_VALUE = new BigDecimal("18446744073709551615");
62 public static final BigDecimal INT8_MAX_VALUE = new BigDecimal("127");
63 public static final BigDecimal INT16_MAX_VALUE = new BigDecimal("32767");
64 public static final BigDecimal INT32_MAX_VALUE = new BigDecimal("2147483647");
65 public static final BigDecimal INT64_MAX_VALUE = new BigDecimal("9223372036854775807");
67 public static BigDecimal getMinValueForYangIntegerDataType(final YangDataType yangDataType) {
69 switch (yangDataType) {
74 return BigDecimal.ZERO;
76 return INT8_MIN_VALUE;
78 return INT16_MIN_VALUE;
80 return INT32_MIN_VALUE;
82 return INT64_MIN_VALUE;
84 throw new RuntimeException("Not an integer data type");
88 public static BigDecimal getMaxValueForYangIntegerDataType(final YangDataType yangDataType) {
90 switch (yangDataType) {
92 return UINT8_MAX_VALUE;
94 return UINT16_MAX_VALUE;
96 return UINT32_MAX_VALUE;
98 return UINT64_MAX_VALUE;
100 return INT8_MAX_VALUE;
102 return INT16_MAX_VALUE;
104 return INT32_MAX_VALUE;
106 return INT64_MAX_VALUE;
108 throw new RuntimeException("Not an integer data type");
112 public static BigDecimal getMinValueForYangDecimalDataType(final int digits) {
113 return (digits >= 1 && digits <= 18) ?
114 new BigDecimal("-9223372036854775808").divide(BigDecimal.valueOf(10L).pow(digits)) :
118 public static BigDecimal getMaxValueForYangDecimalDataType(final int digits) {
119 return (digits >= 1 && digits <= 18) ?
120 new BigDecimal("9223372036854775807").divide(BigDecimal.valueOf(10L).pow(digits)) :
125 * Returns the integer value (in a BigInteger) of a default value. Will return null
126 * if the supplied string cannot be translated to a BigInteger.
128 * Special handling applies as follows (taken from the RFC):
130 * "For convenience, when specifying a default value for an integer in a
131 * YANG module, an alternative lexical representation can be used that
132 * represents the value in a hexadecimal or octal notation. The
133 * hexadecimal notation consists of an optional sign ("+" or "-"),
134 * followed by the characters "0x", followed by a number of hexadecimal
135 * digits where letters may be uppercase or lowercase. The octal
136 * notation consists of an optional sign ("+" or "-"), followed by the
137 * character "0", followed by a number of octal digits.
139 * Note that if a default value in a YANG module has a leading zero
140 * ("0"), it is interpreted as an octal number. In the XML encoding, an
141 * integer is always interpreted as a decimal number, and leading zeros
144 public static BigInteger getIntegerDefaultValue(final String stringefiedValue) {
147 if (stringefiedValue.equals("0") || stringefiedValue.equals("+0") || stringefiedValue.equals("-0")) {
148 return BigInteger.ZERO;
149 } else if (stringefiedValue.startsWith("-0x")) {
150 return new BigInteger(stringefiedValue.substring(3), 16).negate();
151 } else if (stringefiedValue.startsWith("+0x")) {
152 return new BigInteger(stringefiedValue.substring(3), 16);
153 } else if (stringefiedValue.startsWith("0x")) {
154 return new BigInteger(stringefiedValue.substring(2), 16);
155 } else if (stringefiedValue.startsWith("-0")) {
156 return new BigInteger(stringefiedValue.substring(2), 8).negate();
157 } else if (stringefiedValue.startsWith("+0")) {
158 return new BigInteger(stringefiedValue.substring(2), 8);
159 } else if (stringefiedValue.startsWith("0")) {
160 return new BigInteger(stringefiedValue.substring(1), 8);
163 return getIntegerValue(stringefiedValue);
165 } catch (final Exception ignored) {
173 * Returns the integer value (in a BigInteger) of a value. Will return null
174 * if the supplied string cannot be translated to a BigInteger.
176 * Note that special default value handling is <b>not</b> applied by this
177 * method, i.e. a leading zero is interpreted as the number zero.
179 public static BigInteger getIntegerValue(final String stringefiedValue) {
181 return new BigInteger(stringefiedValue);
182 } catch (final Exception ignored) {
190 * Returns the decimal value (in a BigDecimal) of a value. Will return null
191 * if the supplied string cannot be translated to a BigDecimal.
193 * Note that special handling (as for integers above) does NOT apply for
196 public static BigDecimal getDecimalValue(final String stringefiedValue) {
198 return new BigDecimal(stringefiedValue);
199 } catch (final Exception ex) {