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.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Objects;
24
25 import net.sourceforge.jarduino.ArduinoException;
26 import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrObject;
27 import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
28
29
30
31
32 public final class ArduinoSignal
33 implements ArduinoNamedObject, ArduinoAttrObject {
34
35
36
37 static final String MARKER = "SG_";
38
39
40
41
42 private static final char MULTI1 = 'M';
43
44
45
46
47 private static final char MULTI2 = 'm';
48
49
50
51
52 public static final Long MULTI_NONE = -1L;
53
54
55
56
57 private final ArduinoMessage theOwner;
58
59
60
61
62 private final String theName;
63
64
65
66
67 private final String theUnits;
68
69
70
71
72 private final ArduinoSignalDefinition theDefinition;
73
74
75
76
77 private final ArduinoSignalFactor theFactor;
78
79
80
81
82 private final ArduinoSignalRange theRange;
83
84
85
86
87 private final List<ArduinoNode> theReceivers;
88
89
90
91
92 private final Map<ArduinoAttribute, Object> theAttributes;
93
94
95
96
97 private ArduinoValues theValues;
98
99
100
101
102 private boolean isMultiplex;
103
104
105
106
107 private Long theMultiplexId;
108
109
110
111
112
113
114
115
116
117
118 private ArduinoSignal(final ArduinoMessage pOwner,
119 final String pName,
120 final ArduinoSignalDefinition pDef,
121 final ArduinoSignalFactor pFactor,
122 final ArduinoSignalRange pRange,
123 final String pUnits) {
124
125 theOwner = pOwner;
126 theName = pName;
127 theDefinition = pDef;
128 theFactor = pFactor;
129 theRange = pRange;
130 theUnits = pUnits;
131 isMultiplex = false;
132 theMultiplexId = MULTI_NONE;
133
134
135 theReceivers = new ArrayList<>();
136 theAttributes = new HashMap<>();
137 }
138
139
140
141
142
143
144
145
146 private void parseReceivers(final ArduinoSystem pSystem,
147 final String pReceivers) throws ArduinoParserException {
148
149 String myReceivers = pReceivers;
150 while (myReceivers.length() > 0) {
151
152 final int myIndex = myReceivers.indexOf(ArduinoChar.COMMA);
153 if (myIndex == -1) {
154 theReceivers.add(pSystem.findNodeByName(myReceivers.trim()));
155 return;
156 }
157 final String myNode = myReceivers.substring(0, myIndex).trim();
158 theReceivers.add(pSystem.findNodeByName(myNode));
159 myReceivers = myReceivers.substring(myIndex + 1);
160 }
161 }
162
163
164
165
166
167 public ArduinoMessage getOwner() {
168 return theOwner;
169 }
170
171 @Override
172 public String getName() {
173 return theName;
174 }
175
176
177
178
179
180 public String getUnits() {
181 return theUnits;
182 }
183
184
185
186
187
188 public ArduinoSignalDefinition getDefinition() {
189 return theDefinition;
190 }
191
192
193
194
195
196 public ArduinoSignalFactor getFactor() {
197 return theFactor;
198 }
199
200
201
202
203
204 public ArduinoSignalRange getRange() {
205 return theRange;
206 }
207
208
209
210
211
212 public boolean isFloat() {
213 return theFactor.isFloat() || theRange.isFloat();
214 }
215
216
217
218
219
220 public boolean isSigned() {
221 return !isFloat() && theDefinition.getDataType().isSigned();
222 }
223
224
225
226
227
228 public ArduinoValues getValues() {
229 return theValues;
230 }
231
232
233
234
235
236 void setValues(final ArduinoValues pValues) {
237 theValues = pValues;
238 }
239
240
241
242
243
244 public boolean isMultiplex() {
245 return isMultiplex;
246 }
247
248
249
250
251 private void setMultiplex() {
252 isMultiplex = true;
253 }
254
255
256
257
258
259 public Long getMultiplexId() {
260 return theMultiplexId;
261 }
262
263
264
265
266
267 public void setMultiplexId(final Long pId) {
268 theMultiplexId = pId;
269 }
270
271
272
273
274
275 public List<ArduinoNode> getReceivers() {
276 return theReceivers;
277 }
278
279
280
281
282
283
284
285 void setAttrValue(final ArduinoAttribute pAttr,
286 final Object pValue) throws ArduinoParserException {
287
288 if (theAttributes.containsKey(pAttr)) {
289 throw new ArduinoParserException("Duplicate Attribute", pAttr.getName());
290 }
291
292
293 theAttributes.put(pAttr, pValue);
294 }
295
296 @Override
297 public Object getAttrValue(final ArduinoAttribute pAttr) {
298 final Object myValue = theAttributes.get(pAttr);
299 return myValue == null ? pAttr.getDefault() : myValue;
300 }
301
302
303
304
305
306
307
308 static void parseSignal(final ArduinoMessage pOwner,
309 final String pSignalDef) throws ArduinoException {
310
311 final int myIndex = pSignalDef.indexOf(ArduinoChar.COLON);
312 if (myIndex == -1) {
313 throw new ArduinoException("Missing " + ArduinoChar.COLON + " separator", pSignalDef);
314 }
315 String myHdr = pSignalDef.substring(0, myIndex);
316 String myLine = pSignalDef.substring(myIndex + 1).trim();
317
318
319 final String myMarker = ArduinoParser.nextToken(myHdr);
320 myHdr = ArduinoParser.stripToken(myHdr, myMarker);
321 if (!myMarker.equals(MARKER)) {
322 throw new ArduinoException("Invalid marker", pSignalDef);
323 }
324
325
326 final String myName = ArduinoParser.nextToken(myHdr);
327 myHdr = ArduinoParser.stripToken(myHdr, myName);
328
329
330 try {
331
332 final String myDataDef = ArduinoParser.nextToken(myLine);
333 myLine = ArduinoParser.stripToken(myLine, myDataDef);
334 final ArduinoSignalDefinition myDef = ArduinoSignalDefinition.parseDefinition(myDataDef);
335
336
337 final String myFactorDef = ArduinoParser.nextToken(myLine);
338 myLine = ArduinoParser.stripToken(myLine, myFactorDef);
339 final ArduinoSignalFactor myFactor = ArduinoSignalFactor.parseFactors(myFactorDef);
340
341
342 final String myRangeDef = ArduinoParser.nextToken(myLine);
343 myLine = ArduinoParser.stripToken(myLine, myRangeDef);
344 final ArduinoSignalRange myRange = ArduinoSignalRange.parseRange(myRangeDef);
345
346
347 final String myUnits = ArduinoParser.nextQuotedToken(myLine);
348 myLine = ArduinoParser.stripQuotedToken(myLine, myUnits);
349
350
351 final ArduinoSignalinoSignal.html#ArduinoSignal">ArduinoSignal mySignal = new ArduinoSignal(pOwner, myName, myDef, myFactor, myRange, myUnits);
352 mySignal.parseReceivers(pOwner.getSystem(), myLine);
353
354
355 if (myHdr.length() > 0) {
356 if (myHdr.charAt(0) == MULTI1) {
357 mySignal.setMultiplex();
358 } else {
359 if (myHdr.charAt(0) != MULTI2) {
360 throw new ArduinoParserException("Invalid multiplex", myHdr);
361 }
362 mySignal.setMultiplexId((long) ArduinoParser.parseNumber(myHdr.substring(1)));
363 }
364 }
365
366
367 pOwner.addSignal(mySignal);
368
369
370 } catch (ArduinoParserException e) {
371 throw new ArduinoException(e.getMessage() + ArduinoChar.COLON + e.getDetail(), pSignalDef);
372 }
373 }
374
375 @Override
376 public boolean equals(final Object pThat) {
377
378 if (pThat == this) {
379 return true;
380 } else if (!(pThat instanceof ArduinoSignal)) {
381 return false;
382 }
383
384
385 final ArduinoSignal./../net/sourceforge/jarduino/message/ArduinoSignal.html#ArduinoSignal">ArduinoSignal myThat = (ArduinoSignal) pThat;
386
387
388 return theName.equals(myThat.getName())
389 && theOwner.equals(myThat.getOwner());
390 }
391
392 @Override
393 public int hashCode() {
394 return Objects.hash(theOwner, theName);
395 }
396
397 @Override
398 public String toString() {
399
400 final StringBuilder myBuilder = new StringBuilder();
401 myBuilder.append(MARKER);
402 myBuilder.append(ArduinoChar.BLANK);
403 myBuilder.append(theName);
404
405
406 if (isMultiplex) {
407 myBuilder.append(ArduinoChar.BLANK);
408 myBuilder.append(MULTI1);
409 } else if (!theMultiplexId.equals(MULTI_NONE)) {
410 myBuilder.append(ArduinoChar.BLANK);
411 myBuilder.append(MULTI2);
412 myBuilder.append(theMultiplexId);
413 }
414
415
416 myBuilder.append(ArduinoChar.COLON);
417 myBuilder.append(ArduinoChar.BLANK);
418 myBuilder.append(theDefinition);
419 myBuilder.append(ArduinoChar.BLANK);
420 myBuilder.append(theFactor);
421 myBuilder.append(ArduinoChar.BLANK);
422 myBuilder.append(theRange);
423 myBuilder.append(ArduinoChar.BLANK);
424 myBuilder.append(ArduinoChar.QUOTE);
425 myBuilder.append(theUnits);
426 myBuilder.append(ArduinoChar.QUOTE);
427 myBuilder.append(ArduinoChar.BLANK);
428
429
430 for (int i = 0; i < theReceivers.size(); i++) {
431 if (i > 0) {
432 myBuilder.append(ArduinoChar.COMMA);
433 }
434 myBuilder.append(theReceivers.get(i));
435 }
436
437
438 return myBuilder.toString();
439 }
440 }