Ejemplo n.º 1
0
        public void TestParseMir01_Offset()
        {
            var converter = new StdfValueConverter();

            converter.CpuType = 2;
            var referenceMir = Mir01_Source(converter);
            var mir          = new MIR(Mir01, converter: converter, offset: 4);

            Assert.Equal(referenceMir.SetupTimeStamp, mir.SetupTimeStamp);
            Assert.Equal(referenceMir.StartTimeStamp, mir.StartTimeStamp);
            Assert.Equal(referenceMir.StationNumber, mir.StationNumber);
            Assert.Equal(referenceMir.TestModeCode, mir.TestModeCode);
            Assert.Equal(referenceMir.LotRetestCode, mir.LotRetestCode);
            Assert.Equal(referenceMir.DataProtectionCode, mir.DataProtectionCode);
            Assert.Equal(referenceMir.BurnInTimeMinutes, mir.BurnInTimeMinutes);
            Assert.Equal(referenceMir.CommandModeCode, mir.CommandModeCode);
            Assert.Equal(referenceMir.LotId, mir.LotId);
            Assert.Equal(referenceMir.ProductId, mir.ProductId);
            Assert.Equal(referenceMir.NodeName, mir.NodeName);
            Assert.Equal(referenceMir.TesterType, mir.TesterType);
            Assert.Equal(referenceMir.JobName, mir.JobName);
            Assert.Equal(referenceMir.JobRevision, mir.JobRevision);
            Assert.Equal(referenceMir.SublotId, mir.SublotId);
            Assert.Equal(referenceMir.OperatorId, mir.OperatorId);
            Assert.Equal(referenceMir.ExecutiveType, mir.ExecutiveType);
            Assert.Equal(referenceMir.ExecutiveVersion, mir.ExecutiveVersion);
            Assert.Equal(referenceMir.TestCode, mir.TestCode);
            Assert.Equal(referenceMir.TestTemperature, mir.TestTemperature);
            Assert.Equal(referenceMir.UserText, mir.UserText);
            Assert.Equal(referenceMir.AuxFile, mir.AuxFile);
            Assert.Equal(referenceMir.PackageType, mir.PackageType);
            Assert.Equal(referenceMir.ProductFamilyId, mir.ProductFamilyId);
            Assert.Equal(referenceMir.DateCode, mir.DateCode);
            Assert.Equal(referenceMir.TestFacilityId, mir.TestFacilityId);
            Assert.Equal(referenceMir.TestFloorId, mir.TestFloorId);
            Assert.Equal(referenceMir.FabProcessId, mir.FabProcessId);
            Assert.Equal(referenceMir.OperationFrequency, mir.OperationFrequency);
            Assert.Equal(referenceMir.TestSpecName, mir.TestSpecName);
            Assert.Equal(referenceMir.TestSpecVersion, mir.TestSpecVersion);
            Assert.Equal(referenceMir.TestFlowId, mir.TestFlowId);
            Assert.Equal(referenceMir.TestSetupId, mir.TestSetupId);
            Assert.Equal(referenceMir.DeviceDesignRev, mir.DeviceDesignRev);
            Assert.Equal(referenceMir.EngineringLotId, mir.EngineringLotId);
            Assert.Equal(referenceMir.RomCodeId, mir.RomCodeId);
            Assert.Equal(referenceMir.TesterSerialNumber, mir.TesterSerialNumber);
            Assert.Equal(referenceMir.SupervisorId, mir.SupervisorId);
        }
