1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sourceforge.jarduino.message;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
23
24
25
26
27 public interface ArduinoAttrConstraints {
28
29
30
31
32
33
34 Object checkValue(Object pValue) throws ArduinoParserException;
35
36
37
38
39 class ArduinoAttrValueConstraints
40 implements ArduinoAttrConstraints {
41
42
43
44 private Number theMinimum;
45
46
47
48
49 private Number theMaximum;
50
51
52
53
54
55
56 ArduinoAttrValueConstraints(final Number pMinimum,
57 final Number pMaximum) {
58
59 theMinimum = pMinimum;
60 theMaximum = pMaximum;
61 }
62
63
64
65
66
67 Number getMinimum() {
68 return theMinimum;
69 }
70
71
72
73
74
75 Number getMaximum() {
76 return theMaximum;
77 }
78
79 @Override
80 public Object checkValue(final Object pValue) throws ArduinoParserException {
81
82 final Number myValue = (Number) pValue;
83
84
85 final boolean invalid = theMinimum instanceof Double
86 ? myValue.doubleValue() < theMinimum.doubleValue()
87 || myValue.doubleValue() > theMaximum.doubleValue()
88 : myValue.longValue() < theMinimum.longValue()
89 || myValue.longValue() > theMaximum.longValue();
90
91
92 if (invalid) {
93 throw new ArduinoParserException("Attribute breaks constraints", myValue.toString());
94 }
95
96
97 return pValue;
98 }
99
100
101
102
103
104
105
106
107 static ArduinoAttrValueConstraints parseConstraints(final ArduinoAttribute pAttr,
108 final String pConstDef) throws ArduinoParserException {
109
110 final String myMinDef = ArduinoParser.nextToken(pConstDef);
111 final String myMaxDef = ArduinoParser.stripToken(pConstDef, myMinDef);
112
113
114 Number myMin = ArduinoParser.parseNumber(myMinDef);
115 Number myMax = ArduinoParser.parseNumber(myMaxDef);
116
117
118 if (myMin.getClass() != myMax.getClass()) {
119
120 if (myMin instanceof Long) {
121 myMin = myMin.doubleValue();
122 }
123 if (myMax instanceof Long) {
124 myMax = myMax.doubleValue();
125 }
126 }
127
128
129 return ArduinoSignalRange.isZero(myMin) && ArduinoSignalRange.isZero(myMax)
130 ? null
131 : new ArduinoAttrValueConstraints(myMin, myMax);
132 }
133 }
134
135
136
137
138 class ArduinoAttrEnumConstraints
139 implements ArduinoAttrConstraints {
140
141
142
143 private final List<String> theValues;
144
145
146
147
148
149 ArduinoAttrEnumConstraints(final List<String> pValues) {
150 theValues = pValues;
151 }
152
153
154
155
156
157 List<String> getValues() {
158 return theValues;
159 }
160
161 @Override
162 public Object checkValue(final Object pValue) throws ArduinoParserException {
163
164 if (pValue instanceof Long) {
165 final long myValue = (Long) pValue;
166 if (myValue < 0 || myValue >= theValues.size()) {
167 throw new ArduinoParserException("Attribute out of range for enum", pValue.toString());
168 }
169 return theValues.get((int) myValue);
170 }
171
172
173 final String myValue = (String) pValue;
174
175
176 if (!theValues.contains(myValue)) {
177
178 if (myValue.length() == 0 && !theValues.isEmpty()) {
179 return theValues.get(0);
180 }
181 throw new ArduinoParserException("Attribute not valid enum", myValue);
182 }
183
184
185 return pValue;
186 }
187
188
189
190
191
192
193
194 static ArduinoAttrConstraints parseConstraints(final String pConstDef) throws ArduinoParserException {
195
196 final List<String> myEnums = new ArrayList<>();
197
198
199 String myValues = pConstDef;
200 while (myValues.length() > 0) {
201
202 final int myIndex = myValues.indexOf(ArduinoChar.COMMA);
203 if (myIndex == -1) {
204 myEnums.add(ArduinoParser.nextQuotedToken(myValues));
205 return new ArduinoAttrEnumConstraints(myEnums);
206 }
207
208 final String myValue = myValues.substring(0, myIndex).trim();
209 myEnums.add(ArduinoParser.nextQuotedToken(myValue));
210 myValues = myValues.substring(myIndex + 1);
211 }
212 return new ArduinoAttrEnumConstraints(myEnums);
213 }
214 }
215
216
217
218
219
220
221
222
223 static ArduinoAttrConstraints parseConstraints(final ArduinoAttribute pAttr,
224 final String pConstDef) throws ArduinoParserException {
225
226 switch (pAttr.getAttrType()) {
227 case INT:
228 case HEX:
229 case FLOAT:
230 return ArduinoAttrValueConstraints.parseConstraints(pAttr, pConstDef);
231 case ENUM:
232 return ArduinoAttrEnumConstraints.parseConstraints(pConstDef);
233 default:
234 return null;
235 }
236 }
237 }