-
Notifications
You must be signed in to change notification settings - Fork 13
HexEditor #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
HexEditor #10
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 <hex_in> <hex_out> -replace <start address> <data>"); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest, I really don't understand what it should do and how to use it. |
||
| 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; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| /** | ||
| * 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.IntelHexException; | ||
| import cz.jaybee.intelhex.Parser; | ||
| 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; | ||
|
|
||
| public class PrintBin { | ||
|
|
||
| static long a = 0; | ||
|
|
||
|
|
||
| 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"); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please avoid filler words like "just". |
||
| System.out.println(); | ||
| System.out.println("usage:"); | ||
| System.out.println(" PrintBin <file_in>"); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The usual name for this functionality is hexdump. |
||
| System.out.println(); | ||
| return; | ||
| } | ||
|
|
||
| if (args.length >= 1) { | ||
| fileIn = args[0]; | ||
| } | ||
|
|
||
| // create input stream of some IntelHex data | ||
| FileInputStream is = new FileInputStream(Paths.get(fileIn).toFile()); | ||
|
|
||
| // create IntelHexParserObject | ||
| 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 | ||
| parser.setDataListener(new Writer(rangeDetector.getFullRangeRegion()) { | ||
|
|
||
|
|
||
| @Override | ||
| public void write() throws IOException { | ||
| printHumanMessage(buffer, " "); | ||
| } | ||
|
|
||
| @Override | ||
| public void eof() { | ||
| try { | ||
| write(); | ||
| } catch (IOException e) { | ||
| Logger.getLogger(Hex2bin.class.getName()).log(Level.SEVERE, null, e); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| System.out.println(); | ||
| parser.parse(); | ||
|
|
||
| } | ||
|
|
||
| public static void printHumanMessage(byte[] inputArray, String determiner) { | ||
|
|
||
| StringBuilder sb = new StringBuilder(); | ||
|
|
||
| for (int i = 0; i < inputArray.length; i++) { | ||
| String hex = Integer.toHexString(inputArray[i] & 0xFF).toUpperCase().trim(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same problem as in |
||
| sb.append(new String(new char[2 - hex.length()]).replace('\0', '0')) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| .append(hex) | ||
| .append(determiner); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. usually, it is called |
||
|
|
||
| if((i+1)%16==0) { | ||
| System.out.println(sb); | ||
| sb.delete(0, sb.length()); | ||
| } | ||
| } | ||
|
|
||
| if (sb.length() > 0) { | ||
| System.out.println(sb); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,16 @@ | ||
| /** | ||
| * Copyright (c) 2015, Jan Breuer All rights reserved. | ||
| * | ||
| * <p> | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please no html tags in license |
||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions are met: | ||
| * | ||
| * <p> | ||
| * * Redistributions of source code must retain the above copyright notice, | ||
| * this list of conditions and the following disclaimer. | ||
| * | ||
| * <p> | ||
| * * 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. | ||
| * | ||
| * <p> | ||
| * 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; | ||
|
|
@@ -39,55 +40,29 @@ | |
| * | ||
| * @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; | ||
| } | ||
| public void write() throws IOException { | ||
| if (!minimize) { | ||
| maxAddress = outputRegion.getAddressEnd(); | ||
| } | ||
| destination.write(buffer, 0, (int) (maxAddress - outputRegion.getAddressStart() + 1)); | ||
| } | ||
|
|
||
| @Override | ||
| public void eof() { | ||
| public void eof() { | ||
| try { | ||
| if (!minimize) { | ||
| maxAddress = outputRegion.getAddressEnd(); | ||
| } | ||
| destination.write(buffer, 0, (int)(maxAddress - outputRegion.getAddressStart() + 1)); | ||
| write(); | ||
| } catch (IOException ex) { | ||
| Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex); | ||
| } | ||
| } | ||
|
|
||
| public MemoryRegions getMemoryRegions() { | ||
| return regions; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it better to have a method
public byte getChecksum()to calculate checksum here?