A simple FileHandler which allows editing of arbitrary binary data.
It can be used to modify the contents of any file on a byte by byte level. The files contents are fully loaded into memory and presented in a hexadecimal and ASCII table, a way very common among HEX editors.
ASCII control characters (those bytes with a value below 0x20) are displayed in a lighter color in the HEX table than other bytes. They display a tooltip text with the meaning of that byte when hovering the mouse cursor above them.
Modification of bytes is possible both in the per byte hexadecimal table as well in the ASCII line to the right of that table.
Modifying a table cell (either HEX or ASCII) will require to press either TAB or ENTER to confirm the change.
Modifying in the ASCII cell will only change those bytes whose ASCII representation has changed, thus preventing accidentially resetting non-ASCII bytes of that line.
Aside from direct editing of individual byte cells, the contents can be modified in several ways through the available command buttons. Many of these are working with a highlighted selection byte range and operate on these. If nothing is highlighted, then the byte at the current cursor position will be affected or, if the cursor is currently in the offset or ASCII column, the entire row.
Several of the commands will prompt for an input and that input text will be interpreted creatively to provide better usability without cluttering the toolbar with too many specialized commands:
In general, numeric values for single bytes can be in either decimal or hex notation, the choice is done by adding a 0x prefix to hex numbers (where the parsing of these is not case sensitive). They must be in the range from 0 to 255, inclusive.
Whitespace will generally be ignored except between (single or double) quotes.
Where a value for an individual byte should be specified, this can also be done by enclosing an arbitrary character between single quotes, such as 'A' for specifying the value 65 resp. 0x41.
Where an entire section of bytes can be entered, it can be done by explicitly giving multiple hex bytes after a single 0x prefix (e.g. 0xbaadf00d) or by writing a quoted string (such as "ASCII here", with the double quotes!).
Where hex input consists of an odd number of hex digits, a leading (!) zero is assumed, thus 0x1234567 will actually be interpreted as 0x01234567.
The command to insert multiple bytes at once also allows to specify a multiplicator in front of a normal explicit way of specifying multiple bytes. This numerical factor should be separated by the * character from the data that should be thus repeated.
The command to highlight (or select) a range of bytes will accept such a range consisting of two numerical values separated by the - character. One of the two numerical values may be missing if the separator is given, thus choosing the corresponding natural limit (e.g. if the first value is missing, zero is chosen and the end of the data if the second one is missing).
By entering the empty string here, the current highlighting will be removed (e.g. everything is deselected).
By entering the special character * alone, everything from beginning to end will be highlighted.
If after considering all this, the input string can still not be interpreted in any known meaningful way, a corresponding error message will be displayed stating the problem (generally some parsing exception) and the value will be re-queried again before the operation can continue.
When issuing a command which prompts for an input to perform its operation, the suggested default input will be based on the current state:
If a highlighted selection is available, that will be used in most cases.
Otherwise the current byte position or its entire row will be used.
The following content related commands are available:
Find: Find bytes starting at the current position and highlight the next match.
Table 1.1. Input examples for the Find command
||Find the next occurrence of a byte with value 0x41 resp. 65.|
||Find and hightlight the next sequence of 0xBA 0xAD 0xF0 0x0D.|
||Find and hightlight the next sequence of 0x41 0x42 0x63 0x64.|
Select: Prompt for a range and select the corresponding bytes.
Table 1.2. Input examples for the Select command
||Select all bytes from beginning to the end.|
||Select everything after the first 10 bytes.|
||Select the first 34 bytes.|
||Select everything between the two given offsets.|
||Select the same range as the above example.|
||A somewhat exotic way to select the bytes between offsets 0x61 and 0x7a.|
Copy: Copy a hex string representation of the selected bytes to the clipboard.
The string that is copied to the clipboard will not have a 0x prefix and will contain no line breaks or other whitespace.
Set: Prompts for a value and sets the selected bytes to it.
Table 1.3. Input examples for the Set command
||Set all selected bytes to the value 0x41 resp. 65.|
Insert: Insert one (zero-) byte at the currently selected position.
The new zero byte is inserted at the position of the currently selected byte, thus shifting that byte (and all following content) to the end by one.
Multi-Insert: Prompt for input and insert resulting bytes at the current position.
Table 1.4. Input examples for the Multi-Insert command
||Insert three bytes with the value 0x41 resp. 65.|
||Repeat the byte sequence 0xBA 0xAD 0xF0 0x0D 10 times, resulting in a total of 40 bytes inserted.|
||Similar to the above but repeating an ASCII text.|
||A bit weird way to insert 65 times the value for character 'F' (0x46).|
Delete: Delete the selection or the byte at the current position.
Depending on the current selection state, the following will happen:
Something selected, cursor anywhere: The currently selected bytes will be deleted and nothing will be selected afterwards.
Nothing selected, cursor on some byte cell position: The byte at the cursors position will be deleted.
Nothing selected, cursor in either an offset or an ASCII cell: The entire row at the cursors position will be deleted.
Nothing selected, cursor beyond valid bytes: Nothing will be deleted.
As this FileHandler supports modification and saving of the loaded data, it is an editor by nature.
In order to provide a true editor experience however, it is necessary to load the entire files contents into memory to avoid having to make changes on the underlying file when editing. For large files this might result in memory issues though.