From 54b61c863a33664764f23c66f19be3f085428e49 Mon Sep 17 00:00:00 2001 From: Zerog Date: Mon, 27 Feb 2023 11:15:44 +0100 Subject: [PATCH 1/2] HexWriter work --- .../cz/jaybee/intelhex/MemoryRegions.java | 3 +- src/main/java/cz/jaybee/intelhex/Record.java | 1 + .../java/cz/jaybee/intelhex/cli/PrintBin.java | 96 +++++++++ .../jaybee/intelhex/listeners/BinWriter.java | 49 +---- .../jaybee/intelhex/listeners/HexWriter.java | 182 ++++++++++++++++++ .../cz/jaybee/intelhex/listeners/Reader.java | 4 + .../cz/jaybee/intelhex/listeners/Writer.java | 58 ++++++ 7 files changed, 350 insertions(+), 43 deletions(-) create mode 100644 src/main/java/cz/jaybee/intelhex/cli/PrintBin.java create mode 100644 src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java create mode 100644 src/main/java/cz/jaybee/intelhex/listeners/Reader.java create mode 100644 src/main/java/cz/jaybee/intelhex/listeners/Writer.java diff --git a/src/main/java/cz/jaybee/intelhex/MemoryRegions.java b/src/main/java/cz/jaybee/intelhex/MemoryRegions.java index 91d9802..506b37b 100644 --- a/src/main/java/cz/jaybee/intelhex/MemoryRegions.java +++ b/src/main/java/cz/jaybee/intelhex/MemoryRegions.java @@ -42,8 +42,9 @@ public class MemoryRegions { public void add(long start, long length) { Region prevRegion; + if (regions.size() > 0) { - prevRegion = regions.get(regions.size() - 1); + prevRegion = regions.get(regions.size() - 1); //get last region long nextAddress = prevRegion.getAddressStart() + prevRegion.getLength(); if (nextAddress == start) { prevRegion.incLength(length); diff --git a/src/main/java/cz/jaybee/intelhex/Record.java b/src/main/java/cz/jaybee/intelhex/Record.java index 6fd0dd4..885cfd3 100644 --- a/src/main/java/cz/jaybee/intelhex/Record.java +++ b/src/main/java/cz/jaybee/intelhex/Record.java @@ -35,6 +35,7 @@ public class Record { public int address; public RecordType type; public byte[] data; + public byte checksum; /** * Convert the record to pretty string diff --git a/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java b/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java new file mode 100644 index 0000000..2c1a736 --- /dev/null +++ b/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015, Jan Breuer All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package cz.jaybee.intelhex.cli; + +import cz.jaybee.intelhex.DataListener; +import cz.jaybee.intelhex.IntelHexException; +import cz.jaybee.intelhex.Parser; +import cz.jaybee.intelhex.Region; +import cz.jaybee.intelhex.listeners.BinWriter; +import cz.jaybee.intelhex.listeners.RangeDetector; + +import java.io.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Class to demonstrate usage of Intel HEX parser + * + * @author Jan Breuer + */ +public class PrintBin { + + static long a = 0; + + + public static void main(String[] args) throws IOException, IntelHexException { + + // create input stream of some IntelHex data + InputStream is = new FileInputStream("/home/zerog/work/telesoft/master_slave/nrf_16.hex"); + + // create IntelHexParserObject + Parser ihp = new Parser(is); + + // register parser listener + ihp.setDataListener(new DataListener() { + + @Override + public void data(long address, byte[] data) { + System.out.println(address-a+" - "+getHumanMessage(data, " ")); + a = address; + } + + @Override + public void eof() { + // do some action + } + }); + ihp.parse(); + + } + + public static String getHumanMessage(byte[] inputArray, String determiner) { + + if(inputArray==null) { + return "null"; + } + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < inputArray.length; i++) { + String hex = Integer.toHexString(inputArray[i] & 0xFF).toUpperCase().trim(); + sb.append(new String(new char[2 - hex.length()]).replace('\0', '0')) + .append(hex) + .append(determiner); + } + + if (sb.length() > 0) { + return (sb.subSequence(0, sb.length() - determiner.length())).toString(); + } + + return sb.append(" (").append(inputArray.length).append(")").toString(); + } +} diff --git a/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java b/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java index 870781d..2b5e5a4 100644 --- a/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java +++ b/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java @@ -39,55 +39,20 @@ * * @author Jan Breuer */ -public class BinWriter implements DataListener { +public class BinWriter extends Writer { - private final Region outputRegion; - private final OutputStream destination; - private final byte[] buffer; - private final MemoryRegions regions; - private long maxAddress; - private final boolean minimize; + final boolean minimize; public BinWriter(Region outputRegion, OutputStream destination, boolean minimize) { - this.outputRegion = outputRegion; - this.destination = destination; + super(outputRegion, destination); this.minimize = minimize; - this.buffer = new byte[(int) (outputRegion.getLength())]; - Arrays.fill(buffer, (byte) 0xFF); - regions = new MemoryRegions(); - maxAddress = outputRegion.getAddressStart(); } @Override - public void data(long address, byte[] data) { - regions.add(address, data.length); - - if ((address >= outputRegion.getAddressStart()) && (address <= outputRegion.getAddressEnd())) { - int length = data.length; - if ((address + length) > outputRegion.getAddressEnd()) { - length = (int) (outputRegion.getAddressEnd() - address + 1); - } - System.arraycopy(data, 0, buffer, (int) (address - outputRegion.getAddressStart()), length); - - if (maxAddress < (address + data.length -1)) { - maxAddress = address + data.length - 1; - } - } - } - - @Override - public void eof() { - try { - if (!minimize) { - maxAddress = outputRegion.getAddressEnd(); - } - destination.write(buffer, 0, (int)(maxAddress - outputRegion.getAddressStart() + 1)); - } catch (IOException ex) { - Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex); + void write() throws IOException { + if (!minimize) { + maxAddress = outputRegion.getAddressEnd(); } + destination.write(buffer, 0, (int)(maxAddress - outputRegion.getAddressStart() + 1)); } - - public MemoryRegions getMemoryRegions() { - return regions; - } } diff --git a/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java b/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java new file mode 100644 index 0000000..92962f0 --- /dev/null +++ b/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java @@ -0,0 +1,182 @@ +package cz.jaybee.intelhex.listeners; + +import cz.jaybee.intelhex.Record; +import cz.jaybee.intelhex.RecordType; +import cz.jaybee.intelhex.Region; + +import java.io.*; + +public class HexWriter extends Writer { + + public HexWriter(Region outputRegion, OutputStream destination) { + super(outputRegion, destination); + } + + public void appendPrefix(byte[] data) { + byte[] newBuffer = new byte[buffer.length + data.length]; + + //copy whole buffer to bigger + System.arraycopy(buffer, 0, newBuffer, data.length, newBuffer.length); + buffer = newBuffer; + + replaceData(0, data); + } + + public void replaceData(int address, byte[] data) { + //TODO test address + System.arraycopy(data, 0, buffer, address, data.length); + } + + @Override + void write() throws IOException { + + try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(destination))) { + + //cuts data to 16 bytes blocks + //if 0xFF are redundant, skip it + int i = 0; + while (i < buffer.length) { + byte[] recordData = new byte[16]; //line block of data + + int len = 0; + boolean detected0xFF = false; + boolean first0xFF = true; + + int skipIndex = 0; + for (int j = 0; j < 16; j++, skipIndex++) { + + if (buffer[i + j] != (byte) 0xff) { + + if (detected0xFF) { + //if 0xFF is detected + //and then NON 0xFF is detected + //go out of for and print line + break; + } + + recordData[j] = buffer[i + j]; + len++; + + } else { + + + if (first0xFF) { + first0xFF = false; + if (buffer[i + j + 1] != (byte) 0xff) { + //if first 0xFF is detected and after it + //is normal non 0xFF, then 0xFF doesn't skip + recordData[j] = buffer[i + j]; + len++; + continue; + } + } + + detected0xFF = true; + } + } + + Record record = new Record(); + record.length = len; + record.address = i; + record.data = recordData; + record.type = RecordType.DATA; + sumCalculator(record); + + if (len > 0) { + i += len; + bw.write(getLine(record)); + continue; + } + + //if len == 0, meaning only 0xFF lines + //so skip it + i += skipIndex; + } + + + //EOF record + Record record = new Record(); + record.length = 0; + record.address = 0x0000; + record.data = new byte[0]; + record.type = RecordType.EOF; + sumCalculator(record); + + bw.write(getLine(record)); + } + } + + public void sumCalculator(Record record) { + int sum = 0; + + //data + for (int i = 0; i < record.length; i++) { + sum += record.data[i] & 0xff; + } + + //address + sum += record.address & 0xff; + sum += (record.address >> 8) & 0xff; + + //type + sum += record.type.toInt() & 0xff; + + //length + sum += record.length; + + //sum + record.checksum = (byte) (~(sum & 0xff) + 1); + } + + private byte[] intTo1BytesArr(int data) { + return new byte[]{ + (byte) ((data) & 0xff), + }; + } + + private byte[] intTo2BytesArr(int data) { + return new byte[]{ + (byte) ((data >> 8) & 0xff), + (byte) ((data) & 0xff), + }; + } + + + public String getLine(Record record) { + + StringBuilder sb = new StringBuilder(":"); + //sb.append("L>"); + + get(sb, intTo1BytesArr(record.length)); + //sb.append(" A>"); + + get(sb, intTo2BytesArr(record.address)); + //sb.append(" T>"); + + get(sb, intTo1BytesArr(record.type.toInt())); + //sb.append(" D>"); + get(sb, record.data, record.length); + + //sb.append(" C>"); + get(sb, intTo1BytesArr(record.checksum)); + + sb.append("\r\n"); //old windows line separator + + System.out.print(sb.toString().toUpperCase()); + + return sb.toString().toUpperCase(); + } + + private void get(StringBuilder sb, byte[] arr) { + get(sb, arr, arr.length); + } + + private void get(StringBuilder sb, byte[] arr, int len) { + for (int i = 0; i < len; i++) { + byte b = arr[i]; + String hex = Integer.toHexString(b & 0xFF).trim(); + sb.append(new String(new char[2 - hex.length()]).replace('\0', '0')) + .append(hex); + } + } +} diff --git a/src/main/java/cz/jaybee/intelhex/listeners/Reader.java b/src/main/java/cz/jaybee/intelhex/listeners/Reader.java new file mode 100644 index 0000000..0ee38e5 --- /dev/null +++ b/src/main/java/cz/jaybee/intelhex/listeners/Reader.java @@ -0,0 +1,4 @@ +package cz.jaybee.intelhex.listeners; + +public class Reader { +} diff --git a/src/main/java/cz/jaybee/intelhex/listeners/Writer.java b/src/main/java/cz/jaybee/intelhex/listeners/Writer.java new file mode 100644 index 0000000..c3a7e49 --- /dev/null +++ b/src/main/java/cz/jaybee/intelhex/listeners/Writer.java @@ -0,0 +1,58 @@ +package cz.jaybee.intelhex.listeners; + +import cz.jaybee.intelhex.DataListener; +import cz.jaybee.intelhex.Region; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; + +public abstract class Writer implements DataListener { + + final Region outputRegion; + final OutputStream destination; + byte[] buffer; + //private final MemoryRegions regions; + long maxAddress; + + public Writer(Region outputRegion, OutputStream destination) { + this.outputRegion = outputRegion; + this.destination = destination; + this.buffer = new byte[(int) (outputRegion.getLength())]; + Arrays.fill(buffer, (byte) 0xFF); + //regions = new MemoryRegions(); + maxAddress = outputRegion.getAddressStart(); + } + + @Override + public void data(long address, byte[] data) { + //regions.add(address, data.length); + + if ((address >= outputRegion.getAddressStart()) && (address <= outputRegion.getAddressEnd())) { + int length = data.length; + + if ((address + length) > outputRegion.getAddressEnd()) { + length = (int) (outputRegion.getAddressEnd() - address + 1); + } + System.arraycopy(data, 0, buffer, (int) (address - outputRegion.getAddressStart()), length); + + if (maxAddress < (address + data.length -1)) { + maxAddress = address + data.length - 1; + } + } + } + + @Override + public void eof() { + try { + write(); + } catch (IOException ex) { + Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex); + } + } + + abstract void write() throws IOException; + +} From e0d993d201a10e3a015e4d1b02bf5b0556ee710b Mon Sep 17 00:00:00 2001 From: Zerog Date: Tue, 28 Feb 2023 23:05:41 +0100 Subject: [PATCH 2/2] Modified HexEditor and PrintBin --- .../cz/jaybee/intelhex/cli/HexEditor.java | 94 +++++++++++++++++++ .../java/cz/jaybee/intelhex/cli/PrintBin.java | 68 +++++++++----- .../jaybee/intelhex/listeners/BinWriter.java | 22 +++-- .../jaybee/intelhex/listeners/HexWriter.java | 48 ++++++---- .../cz/jaybee/intelhex/listeners/Reader.java | 4 - .../cz/jaybee/intelhex/listeners/Writer.java | 22 ++--- 6 files changed, 192 insertions(+), 66 deletions(-) create mode 100644 src/main/java/cz/jaybee/intelhex/cli/HexEditor.java delete mode 100644 src/main/java/cz/jaybee/intelhex/listeners/Reader.java diff --git a/src/main/java/cz/jaybee/intelhex/cli/HexEditor.java b/src/main/java/cz/jaybee/intelhex/cli/HexEditor.java new file mode 100644 index 0000000..c3cf6a6 --- /dev/null +++ b/src/main/java/cz/jaybee/intelhex/cli/HexEditor.java @@ -0,0 +1,94 @@ +package cz.jaybee.intelhex.cli; + +import cz.jaybee.intelhex.IntelHexException; +import cz.jaybee.intelhex.Parser; +import cz.jaybee.intelhex.listeners.HexWriter; +import cz.jaybee.intelhex.listeners.RangeDetector; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class HexEditor { + + public static void main(String[] args) throws IOException, IntelHexException { + String fileIn = "input.hex"; + String fileOut = "output.hex"; + int address = 0x00; + boolean replace = false; + byte[] data = new byte[0]; + + if (args.length == 0) { + System.out.println("usage:"); + System.out.println(" hexEditor -replace "); + System.out.println(); + return; + } + + if (args.length >= 1) { + fileIn = args[0]; + } + + if (args.length >= 2) { + fileOut = args[1]; + } + + if (args.length >= 3 && "-replace".equals(args[2])) { + replace = true; + + if (args.length >= 4) { + address = Integer.parseInt(args[3].substring(2),16); + } + + if (args.length >= 5) { + data = fromHexString(args[4].substring(2)); + } + } + + + try (FileInputStream is = new FileInputStream(fileIn)) { + OutputStream os = Files.newOutputStream(Paths.get(fileOut)); + Parser parser = new Parser(is); + + // 1st iteration - calculate maximum output range + RangeDetector rangeDetector = new RangeDetector(); + parser.setDataListener(rangeDetector); + parser.parse(); + is.getChannel().position(0); + + // 2nd iteration - actual write of the output + HexWriter hexWriter = new HexWriter(rangeDetector.getFullRangeRegion(), os); + + parser.setDataListener(hexWriter); + parser.parse(); + + if(replace) { + hexWriter.replaceData(address, data); + } + + + //save into file + hexWriter.save(); + + } catch (IOException ex) { + Logger.getLogger(Hex2bin.class.getName()).log(Level.SEVERE, null, ex); + } + + } + + private static byte[] fromHexString(final String encoded) throws IntelHexException { + if ((encoded.length() % 2) != 0) + throw new IntelHexException("Input string must contain an even number of characters"); + + final byte[] result = new byte[encoded.length()/2]; + final char[] enc = encoded.toCharArray(); + + for (int i = 0; i < enc.length; i += 2) { + result[i/2] = (byte) Integer.parseInt(String.valueOf(enc[i]) + enc[i + 1], 16); + } + + return result; + } +} diff --git a/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java b/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java index 2c1a736..fd5cd7c 100644 --- a/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java +++ b/src/main/java/cz/jaybee/intelhex/cli/PrintBin.java @@ -25,22 +25,16 @@ */ package cz.jaybee.intelhex.cli; -import cz.jaybee.intelhex.DataListener; import cz.jaybee.intelhex.IntelHexException; import cz.jaybee.intelhex.Parser; -import cz.jaybee.intelhex.Region; -import cz.jaybee.intelhex.listeners.BinWriter; import cz.jaybee.intelhex.listeners.RangeDetector; +import cz.jaybee.intelhex.listeners.Writer; import java.io.*; +import java.nio.file.Paths; import java.util.logging.Level; import java.util.logging.Logger; -/** - * Class to demonstrate usage of Intel HEX parser - * - * @author Jan Breuer - */ public class PrintBin { static long a = 0; @@ -48,35 +42,58 @@ public class PrintBin { public static void main(String[] args) throws IOException, IntelHexException { + String fileIn = "input.hex"; + + if (args.length == 0) { + System.out.println("Just print binary data from IntelHex file to console"); + System.out.println(); + System.out.println("usage:"); + System.out.println(" PrintBin "); + System.out.println(); + return; + } + + if (args.length >= 1) { + fileIn = args[0]; + } + // create input stream of some IntelHex data - InputStream is = new FileInputStream("/home/zerog/work/telesoft/master_slave/nrf_16.hex"); + FileInputStream is = new FileInputStream(Paths.get(fileIn).toFile()); // create IntelHexParserObject - Parser ihp = new Parser(is); + Parser parser = new Parser(is); + + // 1st iteration - calculate maximum output range + RangeDetector rangeDetector = new RangeDetector(); + parser.setDataListener(rangeDetector); + parser.parse(); + is.getChannel().position(0); // register parser listener - ihp.setDataListener(new DataListener() { + parser.setDataListener(new Writer(rangeDetector.getFullRangeRegion()) { + @Override - public void data(long address, byte[] data) { - System.out.println(address-a+" - "+getHumanMessage(data, " ")); - a = address; + public void write() throws IOException { + printHumanMessage(buffer, " "); } @Override public void eof() { - // do some action + try { + write(); + } catch (IOException e) { + Logger.getLogger(Hex2bin.class.getName()).log(Level.SEVERE, null, e); + } } }); - ihp.parse(); - } + System.out.println(); + parser.parse(); - public static String getHumanMessage(byte[] inputArray, String determiner) { + } - if(inputArray==null) { - return "null"; - } + public static void printHumanMessage(byte[] inputArray, String determiner) { StringBuilder sb = new StringBuilder(); @@ -85,12 +102,15 @@ public static String getHumanMessage(byte[] inputArray, String determiner) { sb.append(new String(new char[2 - hex.length()]).replace('\0', '0')) .append(hex) .append(determiner); + + if((i+1)%16==0) { + System.out.println(sb); + sb.delete(0, sb.length()); + } } if (sb.length() > 0) { - return (sb.subSequence(0, sb.length() - determiner.length())).toString(); + System.out.println(sb); } - - return sb.append(" (").append(inputArray.length).append(")").toString(); } } diff --git a/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java b/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java index 2b5e5a4..7ca41e1 100644 --- a/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java +++ b/src/main/java/cz/jaybee/intelhex/listeners/BinWriter.java @@ -1,16 +1,16 @@ /** * Copyright (c) 2015, Jan Breuer All rights reserved. - * + *

* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + *

* * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + *

* * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + *

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -28,6 +28,7 @@ import cz.jaybee.intelhex.DataListener; import cz.jaybee.intelhex.MemoryRegions; import cz.jaybee.intelhex.Region; + import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; @@ -49,10 +50,19 @@ public BinWriter(Region outputRegion, OutputStream destination, boolean minimize } @Override - void write() throws IOException { + public void write() throws IOException { if (!minimize) { maxAddress = outputRegion.getAddressEnd(); } - destination.write(buffer, 0, (int)(maxAddress - outputRegion.getAddressStart() + 1)); + destination.write(buffer, 0, (int) (maxAddress - outputRegion.getAddressStart() + 1)); + } + + @Override + public void eof() { + try { + write(); + } catch (IOException ex) { + Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex); + } } } diff --git a/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java b/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java index 92962f0..565c678 100644 --- a/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java +++ b/src/main/java/cz/jaybee/intelhex/listeners/HexWriter.java @@ -1,10 +1,13 @@ package cz.jaybee.intelhex.listeners; +import cz.jaybee.intelhex.IntelHexException; import cz.jaybee.intelhex.Record; import cz.jaybee.intelhex.RecordType; import cz.jaybee.intelhex.Region; import java.io.*; +import java.util.logging.Level; +import java.util.logging.Logger; public class HexWriter extends Writer { @@ -12,23 +15,36 @@ public HexWriter(Region outputRegion, OutputStream destination) { super(outputRegion, destination); } - public void appendPrefix(byte[] data) { + public void appendPrefix(byte[] data) throws IntelHexException { byte[] newBuffer = new byte[buffer.length + data.length]; //copy whole buffer to bigger - System.arraycopy(buffer, 0, newBuffer, data.length, newBuffer.length); + System.arraycopy(buffer, 0, newBuffer, data.length, buffer.length); buffer = newBuffer; replaceData(0, data); } - public void replaceData(int address, byte[] data) { - //TODO test address + public void replaceData(int address, byte[] data) throws IntelHexException { + + if(address < 0 ) { + throw new IntelHexException("Replace error. Invalid address. Address=(" + address + ") < 0"); + } + + if(address + data.length > buffer.length) { + throw new IntelHexException("Replace error. Invalid address. Address+data.length=(" + address+data.length + ") > buffer length=(" + buffer.length+")"); + } + System.arraycopy(data, 0, buffer, address, data.length); } @Override - void write() throws IOException { + public void eof() { + //do nothing when eof is detected + } + + @Override + public void write() throws IOException { try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(destination))) { @@ -145,26 +161,14 @@ private byte[] intTo2BytesArr(int data) { public String getLine(Record record) { StringBuilder sb = new StringBuilder(":"); - //sb.append("L>"); - get(sb, intTo1BytesArr(record.length)); - //sb.append(" A>"); - get(sb, intTo2BytesArr(record.address)); - //sb.append(" T>"); - get(sb, intTo1BytesArr(record.type.toInt())); - //sb.append(" D>"); get(sb, record.data, record.length); - - //sb.append(" C>"); get(sb, intTo1BytesArr(record.checksum)); sb.append("\r\n"); //old windows line separator - - System.out.print(sb.toString().toUpperCase()); - - return sb.toString().toUpperCase(); + return sb.toString().toUpperCase(); } private void get(StringBuilder sb, byte[] arr) { @@ -179,4 +183,12 @@ private void get(StringBuilder sb, byte[] arr, int len) { .append(hex); } } + + public void save() { + try { + write(); + } catch (IOException ex) { + Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex); + } + } } diff --git a/src/main/java/cz/jaybee/intelhex/listeners/Reader.java b/src/main/java/cz/jaybee/intelhex/listeners/Reader.java deleted file mode 100644 index 0ee38e5..0000000 --- a/src/main/java/cz/jaybee/intelhex/listeners/Reader.java +++ /dev/null @@ -1,4 +0,0 @@ -package cz.jaybee.intelhex.listeners; - -public class Reader { -} diff --git a/src/main/java/cz/jaybee/intelhex/listeners/Writer.java b/src/main/java/cz/jaybee/intelhex/listeners/Writer.java index c3a7e49..4e4ff84 100644 --- a/src/main/java/cz/jaybee/intelhex/listeners/Writer.java +++ b/src/main/java/cz/jaybee/intelhex/listeners/Writer.java @@ -11,12 +11,15 @@ public abstract class Writer implements DataListener { - final Region outputRegion; - final OutputStream destination; - byte[] buffer; + protected final Region outputRegion; + protected final OutputStream destination; + protected byte[] buffer; //private final MemoryRegions regions; - long maxAddress; + protected long maxAddress; + public Writer(Region outputRegion) { + this(outputRegion, null); + } public Writer(Region outputRegion, OutputStream destination) { this.outputRegion = outputRegion; this.destination = destination; @@ -44,15 +47,6 @@ public void data(long address, byte[] data) { } } - @Override - public void eof() { - try { - write(); - } catch (IOException ex) { - Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex); - } - } - - abstract void write() throws IOException; + public abstract void write() throws IOException; }