/// <summary> /// Takes a file and breaks it down into IElements then returns it in a structured format /// </summary> /// <param name="br">The file to process</param> /// <param name="fileName">The name of the file to be processed (used only for displaying error messages)</param> /// <returns>A class containing the processed file data</returns> public KCFile ParseFile(BinaryReader br, string fileName) { KCFile workingFile = new KCFile(); List <IInstruction> instructions = new List <IInstruction>(); DataBox footer = ReadFooter(br); workingFile.footer = footer; workingFile.header = ReadHeader(br); long streamEnd = br.BaseStream.Length - footer.GetContentsSize(); while (br.BaseStream.Position != streamEnd) // will need to check this for accuracy as it has been unreliable in some cases in the past { Opcode opcode = FileIOHelper.ReadOpcode(br); br.BaseStream.Position -= OpcodeInfo.OPCODE_SIZE; // set the position back by 2, the size of the opcodes, as the instruction parsers will expect to given a position starting with an opcode if (opcode == Opcode.INVALID) { string errorMessage = string.Format("There was an unexpected opcode when reading file {0} at position {1} after reading {2} instructions", fileName, br.BaseStream.Position.ToString("X"), instructions.Count.ToString()); MessageBox.Show(errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(1); } IInstruction newInstruction; Type instructionParserType = OpcodeInfo.GetInstructionParserType(opcode); if (instructionParserType == typeof(InstructionBox)) { newInstruction = MakeInstructionBox(opcode); newInstruction.Read(br); } else { newInstruction = (IInstruction)Activator.CreateInstance(instructionParserType); newInstruction.Read(br); } instructions.Add(newInstruction); } //string finishMessage = string.Format("Parsed file {0} with {1} instructions", fileName, instructions.Count.ToString()); //MessageBox.Show(finishMessage); workingFile.instructions = instructions; return(workingFile); }