Ejemplo n.º 2
0
        public void LoadNextMicroInstruction()
        {
            _globalFunction.ComputeGlobalG();
            var index = _indexSelection.GetIndex();

            var address = GlobalG == "1" ? MIR.Substring(31, 8) : MIR.Substring(42, 8);

            if (index == byte.MaxValue)
            {
                _seq.PlusOneMAR();
            }
            else
            {
                _seq.LdMAR(address);
            }

            _seq.LdMIR();
        }
        public void Step()
        {
            if (!_asmLoaded && !_microInstructionsLoaded)
            {
                MessageBox.Show("Files not loaded!");
                return;
            }

            if (!_initialized)
            {
                Simulation.Initialize();
                _initialized            = true;
                MIR                     = Simulation.GetMicroInstruction();
                CurrentMicroInstruction = MicroInstructions[Convert.ToInt32(ArhitecturaCPU.Simulation.Simulation.MAR, 2)];
            }

            //GetNextMicroInstruction();
            string address;

            switch (_indexStep)
            {
            case 1:
                address            = MIR.Substring(0, 4);
                SBUS               = MicroInstructionInterpreter.SBUSSourceActions[address](SBUS);
                MainView.SBUS.Fill = new SolidColorBrush(Colors.Red);
                MainView.SBUSTextBox.Background = Brushes.Pink;
                break;

            case 2:
                address            = MIR.Substring(4, 4);
                DBUS               = MicroInstructionInterpreter.DBUSSourceActions[address](DBUS);
                MainView.SBUS.Fill = new SolidColorBrush(Colors.Red);
                MainView.SBUSTextBox.Background  = Brushes.White;
                MainView.DBUSSTextBox.Background = Brushes.Pink;
                break;

            case 3:
                address = MIR.Substring(8, 4);
                MicroInstructionInterpreter.ALUOperationActions[address]();
                MainView.DBUSSTextBox.Background = Brushes.White;
                MainView.ALUTextBox.Background   = Brushes.Pink;
                break;

            case 4:
                address = MIR.Substring(12, 4);
                MicroInstructionInterpreter.RBUSDestinationActions[address]();

                MainView.RBUS1.Fill = new SolidColorBrush(Colors.Red);
                MainView.RBUS2.Fill = new SolidColorBrush(Colors.Red);
                MainView.RBUS3.Fill = new SolidColorBrush(Colors.Red);

                MainView.ALUTextBox.Background  = Brushes.White;
                MainView.RBUSTextBox.Background = Brushes.Pink;
                break;

            case 5:
                address = MIR.Substring(16, 5);
                MicroInstructionInterpreter.OtherOperationActions[address]();
                MainView.RBUSTextBox.Background           = Brushes.White;
                MainView.OtherOperationTextBox.Background = Brushes.Pink;
                break;

            case 6:
                address = MIR.Substring(21, 2);
                MicroInstructionInterpreter.MemoryOperationActions[address]();
                MainView.OtherOperationTextBox.Background = Brushes.White;
                MainView.MemoryTextBox.Background         = Brushes.Pink;
                break;

            case 7:
                GetNextMicroInstruction();
                MainView.MemoryTextBox.Background = Brushes.White;
                MainView.JumpTextBox.Background   = Brushes.Pink;

                break;

            default:
                MainView.JumpTextBox.Background = Brushes.White;

                /*
                 * var indexInstr = SimpleMicroInstructions.First(instr => instr.MicroInstructionBinary == MIR);
                 * CurrentIndex = SimpleMicroInstructions.IndexOf(indexInstr);*/
                MainView.ResetView();
                CurrentIndex            = Convert.ToInt32(ArhitecturaCPU.Simulation.Simulation.MAR, 2);
                CurrentMicroInstruction = MicroInstructions[CurrentIndex];
                _indexStep = 0;
                break;
            }
            _indexStep++;
        }
