예제 #1
0
파일: FileParser.cs 프로젝트: shindouj/KPT
        /// <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);
        }