bufferToHex method
Write data to file f in HEX format.
f filename or file-like object for writing
writeStartAddr enable or disable writing start address
record to file (enabled by default).
If there is no start address in obj, nothing
will be written regardless of this setting.
eolstyle can be used to force CRLF line-endings
for output file on different platforms.
Supported eol styles: 'native', 'CRLF'.
byteCount number of bytes in the data field
Implementation
String bufferToHex({bool writeStartAddr = true, EOLStyle eolstyle = EOLStyle.native, int byteCount = 16}){
if (byteCount > 255 || byteCount < 1){
throw("wrong byteCount value: $byteCount");
}
String eol = IntelHex._getEolTextfile(eolstyle);
String fwrite = '';
// # Translation table for uppercasing hex ascii string.
// # timeit shows that using hexstr.translate(table)
// # is faster than hexstr.upper():
// # 0.452ms vs. 0.652ms (translate vs. upper)
// if sys.version_info[0] >= 3
// # Python 3
// table = bytes(range_l(256)).upper()
// else:
// # Python 2
// table = ''.join(chr(i).upper() for i in range_g(256))
// # start address record if any
if (startAddress != null && writeStartAddr){
List<String> keys = startAddress!.keys.toList();
keys.sort();
Uint8List bin = Uint8List(9);//array('B', asbytes('\0'*9));
if(keys == ['CS','IP']){
// Start Segment Address Record
bin[0] = 4; //# reclen
bin[1] = 0; //# offset msb
bin[2] = 0; //# offset lsb
bin[3] = 3; //# rectyp
int cs = startAddress!['CS']!;
bin[4] = (cs >> 8) & 0x0FF;
bin[5] = cs & 0x0FF;
int ip = startAddress!['IP']!;
bin[6] = (ip >> 8) & 0x0FF;
bin[7] = ip & 0x0FF;
bin[8] = -Struct.sum(bin) & 0x0FF; //# chksum
fwrite += ':${hexlify(bin)}$eol';//.translate(table)
}
else if(keys == ['EIP']){
// # Start Linear Address Record
bin[0] = 4; //# reclen
bin[1] = 0; //# offset msb
bin[2] = 0; //# offset lsb
bin[3] = 5; //# rectyp
int eip = startAddress!['EIP']!;
bin[4] = (eip >> 24) & 0x0FF;
bin[5] = (eip >> 16) & 0x0FF;
bin[6] = (eip >> 8) & 0x0FF;
bin[7] = eip & 0x0FF;
bin[8] = -Struct.sum(bin) & 0x0FF; //# chksum
fwrite += ':${hexlify(bin)}$eol';//.translate(table)
}
else{
logger?.verbose('InvalidStartAddressValueError(start_addr=start_addr)');
}
}
// # data
List<int> addresses = buffer.keys.toList();
addresses.sort();
int addrLength = addresses.length;
if(addrLength > 0){
int minAddr = addresses[0];
int maxAddr = addresses[addresses.length-1];
bool needOffsetRecord = maxAddr > 65535?true:false;
int highOFS = 0;
int curAddress = minAddr;
int curIX = 0;
while (curAddress <= maxAddr){
if (needOffsetRecord){
Uint8List bin = Uint8List(7);//array('B', asbytes('\0'*7));
bin[0] = 2; // # reclen
bin[1] = 0; // # offset msb
bin[2] = 0; // # offset lsb
bin[3] = 4; // # rectyp
highOFS = curAddress>>16;
List<int> b = Struct.divmod(highOFS, 256);
bin[4] = b[0]; //# msb of highOFS
bin[5] = b[1]; //# lsb of highOFS
bin[6] = -Struct.sum(bin) & 0x0FF; //# chksum
fwrite += ':${hexlify(bin)}$eol';//.translate(table)
}
while(true){
//# produce one record
int lowAddress = curAddress & 0x0FFFF;
//# chainLength off by 1
int chainLength = min(min(byteCount-1, 65535-lowAddress), maxAddr-curAddress);
//# search continuous chain
int stopAddress = curAddress + chainLength;
if (chainLength != 0){
int ix = bisect_right(addresses, stopAddress,lo: curIX, hi: min(curIX+chainLength+1, addrLength));
chainLength = ix - curIX; //# real chainLength
// # there could be small holes in the chain
// # but we will catch them by try-except later
// # so for big continuous files we will work
// # at maximum possible speed
}
else{
chainLength = 1; //# real chainLength
}
Uint8List bin = Uint8List(5+chainLength);//array('B', asbytes('\0'*(5+chainLength)));
List<int> b = Struct.divmod(lowAddress, 256);
bin[1] = b[0]; //# msb of lowAddress
bin[2] = b[1]; //# lsb of lowAddress
bin[3] = 0; //# rectype
int i = 0;
try{ //# if there is small holes we'll catch them
for(i = 0; i < chainLength;i++){// i in range_g(chainLength):
bin[4+i] = buffer[curAddress+i]!;
}
}
catch(e){
//# we catch a hole so we should shrink the chain
chainLength = i;
bin = bin.sublist(0,5+i);//bin[:5+i];
}
bin[0] = chainLength;
bin[4+chainLength] = -Struct.sum(bin) & 0x0FF; //# chksum
fwrite += ':${hexlify(bin)}$eol';//.translate(table)
//# adjust curAddress/curIX
curIX += chainLength;
if (curIX < addrLength){
curAddress = addresses[curIX];
}
else{
curAddress = maxAddr + 1;
break;
}
int highAddress = curAddress>>16;
if (highAddress > highOFS){
break;
}
}
}
}
//# end-of-file record
fwrite += ":00000001FF$eol";
return fwrite;
}