View Javadoc
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 java.util.LinkedHashMap;
20  import java.util.Map;
21  import java.util.Map.Entry;
22  
23  import net.sourceforge.jarduino.ArduinoException;
24  import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
25  
26  /**
27   * Values.
28   */
29  public class ArduinoValues {
30      /**
31       * The Marker.
32       */
33      static final String MARKER = "VAL_";
34  
35      /**
36       * Owning signal.
37       */
38      private final ArduinoSignal theOwner;
39  
40      /**
41       * The values map.
42       */
43      private final Map<Number, String> theValues;
44  
45      /**
46       * Constructor.
47       * @param pOwner the owning signal
48       * @param pValues the value map
49       */
50      ArduinoValues(final ArduinoSignal pOwner,
51                    final Map<Number, String> pValues) {
52          theOwner = pOwner;
53          theValues = pValues;
54      }
55  
56      /**
57       * Obtain the owner.
58       * @return the owner
59       */
60      public ArduinoSignal getOwner() {
61          return theOwner;
62      }
63  
64      /**
65       * Obtain the values.
66       * @return the values
67       */
68      public Map<Number, String> getValues() {
69          return theValues;
70      }
71  
72      /**
73       * Obtain the description for the value.
74       * @param pValue the value
75       * @return the description
76       */
77      public String getDescriptionForValue(final Number pValue) {
78          return theValues.get(pValue);
79      }
80  
81      /**
82       * parse the values definition.
83       * @param pSystem the system
84       * @param pValuesDef the values definition
85       * @throws ArduinoException on error
86       */
87      public static void parseValues(final ArduinoSystem pSystem,
88                                     final String pValuesDef) throws ArduinoException {
89          /* Marker is first token in header */
90          final String myMarker = ArduinoParser.nextToken(pValuesDef);
91          String myDef = ArduinoParser.stripToken(pValuesDef, myMarker);
92          if (!myMarker.equals(MARKER)) {
93              throw new ArduinoException("Invalid marker", pValuesDef);
94          }
95  
96          /* Split out msgId/comment */
97          final String myMsgId = ArduinoParser.nextToken(myDef);
98          myDef = ArduinoParser.stripToken(myDef, myMsgId);
99          final String myName = ArduinoParser.nextToken(myDef);
100         myDef = ArduinoParser.stripToken(myDef, myName);
101 
102         /* Protect against parser exceptions */
103         try {
104             /* Find the signal */
105             final ArduinoSignal mySignal = pSystem.findSignalByIdAndName(myMsgId, myName);
106 
107             /* Build the value map */
108             final Map<Number, String> myValueMap = buildValueMap(myDef);
109 
110             /* Create Values and assign to signal */
111             final ArduinoValuesinoValues.html#ArduinoValues">ArduinoValues myValues = new ArduinoValues(mySignal, myValueMap);
112             mySignal.setValues(myValues);
113 
114             /* Handle parser exceptions */
115         } catch (ArduinoParserException e) {
116             throw new ArduinoException(e.getMessage() + ArduinoChar.COLON + e.getDetail(), pValuesDef);
117         }
118     }
119 
120     /**
121      * Build the valueMap.
122      * @param pMapDef the mapDefinition
123      * @return the map
124      * @throws ArduinoParserException on error
125      */
126     private static Map<Number, String> buildValueMap(final String pMapDef) throws ArduinoParserException {
127         String myValues = pMapDef;
128         if (myValues.length() == 0 || myValues.charAt(myValues.length() - 1) != ArduinoChar.SEMICOLON) {
129             throw new ArduinoParserException("Invalid ValuesTable", pMapDef);
130         }
131         myValues = myValues.substring(0, myValues.length() - 1);
132 
133         /* Loop through the tokens */
134         final Map<Number, String> myMap = new LinkedHashMap<>();
135         while (myValues.length() > 0) {
136             /* Access the value */
137             final String myValue = ArduinoParser.nextToken(myValues);
138             myValues = ArduinoParser.stripToken(myValues, myValue);
139             final Number myNumber = ArduinoParser.parseNumber(myValue);
140 
141             /* Access description */
142             final String myDesc = ArduinoParser.nextQuotedToken(myValues);
143             myValues = ArduinoParser.stripQuotedToken(myValues, myDesc);
144 
145             /* Add to the table */
146             myMap.put(myNumber, myDesc);
147         }
148 
149         /* Return the map */
150         return myMap;
151     }
152 
153     @Override
154     public String toString() {
155         /* Handle headers */
156         final StringBuilder myBuilder = new StringBuilder();
157         myBuilder.append(MARKER);
158         myBuilder.append(ArduinoChar.BLANK);
159         myBuilder.append(theOwner.getOwner().getId());
160         myBuilder.append(ArduinoChar.BLANK);
161         myBuilder.append(theOwner.getName());
162 
163         /* Loop through the values */
164         for (Entry<Number, String> myEntry : theValues.entrySet()) {
165             myBuilder.append(ArduinoChar.BLANK);
166             myBuilder.append(myEntry.getKey());
167             myBuilder.append(ArduinoChar.BLANK);
168             myBuilder.append(ArduinoChar.QUOTE);
169             myBuilder.append(myEntry.getValue());
170             myBuilder.append(ArduinoChar.QUOTE);
171         }
172 
173         /* Terminate and return */
174         myBuilder.append(ArduinoChar.SEMICOLON);
175         return myBuilder.toString();
176     }
177 }