1 /*******************************************************************************
2 * jArduino: Arduino C++ Code Generation From Java
3 * Copyright 2020 Tony Washer
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ******************************************************************************/
17 package net.sourceforge.jarduino.message;
18
19 import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
20
21 /**
22 * Arduino Signal Range.
23 */
24 public final class ArduinoSignalRange {
25 /**
26 * The start character.
27 */
28 private static final char START = '[';
29
30 /**
31 * The end character.
32 */
33 private static final char END = ']';
34
35 /**
36 * the maximum value of the signal.
37 */
38 private final Number theMaximum;
39
40 /**
41 * the minimum value of the signal.
42 */
43 private final Number theMinimum;
44
45 /**
46 * Constructor.
47 * @param pMinimum the min value
48 * @param pMaximum the max value
49 */
50 private ArduinoSignalRange(final Number pMinimum,
51 final Number pMaximum) {
52 /* Store values */
53 theMinimum = pMinimum;
54 theMaximum = pMaximum;
55 }
56
57 /**
58 * Obtain the maximum.
59 * @return the maximum
60 */
61 public Number getMaximum() {
62 return theMaximum;
63 }
64
65 /**
66 * Obtain the minimum.
67 * @return the minimum
68 */
69 public Number getMinimum() {
70 return theMinimum;
71 }
72
73 /**
74 * is the range unbounded?
75 * @return true/false
76 */
77 public boolean unBounded() {
78 return isZero(theMinimum) && isZero(theMaximum);
79 }
80
81 /**
82 * is the number zero?
83 * @param pNumber the number
84 * @return true/false
85 */
86 static boolean isZero(final Number pNumber) {
87 return pNumber instanceof Double
88 ? pNumber.doubleValue() == 0.0
89 : pNumber.longValue() == 0;
90 }
91
92 /**
93 * Does this range use floats?
94 * @return true/false
95 */
96 public boolean isFloat() {
97 return theMinimum instanceof Double;
98 }
99
100 /**
101 * Parse range.
102 * @param pRangeDef the range representation
103 * @return the range
104 * @throws ArduinoParserException on error
105 */
106 static ArduinoSignalRange parseRange(final String pRangeDef) throws ArduinoParserException {
107 /* Remove surrounding brackets */
108 if (pRangeDef.charAt(0) != START
109 || pRangeDef.charAt(pRangeDef.length() - 1) != END) {
110 throw new ArduinoParserException("Missing surrounding []s", pRangeDef);
111 }
112 final String myFactors = pRangeDef.substring(1, pRangeDef.length() - 1);
113
114 /* Split out factors */
115 final int myIndex = myFactors.indexOf(ArduinoChar.PIPE);
116 if (myIndex == -1) {
117 throw new ArduinoParserException("Missing " + ArduinoChar.PIPE + " separator", pRangeDef);
118 }
119
120 /* Parse the numbers */
121 final String myMin = myFactors.substring(0, myIndex);
122 final String myMax = myFactors.substring(myIndex + 1);
123 Number myMinimum = ArduinoParser.parseNumber(myMin);
124 Number myMaximum = ArduinoParser.parseNumber(myMax);
125
126 /* Make sure that if either value is double, both are */
127 if (myMinimum.getClass() != myMaximum.getClass()) {
128 /* Convert longs to doubles */
129 if (myMinimum instanceof Long) {
130 myMinimum = myMinimum.doubleValue();
131 }
132 if (myMaximum instanceof Long) {
133 myMaximum = myMaximum.doubleValue();
134 }
135 }
136
137 /* return the parsed Range */
138 return new ArduinoSignalRange(myMinimum, myMaximum);
139 }
140
141 @Override
142 public String toString() {
143 return "" + START + theMinimum + ArduinoChar.PIPE + theMaximum + END;
144 }
145 }