|
9 | 9 | import de.neemann.digital.lang.Lang; |
10 | 10 |
|
11 | 11 | import java.io.*; |
12 | | -import java.util.StringTokenizer; |
| 12 | + |
| 13 | +import static java.io.StreamTokenizer.*; |
13 | 14 |
|
14 | 15 | /** |
15 | 16 | * Reader to read the original Logisim hex file format |
@@ -38,47 +39,55 @@ public LogisimReader(Reader reader) { |
38 | 39 |
|
39 | 40 | @Override |
40 | 41 | public void read(ValueArray valueArray) throws IOException { |
41 | | - try (BufferedReader br = new BufferedReader(reader)) { |
42 | | - String header = br.readLine(); |
| 42 | + try (BufferedReader bufferedReader = new BufferedReader(reader)) { |
| 43 | + String header = bufferedReader.readLine(); |
43 | 44 | if (header == null || !header.equals("v2.0 raw")) |
44 | 45 | throw new IOException(Lang.get("err_invalidFileFormat")); |
45 | | - String line; |
46 | | - int pos = 0; |
47 | | - while ((line = br.readLine()) != null) { |
48 | | - try { |
49 | | - int p = line.indexOf('#'); |
50 | | - if (p >= 0) |
51 | | - line = line.substring(0, p).trim(); |
52 | | - else |
53 | | - line = line.trim(); |
54 | 46 |
|
55 | | - StringTokenizer tc = new StringTokenizer(line, " \t"); |
56 | | - while (tc.hasMoreTokens()) { |
57 | | - String num = tc.nextToken(); |
58 | | - int rle = 1; |
59 | | - p = num.indexOf('*'); |
60 | | - if (p > 0) { |
61 | | - rle = Integer.parseInt(num.substring(0, p)); |
62 | | - num = num.substring(p + 1).trim(); |
63 | | - } |
64 | | - |
65 | | - if (num.length() > 2 && num.charAt(0) == '0' && (num.charAt(1) == 'x' || num.charAt(1) == 'X')) |
66 | | - num = num.substring(2); |
| 47 | + StreamTokenizer t = new StreamTokenizer(bufferedReader); |
| 48 | + t.resetSyntax(); |
| 49 | + t.commentChar('#'); |
| 50 | + t.wordChars('a', 'f'); |
| 51 | + t.wordChars('A', 'F'); |
| 52 | + t.wordChars('x', 'x'); |
| 53 | + t.wordChars('X', 'X'); |
| 54 | + t.wordChars('0', '9'); |
| 55 | + t.whitespaceChars(0, ' '); |
67 | 56 |
|
68 | | - if (num.length() > 0) { |
69 | | - long v = Bits.decode(num, 0, 16); |
70 | | - for (int i = 0; i < rle; i++) { |
71 | | - valueArray.set(pos, v); |
72 | | - pos++; |
73 | | - } |
| 57 | + int pos = 0; |
| 58 | + while (t.nextToken() != TT_EOF) { |
| 59 | + try { |
| 60 | + String vStr = t.sval; |
| 61 | + if (vStr == null) |
| 62 | + throw new IOException("invalid token in line " + t.lineno()); |
| 63 | + if (t.nextToken() == '*') { |
| 64 | + t.nextToken(); |
| 65 | + if (t.sval == null) |
| 66 | + throw new IOException("invalid token in line " + t.lineno()); |
| 67 | + long v = getHexLong(t.sval); |
| 68 | + int reps = (int) Bits.decode(vStr, 0, 10); |
| 69 | + for (int i = 0; i < reps; i++) { |
| 70 | + valueArray.set(pos, v); |
| 71 | + pos++; |
74 | 72 | } |
| 73 | + } else { |
| 74 | + t.pushBack(); |
| 75 | + valueArray.set(pos, getHexLong(vStr)); |
| 76 | + pos++; |
75 | 77 | } |
76 | | - |
77 | 78 | } catch (Bits.NumberFormatException e) { |
78 | 79 | throw new IOException(e); |
79 | 80 | } |
80 | 81 | } |
81 | 82 | } |
82 | 83 | } |
83 | 84 |
|
| 85 | + private long getHexLong(String vStr) throws Bits.NumberFormatException { |
| 86 | + int p = 0; |
| 87 | + if (vStr.length() > 2 && vStr.charAt(0) == '0' && (vStr.charAt(1) == 'x' || vStr.charAt(1) == 'X')) |
| 88 | + p = 2; |
| 89 | + |
| 90 | + return Bits.decode(vStr, p, 16); |
| 91 | + } |
| 92 | + |
84 | 93 | } |
0 commit comments