The line dash of singlebit wires changes according to their value
[Mograsim.git] / plugins / net.mograsim.logic.model / src / net / mograsim / logic / model / BitVectorFormatter.java
1 package net.mograsim.logic.model;
2
3 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_ONE_COLOR;
4 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_ONE_DASH;
5 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_U_COLOR;
6 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_U_DASH;
7 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_X_COLOR;
8 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_X_DASH;
9 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_ZERO_COLOR;
10 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_ZERO_DASH;
11 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_Z_COLOR;
12 import static net.mograsim.logic.model.preferences.RenderPreferences.BIT_Z_DASH;
13
14 import java.math.BigInteger;
15
16 import net.mograsim.logic.core.types.BitVector;
17 import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
18 import net.mograsim.logic.model.preferences.RenderPreferences;
19 import net.mograsim.preferences.ColorDefinition;
20 import net.mograsim.preferences.ColorDefinition.BuiltInColor;
21
22 public class BitVectorFormatter
23 {
24         public static String formatValueAsString(ReadEnd end, boolean useDashInsteadOfZ)
25         {
26                 return formatAsString(end == null ? null : end.getValues(), useDashInsteadOfZ);
27         }
28
29         public static String toBitstring(BitVector bitVector)
30         {
31                 return bitVector.toBitstring();
32         }
33
34         public static String formatAsString(BitVector bitVector, boolean useDashInsteadOfZ)
35         {
36                 if (bitVector == null)
37                         return "null";
38                 if (useDashInsteadOfZ && bitVector.isHighImpedance())
39                         return "-";
40                 if (bitVector.length() == 1)
41                         return bitVector.toBitstring();
42                 if (bitVector.isBinary())
43                 {
44                         String hexdigits = bitVector.getUnsignedValue().toString(16);
45                         StringBuilder sb = new StringBuilder();
46                         sb.append("0x");
47                         sb.append("0".repeat((bitVector.length() + 3) / 4 - hexdigits.length()));
48                         sb.append(hexdigits);
49                         return sb.toString();
50                 }
51                 return bitVector.toBitstring();
52         }
53
54         // TODO this method overlaps in functionality with AsmNumberUtil (in plugin.core)
55         public static BitVector parseUserBitVector(String userInput, int width)
56         {
57                 BitVector bitvector = null;
58                 if (width > 0 && userInput.matches("0x[0-9a-fA-F]+"))
59                         // TODO should we check for overflows?
60                         bitvector = BitVector.from(new BigInteger(userInput.substring(2), 16), width);
61                 else if (width <= 0 || userInput.length() == width)
62                         // TODO do this without exceptions
63                         try
64                         {
65                                 bitvector = BitVector.parseBitstring(userInput);
66                         }
67                         catch (@SuppressWarnings("unused") NullPointerException x)
68                         {
69                                 // ignore
70                         }
71                 if (bitvector == null && width > 0)
72                         try
73                         {
74                                 // TODO should we check for overflows?
75                                 bitvector = BitVector.from(new BigInteger(userInput), width);
76                         }
77                         catch (@SuppressWarnings("unused") NumberFormatException x)
78                         {
79                                 // ignore
80                         }
81                 return bitvector;
82         }
83
84         public static double[] formatAsLineDash(RenderPreferences renderPrefs, ReadEnd end)
85         {
86                 return formatAsLineDash(renderPrefs, end == null ? null : end.getValues());
87         }
88
89         public static double[] formatAsLineDash(RenderPreferences renderPrefs, BitVector bitVector)
90         {
91                 // TODO maybe find a line dash assignment for multiple-bit bit vectors?
92                 if (bitVector == null || bitVector.length() != 1)
93                         return null;
94                 String prefName;
95                 switch (bitVector.getLSBit(0))
96                 {
97                 case ONE:
98                         prefName = BIT_ONE_DASH;
99                         break;
100                 case U:
101                         prefName = BIT_U_DASH;
102                         break;
103                 case X:
104                         prefName = BIT_X_DASH;
105                         break;
106                 case Z:
107                         prefName = BIT_Z_DASH;
108                         break;
109                 case ZERO:
110                         prefName = BIT_ZERO_DASH;
111                         break;
112                 default:
113                         throw new IllegalArgumentException("Unknown enum constant: " + bitVector.getLSBit(0));
114                 }
115                 return parseLineDashes(renderPrefs.getString(prefName));
116         }
117
118         // TODO this method does not belong here
119         public static double[] parseLineDashes(String dashesString)
120         {
121                 if (dashesString.isEmpty())
122                         return null;
123                 String[] dashesStrings = dashesString.split(",");
124                 double[] dashes = new double[dashesStrings.length];
125                 for (int i = 0; i < dashesStrings.length; i++)
126                         dashes[i] = Double.parseDouble(dashesStrings[i]);
127                 return dashes;
128         }
129
130         public static ColorDefinition formatAsColor(RenderPreferences renderPrefs, ReadEnd end)
131         {
132                 return formatAsColor(renderPrefs, end == null ? null : end.getValues());
133         }
134
135         public static ColorDefinition formatAsColor(RenderPreferences renderPrefs, BitVector bitVector)
136         {
137                 // TODO maybe find a color assignment for multiple-bit bit vectors?
138                 if (bitVector == null || bitVector.length() != 1)
139                         return new ColorDefinition(BuiltInColor.COLOR_BLACK);
140                 switch (bitVector.getLSBit(0))
141                 {
142                 case ONE:
143                         return renderPrefs.getColorDefinition(BIT_ONE_COLOR);
144                 case U:
145                         return renderPrefs.getColorDefinition(BIT_U_COLOR);
146                 case X:
147                         return renderPrefs.getColorDefinition(BIT_X_COLOR);
148                 case Z:
149                         return renderPrefs.getColorDefinition(BIT_Z_COLOR);
150                 case ZERO:
151                         return renderPrefs.getColorDefinition(BIT_ZERO_COLOR);
152                 default:
153                         throw new IllegalArgumentException("Unknown enum constant: " + bitVector.getLSBit(0));
154                 }
155         }
156
157         private BitVectorFormatter()
158         {
159                 throw new UnsupportedOperationException("No BitVectorFormatter instances");
160         }
161 }