/// <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> /// <param name="jumpLabelManager">The jump label manager to use when processing file (pass null to disable jump tracking)</param> /// <returns>A class containing the processed file data</returns> public KCFile ParseFile(BinaryReader br, string fileName, JumpLabelManager jumpLabelManager) { KCFile workingFile = new KCFile(); List <IInstruction> instructions = new List <IInstruction>(); workingFile.footer = ReadFooter(br); workingFile.header = ReadHeader(br); StCpNumber fileNumber = (workingFile.header as StCp_Header).GetFileNumber(); // more than anything else this basically cements that this function reads only StCp files which should really be clarified at some point long streamEnd = br.BaseStream.Length - ElementHelper.GetElementSize(workingFile.footer); 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); } if (jumpLabelManager != null) // we want to support running this without a jumplabelmanager just in case { long currentAddress = br.BaseStream.Position; if (jumpLabelManager.IsJumpTarget(fileNumber, (int)currentAddress)) { var virtualLabel = jumpLabelManager.CreateVirtualLabel(fileNumber, (int)currentAddress); instructions.Add(virtualLabel); } } IInstruction newInstruction; Type instructionParserType = OpcodeInfo.GetInstructionParserType(opcode); if (instructionParserType == typeof(InstructionBox)) { newInstruction = ElementHelper.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); }
/// <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); }
/// <summary> /// A helper function for creating Boxes /// </summary> /// <param name="opcode"></param> /// <returns></returns> /// <remarks> /// Intended to make Box creating code cleaner by delegating the getting of instruction size and construction of object to a seperate function /// </remarks> private InstructionBox MakeInstructionBox(Opcode opcode) { int instructionSize = OpcodeInfo.GetInstructionSize(opcode); return(new InstructionBox(instructionSize)); }
/// <summary> /// A helper function for creating Boxes /// </summary> /// <param name="opcode"></param> /// <returns></returns> /// <remarks> /// Intended to make Box creating code cleaner by delegating the getting of instruction size and construction of object to a seperate function /// </remarks> internal static InstructionBox MakeInstructionBox(Opcode opcode) { int instructionSize = OpcodeInfo.GetInstructionSize(opcode); return(new InstructionBox(instructionSize)); }