Ejemplo n.º 4
0
        private bool ValidBlock2()
        {
            string temp   = Block_2;
            string sub    = null;
            bool   valid  = true;
            int    offset = 0;

            // Check the length first.
            // If this is wrong don't bother checking anything else.
            // Block 2 is optional therefore it is a valid message if it is not present
            if (Block_2 == null)
            {
                errors.Add("Block 2 -- Optional -- : NOT present");
                valid = true;
                return(valid);
            }
            else if (((Block_2.Length < MIN_BLOCK_2i_LEN) || (Block_2.Length > MAX_BLOCK_2i_LEN)) &&
                     ((Block_2.Length < MIN_BLOCK_2o_LEN) || (Block_2.Length > MAX_BLOCK_2o_LEN)))
            {
                errors.Add("Invalid length for block 2 : " + Block_2.Length);
                valid = false;
                return(valid);
            }

            // Check START OF BLOCK INDICATOR = {
            // This is a mandatory field.
            // The character { indicates the beginning of a block.
            if (temp[0] != '{')
            {
                errors.Add("BLOCK 2: Message missing START OF BLOCK INDICATOR ({)");
                valid = false;
            }

            temp = temp.Substring(1);
            // Check BLOCK IDENTIFIER = 3c
            // This is a mandatory field.
            // 1 to 3 alphanumeric characters used to define block contents.
            // This block identiifer must be 1.
            sub = temp.Substring(0, temp.IndexOf(':'));
            if (string.Equals(sub, "2") == false)
            {
                errors.Add("BLOCK 2: Invalid BLOCK IDENTIFIER : " + sub + " Expecting : 2");
                valid = false;
            }

            // We found the colon in the last step now get rid of it
            // This is a mandatory field.
            temp = temp.Substring(2);

            // Check the INPUT OUTPUT IDENTIFIER
            // This is a mandatory field.
            // For an input message, the Input/Output Identifier consists of the single letter 'I'
            // For an input message, the Input/Output Identifier consists of the single letter 'O'
            InputOutputID = temp.Substring(0, 1);
            if ((InputOutputID.Equals("I") == false) && (InputOutputID.Equals("O") == false))
            {
                errors.Add("BLOCK 2: Invalid INPUT OUTPUT IDENTIFIER : " + InputOutputID + " Expecting : I or O");
                valid = false;
            }

            // Check SWIFT MESSAGE TYPE
            // The Message Type consists of 3 digits which define the MT number of the message being input
            // NO CHECK NEEDED.
            // Move forward fitr IOId
            temp = temp.Substring(1);
            // Move forward for SWIFT message type.
            MessageType = temp.Substring(0, 3);
            if (IsValidMessageType(MessageType) == false)
            {
                errors.Add("BLOCK 2: Invalid SWIFT Message Type : " + MessageType);
                valid = false;
            }
            temp = temp.Substring(3);

            if (InputOutputID.Equals("I") == true)
            {
                // We now know it is an INPUT message check the length
                if ((Block_2.Length < MIN_BLOCK_2i_LEN) || (Block_2.Length > MAX_BLOCK_2i_LEN))
                {
                    errors.Add("Invalid length for block 2 INPUT Message: " + Block_2.Length + " Expection length between : " + MIN_BLOCK_2i_LEN + " and " + MAX_BLOCK_2i_LEN);
                    valid = false;
                    return(valid);
                }

                // The DESTINATION ADDRESS = 12x
                // This address is the 12-character SWIFT address of the receiver of the message.
                // It defines the destination to which the message should be sent.
                // NO CHECK needed
                DestinationAddress = temp.Substring(0, 12);
                temp = temp.Substring(12);

                // Check the PRIORITY = 1a
                // This character, used within FIN Application Headers only, defines the priority with which a message is delivered.
                // The possible values are:
                // S = System
                // U = Urgent
                // N = Normal
                Priority = temp.Substring(0, 1);
                if ((Priority.Equals("S") == false) && (Priority.Equals("U") == false) && (Priority.Equals("N") == false))
                {
                    errors.Add("BLOCK 2: PRIORITY not set: ");
                    valid    = false;
                    offset   = 0;
                    Priority = "";
                }
                else
                {
                    offset = 1;
                }

                // Check DELIVERY MONITORING = 1x
                // Delivery monitoring options apply only to FIN user-to-user messages. The chosen option is expressed as a single digit:
                // 1 = Non - Delivery Warning
                // 2 = Delivery Notification
                // 3 = Non - Delivery Warning and Delivery Notification
                // If the message has priority 'U', the user must request delivery monitoring option '1' or '3'.
                // If the message has priority 'N', the user can request delivery monitoring option '2' or, by leaving the option blank, no delivery monitoring.
                temp = temp.Substring(offset);
                DeliveryMonitoring = temp.Substring(0, 1);
                if (Priority.Equals("S"))
                {
                    if ((DeliveryMonitoring.Equals("1") == false) && (DeliveryMonitoring.Equals("1") == false) && (DeliveryMonitoring.Equals("3") == false) && (DeliveryMonitoring.Equals("") == false))
                    {
                        errors.Add("BLOCK 2: Invalid DELIVERY MONITORING - not set" + DeliveryMonitoring + " PRIORITY : " + Priority + " DELIVERY MONITORING MUST BE : 1, 2, 3 or blank");
                        valid = false;
                    }
                    else
                    {
                        offset = 1;
                    }
                }
                else if (Priority.Equals("U"))
                {
                    if ((DeliveryMonitoring.Equals("1") == false) && (DeliveryMonitoring.Equals("3") == false))
                    {
                        errors.Add("BLOCK 2: Invalid DELIVERY MONITORING - " + DeliveryMonitoring + " PRIORITY : " + Priority + " DELIVERY MONITORING MUST BE : 1 or 3");
                        valid = false;
                    }
                    else
                    {
                        offset = 1;
                    }
                }
                else if (Priority.Equals("N"))
                {
                    if ((DeliveryMonitoring.Equals("2") == false) && (DeliveryMonitoring.Equals("") == false))
                    {
                        errors.Add("BLOCK 2: Invalid DELIVERY MONITORING - " + DeliveryMonitoring + " PRIORITY : " + Priority + " DELIVERY MONITORING MUST BE : 2 or blank");
                        valid = false;
                    }
                    else
                    {
                        offset = 1;
                    }
                }
                else
                {
                    offset             = 0;
                    DeliveryMonitoring = "";
                }

                // Check OBSOLESCENCE PERIOD = 3n
                // The obsolescence period defines the period of time after which a Delayed Message (DLM) trailer is added to a FIN user-to-user message
                // when the message is delivered. For urgent priority messages, it is also the period of time after which, if the message remains undelivered,
                // a Non-Delivery Warning is generated.
                // The values for the obsolescence period are:
                // 003 (15 minutes) for 'U' priority, and
                // 020 (100 minutes) for 'N' priority.
                temp = temp.Substring(offset);
                ObsolescencePeriod = temp.Substring(0, 3);
                if (Priority.Equals("U"))
                {
                    if (ObsolescencePeriod.Equals("003") == false)
                    {
                        errors.Add("BLOCK 2: Invalid  OBSOLESCENCE PERIOD - " + ObsolescencePeriod + " PRIORITY : " + Priority + " DELIVERY MONITORING MUST BE : 003");
                        valid = false;
                    }
                }
                else if (Priority.Equals("N"))
                {
                    if (ObsolescencePeriod.Equals("020") == false)
                    {
                        errors.Add("BLOCK 2: Invalid  OBSOLESCENCE PERIOD - " + ObsolescencePeriod + " PRIORITY : " + Priority + " DELIVERY MONITORING MUST BE : 020");
                        valid = false;
                    }
                }

                // Check END OF BLOCK INDICATOR = }
                // This is a mandatory field.
                // The character } indicates the end of a block.
                temp = temp.Substring(3);
                if (temp[0] != '}')
                {
                    errors.Add("BLOCK 2: Message missing END OF BLOCK INDICATOR (})");
                    valid = false;
                }

                return(valid);
            }
            else if (InputOutputID.Equals("O") == true)
            {
                // We now know it is an OUTPUT message check the length
                if ((Block_2.Length < MIN_BLOCK_2o_LEN) || (Block_2.Length > MAX_BLOCK_2o_LEN))
                {
                    errors.Add("Invalid length for block 2 OUTPUT Message: " + Block_2.Length + " Expection length between : " + MIN_BLOCK_2o_LEN + " and " + MAX_BLOCK_2o_LEN);
                    valid = false;
                    return(valid);
                }

                // The INPUT TIME = HHMM
                // The Input Time local to the sender of the message.
                // The hour (HH) and minute (MM) on which the sender sent the message to SWIFT.
                // This is a mandatory field.
                InputTime = temp.Substring(0, 4);
                temp      = temp.Substring(4);

                // The MIR - Message Input Reference
                // The MIR consists of four elements:
                // 1.Sender's Date - Date when the Sender sent the message
                // 2.The Logical Termial (LT)Address is a 12 - character FIN address.
                //   It is the address of the sending LT for this message and includes the Branch Code. It consists of:
                //       -the Sender BIC 8 CODE(8 characters)
                //       - the Logical Terminal Code(1 upper case alphabetic character)
                //       - the Sender BIC Branch Code(3 characters). It defines the sender of the message to the SWIFT network.
                // 3.Session number - As appropriate, the current application session number based on the Login.See block 1, field 4
                // 4.Sequence number - See block 1, field 5
                MIR  = temp.Substring(0, 28);
                temp = temp.Substring(28);

                MIRSenderDate = MIR.Substring(0, 6);

                MIRLTAddress     = MIR.Substring(6, 12);
                MIRBICCode       = MIRLTAddress.Substring(0, 8);
                MIRLTCode        = MIRLTAddress.Substring(8, 1);;
                MIRBICBranchCode = MIRLTAddress.Substring(9, 3);

                MIRSessNum = MIR.Substring(18, 4);
                MIRSeqNum  = MIR.Substring(22, 6);

                // The OUTPUT DATE - YYMMDD
                // The output date, local to the receiver
                // This is a mandatory field
                OutputDate = temp.Substring(0, 6);
                temp       = temp.Substring(6);

                // The OUTPUT TIME - HHMM
                // The output time, local to the receiver
                // This is a mandatory field
                OutputTime = temp.Substring(0, 4);
                temp       = temp.Substring(4);

                // Check the PRIORITY = 1a
                // This character, used within FIN Application Headers only, defines the priority with which a message is delivered.
                // The possible values are:
                // S = System
                // U = Urgent
                // N = Normal
                Priority = temp.Substring(0, 1);
                if ((Priority.Equals("S") == false) && (Priority.Equals("U") == false) && (Priority.Equals("N") == false))
                {
                    errors.Add("BLOCK 2: PRIORITY -- OPTIONAL -- : not present");
                    valid    = false;
                    offset   = 0;
                    Priority = "";
                }
                else
                {
                    offset = 1;
                }

                // Check END OF BLOCK INDICATOR = }
                // This is a mandatory field.
                // The character } indicates the end of a block.
                temp = temp.Substring(offset);
                if (temp[0] != '}')
                {
                    errors.Add("BLOCK 2: Message missing END OF BLOCK INDICATOR (})");
                    valid = false;
                }
            }
            else
            {
                // Some how we corrupted the valid data we just had.
                errors.Add("BLOCK 2: Data corruption");
                valid = false;
            }

            return(valid);
        }
