mirror of
https://github.com/peterdell/wudsn-ide.git
synced 2024-12-21 03:29:32 +00:00
Add IFF support to HexEditor
This commit is contained in:
parent
f2f1e5a598
commit
e40d5bef75
@ -47,6 +47,8 @@ com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.ATARI_MADS_FILE=Atari MAD
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.ATARI_SDX_FILE=Atari SpartaDOS X File
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.ATARI_SAP_FILE=Atari SAP File
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.C64_PRG_FILE=C64 PRG File
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.IFF_FILE=IFF File
|
||||
|
||||
|
||||
com.wudsn.ide.base.editor.hex.HexEditorCharacterSet.ASCII=ASCII
|
||||
com.wudsn.ide.base.editor.hex.HexEditorCharacterSet.ATARI_ATASCII=Atari ATASCII
|
||||
|
@ -47,6 +47,7 @@ com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.ATARI_MADS_FILE=Atari MAD
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.ATARI_SAP_FILE=Atari SAP-Datei
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.ATARI_SDX_FILE=Atari SpartaDOS X-Datei
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.C64_PRG_FILE=C64 PRG-Datei
|
||||
com.wudsn.ide.base.editor.hex.HexEditorFileContentMode.IFF_FILE=IFF-Datei
|
||||
|
||||
com.wudsn.ide.base.editor.hex.HexEditorCharacterSet.ASCII=ASCII
|
||||
com.wudsn.ide.base.editor.hex.HexEditorCharacterSet.ATARI_ATASCII=Atari ATASCII
|
||||
|
@ -73,6 +73,10 @@ public final class Texts extends NLS {
|
||||
public static String HEX_EDITOR_C64_PRG_HEADER_PARAMETERS;
|
||||
public static String HEX_EDITOR_C64_PRG_ERROR;
|
||||
|
||||
public static String HEX_EDITOR_IFF_CHUNK;
|
||||
public static String HEX_EDITOR_IFF_FORM_CHUNK;
|
||||
public static String HEX_EDITOR_IFF_FILE_ERROR;
|
||||
|
||||
public static String HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_LABEL;
|
||||
public static String HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_TEXT;
|
||||
public static String HEX_EDITOR_FILE_CONTENT_MODE_FIELD_LABEL;
|
||||
|
@ -34,6 +34,10 @@ HEX_EDITOR_C64_PRG_HEADER=Program
|
||||
HEX_EDITOR_C64_PRG_HEADER_PARAMETERS={0}-{1} ({2})
|
||||
HEX_EDITOR_C64_PRG_ERROR=PRG file structure error
|
||||
|
||||
HEX_EDITOR_IFF_CHUNK=Chunk {0} contains ${1} ({2}) bytes
|
||||
HEX_EDITOR_IFF_FORM_CHUNK=Chunk {0} of type {1} contains ${2} ({3}) bytes
|
||||
HEX_EDITOR_IFF_FILE_ERROR=IFF file structure error
|
||||
|
||||
HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_LABEL=File Size
|
||||
HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_TEXT=${0} ({1}) bytes
|
||||
HEX_EDITOR_FILE_CONTENT_MODE_FIELD_LABEL=File Mode
|
||||
|
@ -34,6 +34,10 @@ HEX_EDITOR_C64_PRG_HEADER=Programm
|
||||
HEX_EDITOR_C64_PRG_HEADER_PARAMETERS={0}-{1} ({2})
|
||||
HEX_EDITOR_C64_PRG_ERROR=PRG Dateistruktur defekt
|
||||
|
||||
HEX_EDITOR_IFF_CHUNK=Chunk
|
||||
HEX_EDITOR_IFF_FORM_CHUNK=Chunk {0} vom Typ {1} enhl#t ${2} ({3}) Bytes
|
||||
HEX_EDITOR_IFF_FILE_ERROR=IFF Dateistruktur defekt
|
||||
|
||||
HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_LABEL=Dateigröße
|
||||
HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_TEXT=${0} ({1}) Bytes
|
||||
HEX_EDITOR_FILE_CONTENT_MODE_FIELD_LABEL=Datei-Modus
|
||||
|
@ -281,12 +281,12 @@ public final class HexEditor extends EditorPart implements ISelectionProvider, A
|
||||
public <T> T getAdapter(Class<T> adapter) {
|
||||
if (adapter != null && IContentOutlinePage.class.equals(adapter)) {
|
||||
if (contentOutlinePage == null) {
|
||||
|
||||
|
||||
contentOutlinePage = new HexEditorContentOutlinePage(this);
|
||||
contentOutlinePage.setInput(parserComponent.getOutlineBlocks());
|
||||
}
|
||||
|
||||
return (T)contentOutlinePage;
|
||||
return (T) contentOutlinePage;
|
||||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
@ -384,8 +384,8 @@ public final class HexEditor extends EditorPart implements ISelectionProvider, A
|
||||
// Single range selection?
|
||||
if (selection instanceof HexEditorSelection) {
|
||||
HexEditorSelection hexEditorSelection = (HexEditorSelection) selection;
|
||||
int textStartOffset = parserComponent.getByteTextOffset(hexEditorSelection.getStartOffset());
|
||||
int textEndOffset = parserComponent.getByteTextOffset(hexEditorSelection.getEndOffset());
|
||||
long textStartOffset = parserComponent.getByteTextOffset(hexEditorSelection.getStartOffset());
|
||||
long textEndOffset = parserComponent.getByteTextOffset(hexEditorSelection.getEndOffset());
|
||||
setSelectionOffsets(textStartOffset, textEndOffset);
|
||||
// Range of outline tree objects?
|
||||
} else if (selection instanceof IStructuredSelection) {
|
||||
@ -394,8 +394,8 @@ public final class HexEditor extends EditorPart implements ISelectionProvider, A
|
||||
if (structuredSelection.getFirstElement() instanceof HexEditorContentOutlineTreeObject) {
|
||||
Iterator<?> i = ((IStructuredSelection) selection).iterator();
|
||||
|
||||
int textStartOffset = Integer.MAX_VALUE;
|
||||
int textEndOffset = Integer.MIN_VALUE;
|
||||
long textStartOffset = Long.MAX_VALUE;
|
||||
long textEndOffset = Long.MIN_VALUE;
|
||||
while (i.hasNext()) {
|
||||
HexEditorContentOutlineTreeObject treeObject = (HexEditorContentOutlineTreeObject) i.next();
|
||||
textStartOffset = Math.min(treeObject.getTextStartOffset(), textStartOffset);
|
||||
@ -408,15 +408,21 @@ public final class HexEditor extends EditorPart implements ISelectionProvider, A
|
||||
setFocus();
|
||||
}
|
||||
|
||||
private void setSelectionOffsets(int textStartOffset, int textEndOffset) {
|
||||
private void setSelectionOffsets(long textStartOffset, long textEndOffset) {
|
||||
if (textStartOffset < 0 || textEndOffset > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Parameter textStartOffset=" + textStartOffset + " is out of range");
|
||||
}
|
||||
if (textEndOffset < 0 || textEndOffset > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Parameter textStartOffset=" + textStartOffset + " is out of range");
|
||||
}
|
||||
try {
|
||||
// Mark complete selection area. This also scrolls to
|
||||
// the end of the area.
|
||||
textField.setSelection(new Point(textStartOffset, textEndOffset));
|
||||
textField.setSelection(new Point((int) textStartOffset, (int) textEndOffset));
|
||||
//
|
||||
// // But we want to see start of the selection are, so
|
||||
// // position explicitly.
|
||||
textField.setTopIndex(textField.getContent().getLineAtOffset(textStartOffset));
|
||||
textField.setTopIndex(textField.getContent().getLineAtOffset((int) textStartOffset));
|
||||
} catch (IllegalArgumentException x) {
|
||||
// Ignore
|
||||
}
|
||||
@ -570,16 +576,19 @@ public final class HexEditor extends EditorPart implements ISelectionProvider, A
|
||||
|
||||
// If there is no end offset, we insert the new bytes.
|
||||
if (selection.getEndOffset() != HexEditorParserComponent.UNDEFINED_OFFSET) {
|
||||
int selectionLength = selection.getEndOffset() - selection.getStartOffset() + 1;
|
||||
newFileContent = new byte[parserComponent.getFileContent().length - selectionLength + bytes.length];
|
||||
System.arraycopy(parserComponent.getFileContent(), 0, newFileContent, 0, selection.getStartOffset());
|
||||
System.arraycopy(bytes, 0, newFileContent, selection.getStartOffset(), bytes.length);
|
||||
int length = parserComponent.getFileContent().length - selection.getEndOffset() - 1;
|
||||
int selectionStartOffset = (int) selection.getStartOffset();
|
||||
int selectionEndOffset = (int) selection.getEndOffset();
|
||||
|
||||
int selectionLength = selectionEndOffset - selectionStartOffset + 1;
|
||||
int newFileContentLength = parserComponent.getFileContent().length - selectionLength + bytes.length;
|
||||
newFileContent = new byte[newFileContentLength];
|
||||
System.arraycopy(parserComponent.getFileContent(), 0, newFileContent, 0, selectionStartOffset);
|
||||
System.arraycopy(bytes, 0, newFileContent, selectionStartOffset, bytes.length);
|
||||
int length = parserComponent.getFileContent().length - selectionEndOffset - 1;
|
||||
if (length > 0) {
|
||||
// TODO Hex paste is not working yet
|
||||
System.arraycopy(parserComponent.getFileContent(), selection.getEndOffset(),
|
||||
|
||||
newFileContent, selection.getStartOffset() + bytes.length, length);
|
||||
System.arraycopy(parserComponent.getFileContent(), selectionEndOffset, newFileContent,
|
||||
selectionStartOffset + bytes.length, length);
|
||||
}
|
||||
messageManager.sendMessage(0, IStatus.OK,
|
||||
"${0} ({1}) bytes pasted from clipboard to replace ${2} ({3}) bytes ",
|
||||
@ -588,7 +597,7 @@ public final class HexEditor extends EditorPart implements ISelectionProvider, A
|
||||
HexUtility.getLongValueHexString(selectionLength),
|
||||
NumberUtility.getLongValueDecimalString(selectionLength));
|
||||
} else {
|
||||
// If there is and end offset, we replace the selection with the new
|
||||
// If there is an end offset, we replace the selection with the new
|
||||
// bytes.
|
||||
newFileContent = parserComponent.getFileContent();
|
||||
messageManager.sendMessage(0, IStatus.OK, "${0} ({1}) bytes inserted from clipboard",
|
||||
|
@ -29,10 +29,10 @@ import org.eclipse.jface.viewers.StyledString;
|
||||
public final class HexEditorContentOutlineTreeObject {
|
||||
|
||||
private final StyledString styledString;
|
||||
private int fileStartOffset;
|
||||
private int textStartOffset;
|
||||
private int fileEndOffset;
|
||||
private int textEndOffset;
|
||||
private long fileStartOffset;
|
||||
private long textStartOffset;
|
||||
private long fileEndOffset;
|
||||
private long textEndOffset;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -62,7 +62,7 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
*
|
||||
* @return The start offset, a non-negative integer.
|
||||
*/
|
||||
public int getFileStartOffset() {
|
||||
public long getFileStartOffset() {
|
||||
return fileStartOffset;
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
* The start offset, a non-negative integer or <code>-1</code> if
|
||||
* the offset is not defined.
|
||||
*/
|
||||
public void setFileStartOffset(int fileOffset) {
|
||||
public void setFileStartOffset(long fileOffset) {
|
||||
|
||||
this.fileStartOffset = fileOffset;
|
||||
}
|
||||
@ -84,7 +84,7 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
* @return The end offset, a non-negative integer or <code>-1</code> if the
|
||||
* offset is not defined.
|
||||
*/
|
||||
public int getFileEndOffset() {
|
||||
public long getFileEndOffset() {
|
||||
return fileEndOffset;
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
* The end offset, a non-negative integer or <code>-1</code> if
|
||||
* the offset is not defined.
|
||||
*/
|
||||
public void setFileEndOffset(int fileOffset) {
|
||||
public void setFileEndOffset(long fileOffset) {
|
||||
|
||||
this.fileEndOffset = fileOffset;
|
||||
}
|
||||
@ -106,7 +106,7 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
*
|
||||
* @return The offset, a non-negative integer.
|
||||
*/
|
||||
public int getTextStartOffset() {
|
||||
public long getTextStartOffset() {
|
||||
return textStartOffset;
|
||||
}
|
||||
|
||||
@ -116,10 +116,10 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
* @param textOffset
|
||||
* The offset, a non-negative integer.
|
||||
*/
|
||||
public void setTextStartOffset(int textOffset) {
|
||||
public void setTextStartOffset(long textOffset) {
|
||||
if (textOffset < 0) {
|
||||
throw new IllegalArgumentException("Parameter 'textOffset' must not be negative. Specified value is "
|
||||
+ textOffset + ".");
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter 'textOffset' must not be negative. Specified value is " + textOffset + ".");
|
||||
}
|
||||
this.textStartOffset = textOffset;
|
||||
}
|
||||
@ -129,7 +129,7 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
*
|
||||
* @return The offset, a non-negative integer.
|
||||
*/
|
||||
public int getTextEndOffset() {
|
||||
public long getTextEndOffset() {
|
||||
return textEndOffset;
|
||||
}
|
||||
|
||||
@ -141,8 +141,8 @@ public final class HexEditorContentOutlineTreeObject {
|
||||
*/
|
||||
public void setTextEndOffset(int textOffset) {
|
||||
if (textOffset < 0) {
|
||||
throw new IllegalArgumentException("Parameter 'textOffset' must not be negative. Specified value is "
|
||||
+ textOffset + ".");
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter 'textOffset' must not be negative. Specified value is " + textOffset + ".");
|
||||
}
|
||||
this.textEndOffset = textOffset;
|
||||
}
|
||||
|
@ -19,22 +19,45 @@
|
||||
|
||||
package com.wudsn.ide.base.editor.hex;
|
||||
|
||||
import com.wudsn.ide.base.editor.hex.parser.*;
|
||||
|
||||
enum HexEditorFileContentMode {
|
||||
|
||||
BINARY(Hardware.GENERIC), ATARI_COM_FILE(Hardware.ATARI8BIT), ATARI_DISK_IMAGE(Hardware.ATARI8BIT), ATARI_DISK_IMAGE_K_FILE(
|
||||
Hardware.ATARI8BIT), ATARI_MADS_FILE(Hardware.ATARI8BIT), ATARI_SDX_FILE(Hardware.ATARI8BIT), ATARI_SAP_FILE(
|
||||
Hardware.ATARI8BIT), C64_PRG_FILE(Hardware.C64);
|
||||
BINARY(Hardware.GENERIC, BinaryParser.class), ATARI_COM_FILE(Hardware.ATARI8BIT,
|
||||
AtariCOMParser.class), ATARI_DISK_IMAGE(Hardware.ATARI8BIT,
|
||||
AtariDiskImageParser.class), ATARI_DISK_IMAGE_K_FILE(Hardware.ATARI8BIT,
|
||||
AtariDiskImageKFileParser.class), ATARI_MADS_FILE(Hardware.ATARI8BIT,
|
||||
AtariMADSParser.class), ATARI_SDX_FILE(Hardware.ATARI8BIT,
|
||||
AtariSDXParser.class), ATARI_SAP_FILE(Hardware.ATARI8BIT,
|
||||
AtariSAPParser.class), C64_PRG_FILE(Hardware.C64,
|
||||
C64PRGParser.class), IFF_FILE(Hardware.GENERIC,
|
||||
IFFParser.class);
|
||||
|
||||
private Hardware hardware;
|
||||
private Class<? extends HexEditorParser> parserClass;
|
||||
|
||||
private HexEditorFileContentMode(Hardware hardware) {
|
||||
private HexEditorFileContentMode(Hardware hardware, Class<? extends HexEditorParser> parserClass) {
|
||||
if (hardware == null) {
|
||||
throw new IllegalArgumentException("Parameter 'hardware' must not be null.");
|
||||
}
|
||||
if (parserClass == null) {
|
||||
throw new IllegalArgumentException("Parameter 'parserClass' must not be null.");
|
||||
}
|
||||
this.hardware = hardware;
|
||||
this.parserClass = parserClass;
|
||||
}
|
||||
|
||||
public Hardware getHardware() {
|
||||
return hardware;
|
||||
}
|
||||
|
||||
public HexEditorParser createParser() {
|
||||
try {
|
||||
return parserClass.newInstance();
|
||||
} catch (InstantiationException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,27 +83,38 @@ public abstract class HexEditorParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte from the file content.
|
||||
* Gets a byte (8-bit) from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The byte from the file content.
|
||||
*/
|
||||
protected final int getFileContentByte(int offset) {
|
||||
protected final int getFileContentByte(long offset) {
|
||||
return owner.getFileContentByte(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a word from the file content.
|
||||
* Gets a word (16 bit) in little endian format from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The word from the file content.
|
||||
*/
|
||||
protected final int getFileContentWord(int offset) {
|
||||
protected final int getFileContentWord(long offset) {
|
||||
return owner.getFileContentWord(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a double word (32 bit) in big endian format from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The word from the file content.
|
||||
*/
|
||||
protected final long getFileContentDoubleWordBigEndian(long offset) {
|
||||
return owner.getFileContentDoubleWordBigEndian(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a block header in the context area and adds a block to the
|
||||
* outline.
|
||||
@ -128,13 +139,13 @@ public abstract class HexEditorParser {
|
||||
* @return The tree object representing the block.
|
||||
*/
|
||||
protected final HexEditorContentOutlineTreeObject printBlockHeader(StyledString contentBuilder,
|
||||
String blockHeaderText, int blockHeaderNumber, String blockHeaderParameterText, int offset,
|
||||
int startAddress, int endAddress) {
|
||||
String blockHeaderText, int blockHeaderNumber, String blockHeaderParameterText, long offset,
|
||||
long startAddress, long endAddress) {
|
||||
|
||||
if (contentBuilder == null) {
|
||||
throw new IllegalArgumentException("Parameter 'contentBuilder' must not be null.");
|
||||
}
|
||||
int blockLength = endAddress - startAddress + 1;
|
||||
long blockLength = endAddress - startAddress + 1;
|
||||
String blockHeaderNumberText;
|
||||
if (blockHeaderNumber >= 0) {
|
||||
blockHeaderNumberText = NumberUtility.getLongValueDecimalString(blockHeaderNumber);
|
||||
@ -177,8 +188,7 @@ public abstract class HexEditorParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a block header in the context area and adds a block to the
|
||||
* outline.
|
||||
* Adds a block to the outline.
|
||||
*
|
||||
* @param contentBuilder
|
||||
* The content builder, not <code>null</code>.
|
||||
@ -191,7 +201,7 @@ public abstract class HexEditorParser {
|
||||
* @return The tree object representing the block.
|
||||
*/
|
||||
protected final HexEditorContentOutlineTreeObject printBlockHeader(StyledString contentBuilder,
|
||||
StyledString headerStyledString, int offset) {
|
||||
StyledString headerStyledString, long offset) {
|
||||
return owner.printBlockHeader(contentBuilder, headerStyledString, offset);
|
||||
}
|
||||
|
||||
@ -208,17 +218,17 @@ public abstract class HexEditorParser {
|
||||
* @param offset
|
||||
* The offset of the last block, a non-negative integer.
|
||||
*/
|
||||
protected final void printBlockWithError(StyledString contentBuilder, String errorText, int length, int offset) {
|
||||
protected final void printBlockWithError(StyledString contentBuilder, String errorText, long length, long offset) {
|
||||
owner.printBlockWithError(contentBuilder, errorText, length, offset);
|
||||
}
|
||||
|
||||
protected final void skipByteTextIndex(int offset) {
|
||||
protected final void skipByteTextIndex(long offset) {
|
||||
owner.skipByteTextIndex(offset);
|
||||
|
||||
}
|
||||
|
||||
protected final int printBytes(HexEditorContentOutlineTreeObject treeObject, StyledString contentBuilder,
|
||||
int offset, int maxOffset, boolean withStartAddress, int startAddress) {
|
||||
protected final long printBytes(HexEditorContentOutlineTreeObject treeObject, StyledString contentBuilder,
|
||||
long offset, long maxOffset, boolean withStartAddress, int startAddress) {
|
||||
return owner.printBytes(treeObject, contentBuilder, offset, maxOffset, withStartAddress, startAddress);
|
||||
|
||||
}
|
||||
|
@ -35,20 +35,15 @@ import com.wudsn.ide.base.common.NumberUtility;
|
||||
import com.wudsn.ide.base.common.Profiler;
|
||||
import com.wudsn.ide.base.common.TextUtility;
|
||||
import com.wudsn.ide.base.editor.hex.HexEditor.MessageIds;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariCOMParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariDiskImageKFileParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariDiskImageParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariMADSParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariSAPParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.AtariSDXParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.BinaryParser;
|
||||
import com.wudsn.ide.base.editor.hex.parser.C64PRGParser;
|
||||
import com.wudsn.ide.base.gui.MessageManager;
|
||||
|
||||
final class HexEditorParserComponent {
|
||||
|
||||
public static final int UNDEFINED_OFFSET = -1;
|
||||
public static final long UNDEFINED_OFFSET = -1;
|
||||
private final static int BYTES_PER_ROW = 16;
|
||||
private static final int INT_FF = 0xff;
|
||||
|
||||
@ -77,7 +72,7 @@ final class HexEditorParserComponent {
|
||||
// Parsing state.
|
||||
private List<HexEditorFileContentMode> possibleFileContentModes;
|
||||
private List<HexEditorContentOutlineTreeObject> outlineBlocks;
|
||||
private int[] byteTextOffsets;
|
||||
private long[] byteTextOffsets;
|
||||
private int byteTextIndex;
|
||||
|
||||
// Line buffers for binary to hex and char conversion.
|
||||
@ -148,7 +143,7 @@ final class HexEditorParserComponent {
|
||||
private void initByteTextOffsets() {
|
||||
// Twice the space, because some format display the content twice, for
|
||||
// example ATARI_DISK_IMAGE_K_FILE.
|
||||
byteTextOffsets = new int[fileContent.length * 2];
|
||||
byteTextOffsets = new long[fileContent.length * 2];
|
||||
byteTextIndex = 0;
|
||||
}
|
||||
|
||||
@ -266,6 +261,21 @@ final class HexEditorParserComponent {
|
||||
result = HexEditorFileContentMode.C64_PRG_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
// IFF files always have an even number of bytes
|
||||
if (fileContent.length > 8 && (fileContent.length & 0x1) == 0) {
|
||||
possibleFileContentModes.add(HexEditorFileContentMode.IFF_FILE);
|
||||
char[] id = new char[4];
|
||||
id[0] = (char) fileContent[0];
|
||||
id[1] = (char) fileContent[1];
|
||||
id[2] = (char) fileContent[2];
|
||||
id[3] = (char) fileContent[3];
|
||||
String chunk = String.copyValueOf(id);
|
||||
boolean iff = chunk.equals("FORM") || chunk.equals("LIST") || chunk.equals("CAT ");
|
||||
if (result.equals(HexEditorFileContentMode.BINARY) && iff) {
|
||||
result = HexEditorFileContentMode.IFF_FILE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -322,8 +332,8 @@ final class HexEditorParserComponent {
|
||||
*/
|
||||
public void setBytesPerRow(int bytesPerRow) {
|
||||
if (bytesPerRow < 1) {
|
||||
throw new IllegalArgumentException("Parameter 'bytesPerRow' must not be positive. Specified valie was "
|
||||
+ bytesPerRow + ".");
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter 'bytesPerRow' must not be positive. Specified valie was " + bytesPerRow + ".");
|
||||
}
|
||||
this.bytesPerRow = bytesPerRow;
|
||||
}
|
||||
@ -386,24 +396,7 @@ final class HexEditorParserComponent {
|
||||
|
||||
if (fileContent.length > 0) {
|
||||
boolean error;
|
||||
HexEditorParser parser;
|
||||
if (fileContentMode.equals(HexEditorFileContentMode.ATARI_COM_FILE)) {
|
||||
parser = new AtariCOMParser();
|
||||
} else if (fileContentMode.equals(HexEditorFileContentMode.ATARI_DISK_IMAGE)) {
|
||||
parser = new AtariDiskImageParser();
|
||||
} else if (fileContentMode.equals(HexEditorFileContentMode.ATARI_DISK_IMAGE_K_FILE)) {
|
||||
parser = new AtariDiskImageKFileParser();
|
||||
} else if (fileContentMode.equals(HexEditorFileContentMode.ATARI_MADS_FILE)) {
|
||||
parser = new AtariMADSParser();
|
||||
} else if (fileContentMode.equals(HexEditorFileContentMode.ATARI_SDX_FILE)) {
|
||||
parser = new AtariSDXParser();
|
||||
} else if (fileContentMode.equals(HexEditorFileContentMode.ATARI_SAP_FILE)) {
|
||||
parser = new AtariSAPParser();
|
||||
} else if (fileContentMode.equals(HexEditorFileContentMode.C64_PRG_FILE)) {
|
||||
parser = new C64PRGParser();
|
||||
} else {
|
||||
parser = new BinaryParser();
|
||||
}
|
||||
HexEditorParser parser = fileContentMode.createParser();
|
||||
|
||||
// Initialize the buffers for the hex and char conversion.
|
||||
hexBuffer = new char[3 + bytesPerRow * 3 + 2];
|
||||
@ -437,25 +430,54 @@ final class HexEditorParserComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte from the file content.
|
||||
* Gets a byte (8 bit) from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The byte from the file content.
|
||||
*/
|
||||
final int getFileContentByte(int offset) {
|
||||
return fileContent[offset] & INT_FF;
|
||||
final int getFileContentByte(long offset) {
|
||||
if (offset < 0) {
|
||||
throw new IllegalArgumentException("Parameter offset=" + offset + " must not be negative");
|
||||
}
|
||||
if (offset >= fileContent.length) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter offset=" + offset + " must be less than the file content size " + fileContent.length);
|
||||
}
|
||||
return fileContent[(int) offset] & INT_FF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a word from the file content.
|
||||
* Gets a word (16 bit) in little endian format from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The word from the file content.
|
||||
*/
|
||||
final int getFileContentWord(int offset) {
|
||||
return getFileContentByte(offset) + 256 * getFileContentByte(offset + 1);
|
||||
final int getFileContentWord(long offset) {
|
||||
return getFileContentByte(offset) + 0x100 * getFileContentByte(offset + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a word (16 bit) in big endian format from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The word from the file content.
|
||||
*/
|
||||
final int getFileContentWordBigEndian(long offset) {
|
||||
return getFileContentByte(offset + 1) + 0x100 * getFileContentByte(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a double word (32 bit) in big endian format from the file content.
|
||||
*
|
||||
* @param offset
|
||||
* The offset, a non-negative integer.
|
||||
* @return The word from the file content.
|
||||
*/
|
||||
final long getFileContentDoubleWordBigEndian(long offset) {
|
||||
return getFileContentWordBigEndian(offset + 2) + 0x10000 * getFileContentWordBigEndian(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -473,7 +495,7 @@ final class HexEditorParserComponent {
|
||||
* @return The tree object representing the block.
|
||||
*/
|
||||
final HexEditorContentOutlineTreeObject printBlockHeader(StyledString contentBuilder,
|
||||
StyledString headerStyledString, int offset) {
|
||||
StyledString headerStyledString, long offset) {
|
||||
|
||||
if (contentBuilder == null) {
|
||||
throw new IllegalArgumentException("Parameter 'contentBuilder' must not be null.");
|
||||
@ -503,7 +525,7 @@ final class HexEditorParserComponent {
|
||||
* @param offset
|
||||
* The offset of the last block, a non-negative integer.
|
||||
*/
|
||||
final void printBlockWithError(StyledString contentBuilder, String errorText, int length, int offset) {
|
||||
final void printBlockWithError(StyledString contentBuilder, String errorText, long length, long offset) {
|
||||
if (contentBuilder == null) {
|
||||
throw new IllegalArgumentException("Parameter 'contentBuilder' must not be null.");
|
||||
}
|
||||
@ -525,22 +547,22 @@ final class HexEditorParserComponent {
|
||||
offset = printBytes(treeObject, contentBuilder, offset, length - 1, true, 0);
|
||||
}
|
||||
|
||||
final void skipByteTextIndex(int offset) {
|
||||
final void skipByteTextIndex(long offset) {
|
||||
byteTextIndex += offset;
|
||||
}
|
||||
|
||||
final int printBytes(HexEditorContentOutlineTreeObject treeObject, StyledString contentBuilder, int offset,
|
||||
int maxOffset, boolean withStartAddress, int startAddress) {
|
||||
final long printBytes(HexEditorContentOutlineTreeObject treeObject, StyledString contentBuilder, long offset,
|
||||
long maxOffset, boolean withStartAddress, int startAddress) {
|
||||
|
||||
if (offset < 0) {
|
||||
throw new IllegalArgumentException("Parameter 'offset' must not be negative, specified value is " + offset
|
||||
+ ".");
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter 'offset' must not be negative, specified value is " + offset + ".");
|
||||
}
|
||||
if (maxOffset < 0) {
|
||||
throw new IllegalArgumentException("Parameter 'offset' must not be negative, specified value is "
|
||||
+ maxOffset + ".");
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter 'offset' must not be negative, specified value is " + maxOffset + ".");
|
||||
}
|
||||
int length = Math.max(4, HexUtility.getLongValueHexLength(maxOffset));
|
||||
int length = Math.max(4, HexUtility.getLongValueHexLength(fileContent.length));
|
||||
char[] characterMapping = characterSet.getCharacterMapping();
|
||||
while (offset <= maxOffset) {
|
||||
int contentBuilderLineStartOffset = contentBuilder.length();
|
||||
@ -609,11 +631,11 @@ final class HexEditorParserComponent {
|
||||
*/
|
||||
public HexEditorSelection getSelection(int x, int y) {
|
||||
|
||||
int startOffset = UNDEFINED_OFFSET;
|
||||
int endOffset = UNDEFINED_OFFSET;
|
||||
int textOffset = 0;
|
||||
long startOffset = UNDEFINED_OFFSET;
|
||||
long endOffset = UNDEFINED_OFFSET;
|
||||
long textOffset = 0;
|
||||
for (int i = 0; i < byteTextIndex && (startOffset == UNDEFINED_OFFSET || endOffset == UNDEFINED_OFFSET); i++) {
|
||||
int nextTextOffset;
|
||||
long nextTextOffset;
|
||||
if (i < byteTextIndex - 1) {
|
||||
nextTextOffset = byteTextOffsets[i + 1];
|
||||
} else {
|
||||
@ -633,23 +655,26 @@ final class HexEditorParserComponent {
|
||||
if (startOffset == UNDEFINED_OFFSET) {
|
||||
return null;
|
||||
}
|
||||
int length;
|
||||
long length;
|
||||
byte[] bytes;
|
||||
|
||||
length = endOffset - startOffset + 1;
|
||||
// BasePlugin.getInstance().log("HexEditor.getSelection(): startOffset={0} endoffset={1} length={2}",
|
||||
// BasePlugin.getInstance().log("HexEditor.getSelection():
|
||||
// startOffset={0} endoffset={1} length={2}",
|
||||
// new Object[] { String.valueOf(startOffset),
|
||||
// String.valueOf(endOffset), String.valueOf(length) });
|
||||
|
||||
// Length not empty and selection does not cross file end boundary.
|
||||
if (length > 0 && endOffset < fileContent.length) {
|
||||
if (length > 0 && length < Integer.MAX_VALUE && startOffset < fileContent.length
|
||||
&& endOffset < fileContent.length) {
|
||||
// Reposition into first occurrence of in the file.
|
||||
// This is relevant for the format that display the content more
|
||||
// than once.
|
||||
bytes = new byte[length];
|
||||
bytes = new byte[(int) length];
|
||||
// startOffset = startOffset % fileContent.length;
|
||||
// endOffset = endOffset % fileContent.length;
|
||||
// length = endOffset - startOffset + 1;
|
||||
System.arraycopy(fileContent, startOffset, bytes, 0, length);
|
||||
System.arraycopy(fileContent, (int) startOffset, bytes, 0, bytes.length);
|
||||
|
||||
// BasePlugin.getInstance().log(
|
||||
// "HexEditor startOffset={0} endoffset={1} length={2}",
|
||||
@ -672,9 +697,9 @@ final class HexEditorParserComponent {
|
||||
* @return The text offset where the byte is represented or <code>-1</code>
|
||||
* if there is no such text offset.
|
||||
*/
|
||||
public int getByteTextOffset(int byteOffset) {
|
||||
public long getByteTextOffset(long byteOffset) {
|
||||
if (byteOffset < byteTextOffsets.length) {
|
||||
return byteTextOffsets[byteOffset];
|
||||
return byteTextOffsets[(int) byteOffset];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ import org.eclipse.jface.viewers.ISelection;
|
||||
*/
|
||||
final class HexEditorSelection implements ISelection {
|
||||
|
||||
private int startOffset;
|
||||
private int endOffset;
|
||||
private long startOffset;
|
||||
private long endOffset;
|
||||
private byte[] bytes;
|
||||
|
||||
/**
|
||||
@ -45,7 +45,7 @@ final class HexEditorSelection implements ISelection {
|
||||
* The content of the selection, may be empty, not
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public HexEditorSelection(int startOffset, int endOffset, byte[] bytes) {
|
||||
public HexEditorSelection(long startOffset, long endOffset, byte[] bytes) {
|
||||
|
||||
if (startOffset < 0) {
|
||||
throw new IllegalArgumentException("Parameter 'startOffset' must not be negative, specified value is "
|
||||
@ -74,7 +74,7 @@ final class HexEditorSelection implements ISelection {
|
||||
* @return The start offset in the original array, a non-negative number.
|
||||
*
|
||||
*/
|
||||
public int getStartOffset() {
|
||||
public long getStartOffset() {
|
||||
return startOffset;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ final class HexEditorSelection implements ISelection {
|
||||
* @return The end offset in the original array, a non-negative number
|
||||
* greater or equal to the start offset.
|
||||
*/
|
||||
public int getEndOffset() {
|
||||
public long getEndOffset() {
|
||||
return endOffset;
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,8 @@ public final class HexEditorSelectionTransfer extends ByteArrayTransfer {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
DataOutputStream writeOut = new DataOutputStream(out);
|
||||
byte[] bytes = hexEditorSelection.getBytes();
|
||||
writeOut.writeInt(hexEditorSelection.getStartOffset());
|
||||
writeOut.writeInt(hexEditorSelection.getEndOffset());
|
||||
writeOut.writeLong(hexEditorSelection.getStartOffset());
|
||||
writeOut.writeLong(hexEditorSelection.getEndOffset());
|
||||
writeOut.writeInt(bytes.length);
|
||||
writeOut.write(bytes);
|
||||
|
||||
@ -66,8 +66,8 @@ public final class HexEditorSelectionTransfer extends ByteArrayTransfer {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(buffer);
|
||||
DataInputStream readIn = new DataInputStream(in);
|
||||
while (readIn.available() > 0) {
|
||||
int startOffset = readIn.readInt();
|
||||
int endOffset = readIn.readInt();
|
||||
long startOffset = readIn.readLong();
|
||||
long endOffset = readIn.readLong();
|
||||
int size = readIn.readInt();
|
||||
byte[] bytes = new byte[size];
|
||||
readIn.read(bytes);
|
||||
|
@ -35,7 +35,7 @@ public class AtariDiskImageParser extends AtariParser {
|
||||
|
||||
boolean error = false;
|
||||
int length = getFileContentLength();
|
||||
int offset = 0;
|
||||
long offset = 0;
|
||||
|
||||
HexEditorContentOutlineTreeObject treeObject;
|
||||
treeObject = printBlockHeader(contentBuilder, Texts.HEX_EDITOR_ATARI_DISK_IMAGE_HEADER, -1, "", offset, offset,
|
||||
@ -63,7 +63,8 @@ public class AtariDiskImageParser extends AtariParser {
|
||||
while (blockMode && !error) {
|
||||
treeObject = printBlockHeader(contentBuilder, Texts.HEX_EDITOR_ATARI_SECTOR_HEADER, sectorCount,
|
||||
|
||||
Texts.HEX_EDITOR_ATARI_SECTOR_HEADER_PARAMETERS, offset, startAddress, startAddress + sectorSize - 1);
|
||||
Texts.HEX_EDITOR_ATARI_SECTOR_HEADER_PARAMETERS, offset, startAddress,
|
||||
startAddress + sectorSize - 1);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + sectorSize - 1, true, startAddress);
|
||||
contentBuilder.append("\n");
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
}
|
||||
|
||||
boolean error;
|
||||
int offset = 0;
|
||||
long offset = 0;
|
||||
|
||||
// Skip offset bytes in lookup array.
|
||||
skipByteTextIndex(offset);
|
||||
@ -82,7 +82,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
treeObject = printHeader(contentBuilder, offset, headerText);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + 15, true, 0);
|
||||
|
||||
int blockEnd = offset + endAddress - startAddress;
|
||||
long blockEnd = offset + endAddress - startAddress;
|
||||
|
||||
offset = printBytes(treeObject, contentBuilder, offset, blockEnd, true, startAddress);
|
||||
|
||||
@ -100,7 +100,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
// stored for each address (low byte of address being
|
||||
// modified).
|
||||
int dataSize = (type == '>' ? 3 : 2);
|
||||
int blockEnd = offset + (dataLength * dataSize) - 1;
|
||||
long blockEnd = offset + (dataLength * dataSize) - 1;
|
||||
|
||||
offset = printBytes(treeObject, contentBuilder, offset, blockEnd, false, 0);
|
||||
|
||||
@ -141,7 +141,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
int labelLength = getFileContentWord(offset + 2);
|
||||
String labelName = getLabelName(offset + 4, labelLength);
|
||||
int address = getFileContentWord(offset + 4 + labelLength);
|
||||
int headerEnd = offset + 6 + labelLength - 1;
|
||||
long headerEnd = offset + 6 + labelLength - 1;
|
||||
switch (labelType) {
|
||||
case 'P':
|
||||
int procType = getFileContentByte(headerEnd + 1);
|
||||
@ -194,7 +194,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
return error;
|
||||
}
|
||||
|
||||
private HexEditorContentOutlineTreeObject printHeader(StyledString contentBuilder, int offset, String headerText) {
|
||||
private HexEditorContentOutlineTreeObject printHeader(StyledString contentBuilder, long offset, String headerText) {
|
||||
HexEditorContentOutlineTreeObject treeObject;
|
||||
StyledString headerStyledString = new StyledString(headerText, offsetStyler);
|
||||
contentBuilder.append(headerStyledString).append("\n");
|
||||
@ -202,7 +202,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
return treeObject;
|
||||
}
|
||||
|
||||
private HexEditorContentOutlineTreeObject printTypedHeader(StyledString contentBuilder, int offset, String text,
|
||||
private HexEditorContentOutlineTreeObject printTypedHeader(StyledString contentBuilder, long offset, String text,
|
||||
int type, int dataLength) {
|
||||
HexEditorContentOutlineTreeObject treeObject;
|
||||
String headerText = TextUtility.format(text, String.valueOf((char) type),
|
||||
@ -211,7 +211,7 @@ public class AtariMADSParser extends HexEditorParser {
|
||||
return treeObject;
|
||||
}
|
||||
|
||||
private String getLabelName(int offset, int length) {
|
||||
private String getLabelName(long offset, int length) {
|
||||
StringBuffer buffer = new StringBuffer(8);
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer.append((char) getFileContentByte(offset + i));
|
||||
|
@ -29,7 +29,7 @@ public abstract class AtariParser extends HexEditorParser {
|
||||
|
||||
public final static int COM_HEADER = 0xffff;
|
||||
|
||||
protected final boolean parseAtariCOMFile(StyledString contentBuilder, int offset, int fileContentLength) {
|
||||
protected final boolean parseAtariCOMFile(StyledString contentBuilder, long offset, int fileContentLength) {
|
||||
if (contentBuilder == null) {
|
||||
throw new IllegalArgumentException("Parameter 'contentBuilder' must not be null.");
|
||||
}
|
||||
@ -38,7 +38,7 @@ public abstract class AtariParser extends HexEditorParser {
|
||||
int endAddress;
|
||||
|
||||
int blockCount;
|
||||
int blockEnd;
|
||||
long blockEnd;
|
||||
|
||||
// Skip offset bytes in lookup array.
|
||||
skipByteTextIndex(offset);
|
||||
|
@ -31,7 +31,7 @@ public final class AtariSAPParser extends AtariParser {
|
||||
if (contentBuilder == null) {
|
||||
throw new IllegalArgumentException("Parameter 'contentBuilder' must not be null.");
|
||||
}
|
||||
int offset = 0;
|
||||
long offset = 0;
|
||||
int fileContentLenght = getFileContentLength();
|
||||
int maxOffset = fileContentLenght - 2;
|
||||
while (offset < maxOffset && getFileContentByte(offset) != 0xff && getFileContentByte(offset) != 0xff) {
|
||||
|
@ -43,7 +43,7 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
}
|
||||
|
||||
boolean error;
|
||||
int offset = 0;
|
||||
long offset = 0;
|
||||
|
||||
// Skip offset bytes in lookup array.
|
||||
skipByteTextIndex(offset);
|
||||
@ -74,7 +74,7 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
endAddress);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + 5, true, 0);
|
||||
|
||||
int blockEnd = offset + endAddress - startAddress;
|
||||
long blockEnd = offset + endAddress - startAddress;
|
||||
|
||||
offset = printBytes(treeObject, contentBuilder, offset, blockEnd, true, startAddress);
|
||||
|
||||
@ -94,7 +94,7 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
treeObject = printBlockHeader(contentBuilder, headerStyledString, offset);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + 7, true, 0);
|
||||
|
||||
int blockEnd = offset + blockLength - 1;
|
||||
long blockEnd = offset + blockLength - 1;
|
||||
|
||||
// Print bytes only of the block is not marked as EMPTY
|
||||
if ((blockId & 0x80) != 0x80) {
|
||||
@ -111,7 +111,7 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
contentBuilder.append(headerStyledString).append("\n");
|
||||
treeObject = printBlockHeader(contentBuilder, headerStyledString, offset);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + 4, true, 0);
|
||||
int blockEnd = getBlockEnd(offset);
|
||||
long blockEnd = getBlockEnd(offset);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, blockEnd, true, 0);
|
||||
} else if (header == UPDATE_SYMBOLS_HEADER) {
|
||||
String symbolName = getSymbolName(offset + 2);
|
||||
@ -123,7 +123,7 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
contentBuilder.append(headerStyledString).append("\n");
|
||||
treeObject = printBlockHeader(contentBuilder, headerStyledString, offset);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + 11, true, 0);
|
||||
int blockEnd = getBlockEnd(offset);
|
||||
long blockEnd = getBlockEnd(offset);
|
||||
offset = printBytes(treeObject, contentBuilder, offset, blockEnd, true, 0);
|
||||
} else if (header == DEFINE_SYMBOLS_HEADER) {
|
||||
int blockNumber = getFileContentByte(offset + 2);
|
||||
@ -160,10 +160,10 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
* The start offset, a non-negative integer.
|
||||
* @return The end offset, a non-negative integer.
|
||||
*/
|
||||
private int getBlockEnd(int offset) {
|
||||
private long getBlockEnd(long offset) {
|
||||
int fileContentLength = getFileContentLength();
|
||||
int i = offset;
|
||||
int blockEnd = -1;
|
||||
long i = offset;
|
||||
long blockEnd = -1;
|
||||
while (blockEnd < 0 && i < fileContentLength) {
|
||||
int location = getFileContentByte(i);
|
||||
switch (location) {
|
||||
@ -184,7 +184,7 @@ public class AtariSDXParser extends HexEditorParser {
|
||||
return blockEnd;
|
||||
}
|
||||
|
||||
private String getSymbolName(int offset) {
|
||||
private String getSymbolName(long offset) {
|
||||
StringBuffer buffer = new StringBuffer(8);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
buffer.append((char) getFileContentByte(offset + i));
|
||||
|
@ -37,7 +37,7 @@ public class C64PRGParser extends HexEditorParser {
|
||||
int endAddress;
|
||||
|
||||
int length = getFileContentLength();
|
||||
int offset = 0;
|
||||
long offset = 0;
|
||||
|
||||
error = (length < 2);
|
||||
if (!error) {
|
||||
|
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Copyright (C) 2009 - 2019 <a href="https://www.wudsn.com" target="_top">Peter Dell</a>
|
||||
*
|
||||
* This file is part of WUDSN IDE.
|
||||
*
|
||||
* WUDSN IDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WUDSN IDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.wudsn.ide.base.editor.hex.parser;
|
||||
|
||||
import org.eclipse.jface.viewers.StyledString;
|
||||
|
||||
import com.wudsn.ide.base.Texts;
|
||||
import com.wudsn.ide.base.common.HexUtility;
|
||||
import com.wudsn.ide.base.common.NumberUtility;
|
||||
import com.wudsn.ide.base.common.TextUtility;
|
||||
import com.wudsn.ide.base.editor.hex.HexEditorContentOutlineTreeObject;
|
||||
import com.wudsn.ide.base.editor.hex.HexEditorParser;
|
||||
|
||||
public final class IFFParser extends HexEditorParser {
|
||||
|
||||
@Override
|
||||
public final boolean parse(StyledString contentBuilder) {
|
||||
if (contentBuilder == null) {
|
||||
throw new IllegalArgumentException("Parameter 'contentBuilder' must not be null.");
|
||||
}
|
||||
boolean error;
|
||||
long offset = 0;
|
||||
long fileContentLength = getFileContentLength();
|
||||
error = parse(contentBuilder, offset, fileContentLength, null);
|
||||
return error;
|
||||
}
|
||||
|
||||
private boolean parse(StyledString contentBuilder, long offset, long fileContentLength,
|
||||
HexEditorContentOutlineTreeObject treeObject) {
|
||||
boolean error;
|
||||
|
||||
error = (fileContentLength - offset) < 8;
|
||||
if (!error) {
|
||||
while ((fileContentLength - offset) >= 8 && !error) {
|
||||
long headerLength = 8;
|
||||
String chunkName = getChunkName(offset);
|
||||
long chunkLength = getFileContentDoubleWordBigEndian(offset + 4);
|
||||
String headerText;
|
||||
String formTypeName = "";
|
||||
boolean hasInnerChunks = false;
|
||||
if (chunkName.equals("FORM")) {
|
||||
if (chunkLength >= 4) {
|
||||
formTypeName = getChunkName(offset + 8);
|
||||
headerText = TextUtility.format(Texts.HEX_EDITOR_IFF_FORM_CHUNK, chunkName, formTypeName,
|
||||
HexUtility.getLongValueHexString(chunkLength),
|
||||
NumberUtility.getLongValueDecimalString(chunkLength));
|
||||
headerLength += 4;
|
||||
chunkLength -= 4;
|
||||
// Ignore trailing parts in the file outside of the main chunk
|
||||
fileContentLength = offset + chunkLength;
|
||||
hasInnerChunks = true;
|
||||
} else {
|
||||
error = true;
|
||||
headerText = null;
|
||||
}
|
||||
} else {
|
||||
headerText = TextUtility.format(Texts.HEX_EDITOR_IFF_CHUNK, chunkName,
|
||||
HexUtility.getLongValueHexString(chunkLength),
|
||||
NumberUtility.getLongValueDecimalString(chunkLength));
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
StyledString styledString = new StyledString(headerText, offsetStyler);
|
||||
treeObject = printBlockHeader(contentBuilder, styledString, offset);
|
||||
contentBuilder.append(styledString);
|
||||
contentBuilder.append("\n");
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + headerLength - 1, false, 0);
|
||||
|
||||
if (hasInnerChunks) {
|
||||
contentBuilder.append("\n");
|
||||
|
||||
parse(contentBuilder, offset, fileContentLength, treeObject);
|
||||
offset += chunkLength;
|
||||
} else {
|
||||
offset = printBytes(treeObject, contentBuilder, offset, offset + chunkLength - 1, false, 0);
|
||||
}
|
||||
contentBuilder.append("\n");
|
||||
|
||||
// Skip padding byte
|
||||
if ((offset & 0x1) == 1) {
|
||||
offset++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (error) {
|
||||
printBlockWithError(contentBuilder, Texts.HEX_EDITOR_IFF_FILE_ERROR, fileContentLength, offset);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
private String getChunkName(long offset) {
|
||||
char[] id = new char[4];
|
||||
id[0] = (char) getFileContentByte(offset);
|
||||
id[1] = (char) getFileContentByte(offset + 1);
|
||||
id[2] = (char) getFileContentByte(offset + 2);
|
||||
id[3] = (char) getFileContentByte(offset + 3);
|
||||
return String.copyValueOf(id);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user