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.List;
20 import java.util.Map.Entry;
21
22
23
24
25 public final class ArduinoGenerator {
26
27
28
29 private ArduinoGenerator() {
30 }
31
32
33
34
35
36
37
38 public static String formatHeader(final ArduinoSystem pSystem,
39 final ArduinoMsgFilter pFilter) {
40
41 final StringBuilder myBuilder = new StringBuilder();
42
43
44 final String myResult = updateTemplate(ArduinoTemplate.HEADER, pSystem);
45
46
47 for (ArduinoMessage myMessage : pSystem.getMessages()) {
48
49 if (pFilter.isSelected(myMessage.getId())) {
50
51 myBuilder.append(formatMessageHeader(myMessage, pFilter));
52 }
53 }
54
55
56 return myResult.replace(ArduinoVar.HDRCLASSES, myBuilder.toString());
57 }
58
59
60
61
62
63
64
65 public static String formatBody(final ArduinoSystem pSystem,
66 final ArduinoMsgFilter pFilter) {
67
68 final StringBuilder myBuilder = new StringBuilder();
69
70
71 final String myResult = updateTemplate(ArduinoTemplate.BODY, pSystem);
72
73
74 for (ArduinoMessage myMessage : pSystem.getMessages()) {
75
76 if (pFilter.isSelected(myMessage.getId())) {
77
78 myBuilder.append(formatMessageBody(myMessage, pFilter));
79 }
80 }
81
82
83 return myResult.replace(ArduinoVar.BDYCLASSES, myBuilder.toString())
84 .replace(ArduinoVar.MSGCASES, buildMsgCases(pSystem, pFilter));
85 }
86
87
88
89
90
91
92
93 private static String formatMessageHeader(final ArduinoMessage pMessage,
94 final ArduinoMsgFilter pFilter) {
95
96 final StringBuilder myBuilder = new StringBuilder();
97
98
99 final boolean parseMsg = pFilter.isParsed(pMessage.getId());
100 final boolean buildMsg = pFilter.isBuilt(pMessage.getId());
101
102
103 String myBase = ArduinoTemplate.HDRCLASS.replace(ArduinoVar.PARSEHDR, parseMsg ? ArduinoTemplate.HDRPARSECLASS : "");
104 myBase = myBase.replace(ArduinoVar.BUILDHDR, buildMsg ? ArduinoTemplate.HDRBUILDCLASS : "");
105 myBuilder.append(formatClassHeader(myBase, pFilter, pMessage, ArduinoSignal.MULTI_NONE, pMessage.getSignals()));
106
107
108 if (pMessage.hasMultiplex()) {
109
110 for (Entry<Long, List<ArduinoSignal>> myEntry : pMessage.getMultiplexMap().entrySet()) {
111
112 myBase = ArduinoTemplate.HDRMULTICLASS.replace(ArduinoVar.PARSEHDR, parseMsg ? ArduinoTemplate.HDRPARSECLASS : "");
113 myBase = myBase.replace(ArduinoVar.BUILDHDR, buildMsg ? ArduinoTemplate.HDRBUILDMULTICLASS : "");
114 myBuilder.append(formatClassHeader(myBase, pFilter, pMessage, myEntry.getKey(), myEntry.getValue()));
115 }
116 }
117
118
119 return myBuilder.toString();
120 }
121
122
123
124
125
126
127
128 private static String formatMessageBody(final ArduinoMessage pMessage,
129 final ArduinoMsgFilter pFilter) {
130
131 final StringBuilder myBuilder = new StringBuilder();
132
133
134 final boolean parseMsg = pFilter.isParsed(pMessage.getId());
135 final boolean buildMsg = pFilter.isBuilt(pMessage.getId());
136
137
138 String myBase = ArduinoTemplate.BDYCLASS.replace(ArduinoVar.PARSEBDY + ArduinoChar.LF, parseMsg ? ArduinoTemplate.BDYPARSECLASS : "");
139 myBase = myBase.replace(ArduinoVar.BUILDBDY, buildMsg ? ArduinoTemplate.BDYBUILDCLASS : "");
140 myBuilder.append(formatClassBody(myBase, pMessage, ArduinoSignal.MULTI_NONE, pMessage.getSignals()));
141
142
143 if (pMessage.hasMultiplex()) {
144
145 for (Entry<Long, List<ArduinoSignal>> myEntry : pMessage.getMultiplexMap().entrySet()) {
146
147 myBase = ArduinoTemplate.BDYMULTICLASS.replace(ArduinoVar.PARSEBDY + ArduinoChar.LF, parseMsg ? ArduinoTemplate.BDYPARSEMULTICLASS : "");
148 myBase = myBase.replace(ArduinoVar.BUILDBDY, buildMsg ? ArduinoTemplate.BDYBUILDMULTICLASS : "");
149 myBuilder.append(formatClassBody(myBase, pMessage, myEntry.getKey(), myEntry.getValue()));
150 }
151 }
152
153
154 return myBuilder.toString();
155 }
156
157
158
159
160
161
162
163
164
165
166 private static String formatClassHeader(final String pTemplate,
167 final ArduinoMsgFilter pFilter,
168 final ArduinoMessage pMessage,
169 final Long pMultiplex,
170 final List<ArduinoSignal> pSignals) {
171
172 final boolean pubFields = pFilter.publicFields();
173
174
175 String myResult = pTemplate.replace(ArduinoVar.HDRSETTERS, pubFields ? "" : formatSignals(ArduinoTemplate.HDRSETTER, pSignals));
176 myResult = myResult.replace(ArduinoVar.HDRGETTERS, pubFields ? "" : formatSignals(ArduinoTemplate.HDRGETTER, pSignals));
177 myResult = myResult.replace(ArduinoVar.PUBFIELDS, pubFields ? "private:\n " : "");
178 myResult = myResult.replace(ArduinoVar.PRIVFIELDS, pubFields ? "\n" : "\n private:\n");
179 myResult = myResult.replace(ArduinoVar.HDRFIELDS, formatSignals(ArduinoTemplate.HDRFIELD, pSignals));
180 myResult = myResult.replace(ArduinoVar.HDRFIELDDEFS, formatDefSignals(ArduinoTemplate.HDRFIELDDEF, pSignals));
181
182
183 String myClass = pMessage.getName();
184 if (!ArduinoSignal.MULTI_NONE.equals(pMultiplex)) {
185
186 myClass += "_m" + pMultiplex;
187
188
189 myResult = myResult.replace(ArduinoVar.MUXSETTER, pubFields ? "" : updateTemplate(ArduinoTemplate.MUXSETTER, pMessage.getMultiplexSignal()));
190 myResult = myResult.replace(ArduinoVar.MUXSET, updateTemplate(pMessage.getMultiplexSignal(), pFilter, pMultiplex));
191 }
192
193
194 myResult = updateTemplate(myResult, pMessage);
195 myResult = myResult.replace(ArduinoVar.CLASSNAME, myClass);
196
197
198 return myResult;
199 }
200
201
202
203
204
205
206
207
208
209 private static String formatClassBody(final String pTemplate,
210 final ArduinoMessage pMessage,
211 final Long pMultiplex,
212 final List<ArduinoSignal> pSignals) {
213
214 String myResult = pTemplate.replace(ArduinoVar.BDYREADERS, formatSignals(ArduinoTemplate.BDYPARSER, pSignals));
215 myResult = myResult.replace(ArduinoVar.BDYWRITERS, formatSignals(ArduinoTemplate.BDYWRITER, pSignals));
216 myResult = myResult.replace(ArduinoVar.BDYFIELDDEFS, formatDefSignals(ArduinoTemplate.BDYFIELDDEF, pSignals));
217
218
219 String myClass = pMessage.getName();
220 if (!ArduinoSignal.MULTI_NONE.equals(pMultiplex)) {
221
222 myClass += "_m" + pMultiplex;
223 }
224
225
226 myResult = updateTemplate(myResult, pMessage);
227 myResult = myResult.replace(ArduinoVar.CLASSNAME, myClass);
228
229
230 return myResult;
231 }
232
233
234
235
236
237
238
239 private static String formatSignals(final String pTemplate,
240 final List<ArduinoSignal> pSignals) {
241
242 final StringBuilder myBuilder = new StringBuilder();
243
244
245 for (ArduinoSignal mySignal : pSignals) {
246 myBuilder.append(updateTemplate(pTemplate, mySignal));
247 }
248
249
250 return myBuilder.toString();
251 }
252
253
254
255
256
257
258
259 private static String formatDefSignals(final String pTemplate,
260 final List<ArduinoSignal> pSignals) {
261
262 final StringBuilder myBuilder = new StringBuilder();
263
264
265 for (ArduinoSignal mySignal : pSignals) {
266 myBuilder.append(updateDefTemplate(pTemplate, mySignal));
267 }
268
269
270 return myBuilder.toString();
271 }
272
273
274
275
276
277
278
279 private static String updateTemplate(final String pTemplate,
280 final ArduinoSystem pSystem) {
281 return pTemplate.replace(ArduinoVar.SYSNAME, pSystem.getName())
282 .replace(ArduinoVar.SYSCNAME, pSystem.getCName());
283 }
284
285
286
287
288
289
290
291 private static String updateTemplate(final String pTemplate,
292 final ArduinoMessage pMessage) {
293 return pTemplate.replace(ArduinoVar.MSGNAME, pMessage.getName())
294 .replace(ArduinoVar.MSGID, pMessage.getId())
295 .replace(ArduinoVar.MSGLEN, Integer.toString(pMessage.getLength()));
296 }
297
298
299
300
301
302
303
304 private static String updateTemplate(final String pTemplate,
305 final ArduinoSignal pSignal) {
306 final boolean isFloat = pSignal.isFloat();
307 final String myClass = isFloat ? "Double" : "Long";
308 final boolean unBounded = pSignal.getRange().unBounded();
309 final String myBounds = unBounded ? "" : "Bounded";
310 return pTemplate.replace(ArduinoVar.FIELDNAME, pSignal.getName())
311 .replace(ArduinoVar.FIELDCLASS, myClass)
312 .replace(ArduinoVar.FIELDBOUND, myBounds)
313 .replace(ArduinoVar.FIELDTYPE, getFieldType(pSignal));
314 }
315
316
317
318
319
320
321
322
323 private static String updateTemplate(final ArduinoSignal pSignal,
324 final ArduinoMsgFilter pFilter,
325 final Long pMultiplex) {
326
327 final boolean pubFields = pFilter.publicFields();
328
329 final String myBase = updateTemplate(pubFields ? ArduinoTemplate.MUXSETPUB : ArduinoTemplate.MUXSETPRIV, pSignal);
330 return myBase.replace(ArduinoVar.MUXVALUE, pMultiplex.toString());
331 }
332
333
334
335
336
337
338
339 private static String updateDefTemplate(final String pTemplate,
340 final ArduinoSignal pSignal) {
341 final boolean isFloat = pSignal.isFloat();
342 final String myClass = isFloat ? "Double" : "Long";
343 return pTemplate.replace(ArduinoVar.DEFSTART, Integer.toString(pSignal.getDefinition().getStartBit()))
344 .replace(ArduinoVar.DEFLENGTH, Integer.toString(pSignal.getDefinition().getBitLength()))
345 .replace(ArduinoVar.DEFENDIAN, Boolean.toString(pSignal.getDefinition().getDataType().isLittleEndian()))
346 .replace(ArduinoVar.DEFSIGNED, Boolean.toString(pSignal.getDefinition().getDataType().isSigned()))
347 .replace(ArduinoVar.DEFFACTOR, pSignal.getFactor().getFactor().toString())
348 .replace(ArduinoVar.DEFOFFSET, pSignal.getFactor().getOffset().toString())
349 .replace(ArduinoVar.FIELDNAME, pSignal.getName())
350 .replace(ArduinoVar.FIELDCLASS, myClass)
351 .replace(ArduinoVar.DEFMIN, pSignal.getRange().getMinimum().toString())
352 .replace(ArduinoVar.DEFMAX, pSignal.getRange().getMaximum().toString());
353 }
354
355
356
357
358
359
360
361 private static String buildMsgCases(final ArduinoSystem pSystem,
362 final ArduinoMsgFilter pFilter) {
363
364 final StringBuilder myBuilder = new StringBuilder();
365
366
367 for (ArduinoMessage myMessage : pSystem.getMessages()) {
368
369 if (!pFilter.isParsed(myMessage.getId())) {
370 continue;
371 }
372
373
374 if (myMessage.hasMultiplex()) {
375 myBuilder.append(buildMultiplexCases(myMessage, pFilter));
376 } else {
377 myBuilder.append(updateTemplate(ArduinoTemplate.PRSMSGCASE, myMessage));
378 }
379 }
380
381
382 return myBuilder.toString();
383 }
384
385
386
387
388
389
390
391 private static String buildMultiplexCases(final ArduinoMessage pMessage,
392 final ArduinoMsgFilter pFilter) {
393
394 final StringBuilder myBuilder = new StringBuilder();
395
396
397 final boolean pubFields = pFilter.publicFields();
398
399
400 for (Long myId : pMessage.getMultiplexMap().keySet()) {
401
402 myBuilder.append(ArduinoTemplate.PRSMULTIMSGCASE.replace(ArduinoVar.MUXVALUE, myId.toString()));
403 }
404
405
406 final String myCase = ArduinoTemplate.PRSMULTIMSG
407 .replace(ArduinoVar.MUXSWITCH, pubFields ? ArduinoTemplate.MUXSWITCHPUB : ArduinoTemplate.MUXSWITCHPRIV)
408 .replace(ArduinoVar.MUXCASES, myBuilder.toString());
409 return updateTemplate(myCase, pMessage).replace(ArduinoVar.FIELDNAME, pMessage.getMultiplexSignal().getName());
410 }
411
412
413
414
415
416
417 private static String getFieldType(final ArduinoSignal pSignal) {
418
419 if (pSignal.isFloat()) {
420 return "double";
421 }
422
423
424 final int myBitLen = pSignal.getDefinition().getBitLength();
425 if (myBitLen == 1) {
426 return "bool";
427 }
428 final int myByteLen = 1 + ((myBitLen - 1) / Byte.SIZE);
429
430
431 final String mySign = pSignal.isSigned() ? "" : "unsigned ";
432 if (myByteLen == Byte.BYTES || myByteLen == Short.BYTES) {
433 return mySign + "short";
434 } else if (myByteLen <= Integer.BYTES) {
435 return mySign + "long";
436 }
437 return mySign + "long long";
438 }
439 }