Ejemplo n.º 5
0
        public List <Stdf4Record> ReadStdf4(BinaryReader reader)
        {
            List <Stdf4Record> records;

            if (this.OnlyParse)
            {
                records = null;
            }
            else
            {
                records = new List <Stdf4Record>(capacity: this.InitialListCapacity);
            }

            int                pos          = 0;
            int                recordNumber = 0;
            Stdf4Record        rec;
            StdfValueConverter converter = new StdfValueConverter();

            try
            {
                ushort recordLength;
                while (true)
                {
                    if (this.ReverseBytesOnRead)
                    {
                        this._twoBytes[1] = reader.ReadByte();
                        this._twoBytes[0] = reader.ReadByte();
                        recordLength      = BitConverter.ToUInt16(_twoBytes, 0);
                    }
                    else
                    {
                        recordLength = reader.ReadUInt16();
                    }

                    var stdfMajorType  = reader.ReadByte();
                    var stdfMinorType  = reader.ReadByte();
                    int stdfRecordType = (((int)stdfMajorType) << 8) | (int)stdfMinorType;

                    // for a FAR record, always read 6 bytes since we don't know the byte order yet.
                    // Also avoiding a cast here.
                    byte[] bytes;
                    if (stdfRecordType == 10)
                    {
                        recordLength = 2;
                    }

                    bytes         = reader.ReadBytes(recordLength);
                    pos          += recordLength + 4;
                    recordNumber += 1;

                    //Three most common record types without a cast and outside the switch statement
                    if (this._debugLevel >= 3)
                    {
                        // Fall through to case statement for lots of printing.
                    }
                    else if (stdfRecordType == 3850)
                    {
                        if (this.OnlyParse)
                        {
                            var ignore_PTR = new PTR(bytes, converter);
                        }
                        else
                        {
                            records.Add(new PTR(bytes, converter));
                        }
                        continue;
                    }
                    else if (stdfRecordType == 1290)
                    {
                        if (this.OnlyParse)
                        {
                            var ignore_PIR = new PIR(bytes, converter);
                        }
                        else
                        {
                            records.Add(new PIR(bytes, converter));
                        }
                        continue;
                    }

                    if (this._debugLevel >= 3 || (this.Verbose && stdfMajorType != 5 && stdfMajorType != 10 && stdfMajorType != 15))
                    {
                        Console.WriteLine(string.Empty);
                        Console.WriteLine($"  Record {recordNumber} is {recordLength} bytes long (0x{recordLength:X2}) of type {stdfMajorType} - {stdfMinorType} ({stdfRecordType}).");
                        if (this._debugLevel > 0)
                        {
                            Console.Write((new LavaData.Util.Debug.HexDump(bytes)).ToString());
                            if (this._debugLevel > 1)
                            {
                                // We want the record length and record type/sub-type.
                                var newBytes = new byte[bytes.Length + 4];
                                (newBytes[0], newBytes[1]) = converter.UshortToBytes(recordLength);
                                newBytes[2] = stdfMajorType;
                                newBytes[3] = stdfMinorType;
                                for (int i = 0; i < bytes.Length; i++)
                                {
                                    newBytes[i + 4] = bytes[i];
                                }
                                Console.WriteLine((new LavaData.Util.Debug.HexDump(newBytes).ToHexByteString()));
                            }
                        }
                    }

                    rec = null;
                    if (Enum.IsDefined(typeof(Stdf4RecordType), stdfRecordType))
                    {
                        Stdf4RecordType recordType = (Stdf4RecordType)stdfRecordType;
                        switch ((Stdf4RecordType)stdfRecordType)
                        {
                        case Stdf4RecordType.PTR:
                            // UNREACHABLE CODE -- handled above, except with debug >=3
                            rec = new PTR(bytes, converter);
                            break;

                        case Stdf4RecordType.PIR:
                            // UNREACHABLE CODE -- handled above, except with debug >=3
                            rec = new PIR(bytes, converter);
                            break;

                        case Stdf4RecordType.PRR:
                            rec = new PRR(bytes, converter);
                            break;

                        case Stdf4RecordType.FAR:
                            var far = new FAR(bytes, converter);
                            converter.CpuType       = far.CpuType;
                            this.ReverseBytesOnRead = converter.ReverseBytesOnRead;
                            rec = far;
                            break;

                        //Data collected on a per lot basis; 1-NN Records
                        case Stdf4RecordType.MIR:
                            rec = new MIR(bytes, converter);
                            break;

                        case Stdf4RecordType.MRR:
                            rec = new MRR(bytes, converter);
                            break;

                        case Stdf4RecordType.PCR:
                            rec = new PCR(bytes, converter);
                            break;

                        case Stdf4RecordType.HBR:
                            rec = new HBR(bytes, converter);
                            break;

                        case Stdf4RecordType.SBR:
                            rec = new SBR(bytes, converter);
                            break;

                        case Stdf4RecordType.PMR:
                            throw new Stdf4ParserException("PMR  Not Implemented");

                        case Stdf4RecordType.PGR:
                            throw new Stdf4ParserException("PGR  Not Implemented");

                        case Stdf4RecordType.RDR:
                            throw new Stdf4ParserException("RDR  Not Implemented");

                        case Stdf4RecordType.SDR:
                            rec = new SDR(bytes, converter);
                            break;

                        // Data collected per Wafer; 2-NN Records.
                        case Stdf4RecordType.WIR:
                            rec = new WIR(bytes, converter);
                            break;

                        case Stdf4RecordType.WRR:
                            rec = new WRR(bytes, converter);
                            break;

                        case Stdf4RecordType.WCR:
                            rec = new WCR(bytes, converter);
                            break;

                        case Stdf4RecordType.TSR:
                            //throw new Stdf4ParserException("TSR  Not Implemented");
                            break;


                        // Generic Data; 50-NN Records.
                        case Stdf4RecordType.GDR:
                            //throw new Stdf4ParserException("GDR  Not Implemented");
                            break;

                        case Stdf4RecordType.DTR:
                            rec = new DTR(bytes, converter);
                            break;

                        default:
                            Console.WriteLine($"  Unhandled STDF4 Record Type: {recordType} ({stdfMajorType} - {stdfMinorType}).");
                            break;
                        }

                        if (rec != null)
                        {
                            if (this._debugLevel >= 3 || (this.Verbose && stdfRecordType != 1300))
                            {
                                // Don't print PRR (1300), lots of them, except at a high debug level.
                                Console.WriteLine(rec.ToString());
                            }

                            if (!this.OnlyParse)
                            {
                                records.Add(rec);
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine($"  No ENUM Defined for STDF4 Record Type: {stdfMajorType} - {stdfMinorType}.");
                    }
                }
            }
            catch (EndOfStreamException)
            {
                if (this.Verbose)
                {
                    Console.WriteLine("Read to the end of the stream!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unhandled Exception: " + ex.Message);
                Console.WriteLine(ex.StackTrace);
            }

            if (this.Verbose)
            {
                Console.WriteLine($"Read {recordNumber} records.");
            }

            return(records);
        }