/// <summary> /// Add the payload of an SRecord to the appropriate blob, or create a new blob if necessary. /// </summary> public void ProcessRecord(SRecord record) { if (record.Payload == null) { return; } foreach (Blob blob in this.Blobs) { if (blob.NextByteAddress == record.Address) { blob.AddRecord(record.Payload); return; } } Blob newBlob = new Blob(record.Address, record.Payload); this.Blobs.Add(newBlob); }
private bool TryProcessRecord(Patch patch, SRecord record) { if (record.Payload == null) { return(true); } int startAddress = (int)(this.apply ? patch.StartAddress : patch.StartAddress + Patcher.BaselineOffset); int endAddress = (int)(this.apply ? patch.EndAddress : patch.EndAddress + Patcher.BaselineOffset); for (uint address = record.Address; address < record.Address + record.Payload.Length; address++) { if (address >= startAddress && address <= endAddress) { this.romStream.Position = address; int i = this.romStream.ReadByte(); if (i == -1) { Console.WriteLine("Reached end of file while trying to verify address {0:X8}", address); return(false); } int recordAddresss = (int)(this.apply ? record.Address : record.Address - Patcher.BaselineOffset); uint payloadIndex = address - record.Address; byte b = record.Payload[payloadIndex]; if (i != b) { Console.WriteLine("Address {0:X8} contains {1:X2}, but should contain {2:X2}", address, b, payloadIndex); return(false); } } } return(true); }
/// <summary> /// Read the next record from an SRecord file. /// </summary> /// <returns>True if there are more records, false if EOF.</returns> public bool TryReadNextRecord(out SRecord record) { string line = this.reader.ReadLine(); if (line == null) { record = null; return(false); } this.lineNumber++; if (line == string.Empty) { record = new SRecord('?', line); return(true); } char s = line[0]; if (s != 'S') { record = new SRecord('?', line); return(true); } char typeCode = line[1]; int addressBytes = 0; bool header = false; bool data = false; bool totalCount = false; bool startAddress = false; switch (typeCode) { case '0': addressBytes = 2; header = true; break; case '1': addressBytes = 2; data = true; break; case '2': addressBytes = 3; data = true; break; case '3': addressBytes = 4; data = true; break; case '5': addressBytes = 2; totalCount = true; break; case '7': addressBytes = 4; startAddress = true; break; case '8': addressBytes = 3; startAddress = true; break; case '9': addressBytes = 2; startAddress = true; break; default: record = new SRecord(typeCode, line, lineNumber); return(true); } int index = 2; int checksum = 0; int count = GetByte(line, ref index, ref checksum); uint address = GetByte(line, ref index, ref checksum); address <<= 8; address += GetByte(line, ref index, ref checksum); if (addressBytes >= 3) { address <<= 8; address += GetByte(line, ref index, ref checksum); } if (addressBytes == 4) { address <<= 8; address += GetByte(line, ref index, ref checksum); } if (startAddress) { record = new SRecord(typeCode, address); this.recordCount++; return(true); } if (totalCount) { record = new SRecord(typeCode, this.recordCount, (int)address); return(true); } List <byte> bytes = new List <byte>(); StringBuilder headerBuilder = new StringBuilder(); for (int payloadIndex = 0; payloadIndex < count - (addressBytes + 1); payloadIndex++) { byte temp = GetByte(line, ref index, ref checksum); bytes.Add(temp); } int unused = 0; byte actualChecksum = (byte)(0xFF & checksum); actualChecksum ^= 0xFF; byte expectedChecksum = GetByte(line, ref index, ref unused); if (actualChecksum != expectedChecksum) { string message = string.Format( "On line {0}, the actual checksum is 0x{1:X2}, but should be 0x{2:X2}", lineNumber, actualChecksum, expectedChecksum); throw new System.Exception(message + Environment.NewLine + line); } if (header) { byte[] array = bytes.ToArray(); string headerText = ASCIIEncoding.ASCII.GetString(array); record = new SRecord(typeCode, headerText); this.recordCount++; return(true); } if (data) { List <string> byteStrings = new List <string>(); foreach (byte b in bytes) { byteStrings.Add(b.ToString("X2")); } record = new SRecord(typeCode, address, bytes.ToArray()); this.recordCount++; return(true); } throw new NotSupportedException("SRecordParser is confused by this line: " + line); }