Fixed bug with Exception being thrown with wrong cause
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / mi / MicroInstructionMemoryParser.java
1 package net.mograsim.machine.mi;
2
3 import java.io.BufferedReader;
4 import java.io.ByteArrayInputStream;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9
10 import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
11 import net.mograsim.machine.mi.parameters.ParameterClassification;
12
13 public class MicroInstructionMemoryParser
14 {
15         private final static String lineSeparator = System.getProperty("line.separator");
16
17         public static void parseMemory(final MicroInstructionMemory memory, String inputPath) throws IOException
18         {
19                 try (InputStream input = new FileInputStream(inputPath))
20                 {
21                         parseMemory(memory, input);
22                 }
23         }
24
25         /**
26          * @param input The input to parse must be in csv format; The stream is closed after being consumed.
27          * 
28          * @throws IOException
29          */
30         public static MicroInstructionMemory parseMemory(MicroInstructionMemoryDefinition memDef, InputStream input) throws IOException
31         {
32                 try
33                 {
34                         MicroInstructionMemory memory = new StandardMicroInstructionMemory(memDef);
35                         parseMemory(memory, input);
36                         return memory;
37                 }
38                 catch (NullPointerException e)
39                 {
40                         throw new MicroInstructionMemoryParseException(e);
41                 }
42         }
43
44         /**
45          *
46          * @param input The input to parse must be in csv format; The stream is closed after being consumed.
47          * 
48          * @throws IOException
49          */
50         public static void parseMemory(final MicroInstructionMemory memory, InputStream input) throws IOException
51         {
52                 try (BufferedReader reader = new BufferedReader(new InputStreamReader(input)))
53                 {
54                         MicroInstructionMemoryDefinition def = memory.getDefinition();
55                         MicroInstructionDefinition miDef = def.getMicroInstructionDefinition();
56
57                         long minAddr = def.getMinimalAddress();
58                         long maxAddr = def.getMaximalAddress();
59
60                         String line;
61                         long i = minAddr;
62                         try
63                         {
64                                 for (; i <= maxAddr && reader.ready() && !"".equals((line = reader.readLine())); i++)
65                                 {
66                                         memory.setCell(i, parse(miDef, line));
67                                 }
68                         }
69                         catch (IOException e)
70                         {
71                                 e.printStackTrace();
72                         }
73
74                         for (; i <= maxAddr; i++)
75                         {
76                                 memory.setCell(i, miDef.createDefaultInstruction());
77                         }
78                 }
79         }
80
81         /**
82          * must be in csv format
83          */
84         public static MicroInstruction parse(MicroInstructionDefinition definition, String input)
85         {
86                 int size = definition.size();
87                 String[] strings = input.split(",");
88                 if (size != strings.length)
89                         throw new MicroInstructionMemoryParseException("String does not match definition! The number of parameters does not match.");
90                 MicroInstructionParameter[] params = new MicroInstructionParameter[size];
91                 ParameterClassification[] classes = definition.getParameterClassifications();
92                 try
93                 {
94                         for (int i = 0; i < size; i++)
95                         {
96                                 params[i] = classes[i].parse(strings[i]);
97                         }
98                         return new StandardMicroInstruction(params);
99                 }
100                 catch (Exception e)
101                 {
102                         throw new MicroInstructionMemoryParseException(e);
103                 }
104         }
105
106         private static String toCSV(MicroInstruction inst)
107         {
108                 int max = inst.getSize() - 1;
109                 StringBuilder sb = new StringBuilder();
110                 for (int i = 0; i < max; i++)
111                 {
112                         sb.append(inst.getParameter(i).toString());
113                         sb.append(",");
114                 }
115                 sb.append(inst.getParameter(max).toString());
116                 return sb.toString();
117         }
118
119         public static InputStream write(MicroInstructionMemory memory)
120         {
121                 return new InputStream()
122                 {
123                         long instIndex = memory.getDefinition().getMinimalAddress(), maxAddress = memory.getDefinition().getMaximalAddress();
124                         InputStream instStream = new ByteArrayInputStream(new byte[0]);
125
126                         @Override
127                         public int read() throws IOException
128                         {
129                                 int val = instStream.read();
130                                 if (val == -1 && instIndex <= maxAddress)
131                                 {
132                                         instStream = new ByteArrayInputStream((toCSV(memory.getCell(instIndex++)) + lineSeparator).getBytes());
133                                         val = instStream.read();
134                                 }
135                                 return val;
136                         }
137                 };
138         }
139 }