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);
}