mirror of
https://github.com/peterdell/wudsn-ide.git
synced 2025-01-28 10:31:35 +00:00
Improve IFF file detection and parsing
This commit is contained in:
parent
1c9e603ba5
commit
a2026b1fa5
@ -41,6 +41,7 @@ import com.wudsn.ide.hex.parser.AtariDiskImageKFileParser;
|
|||||||
import com.wudsn.ide.hex.parser.AtariMADSParser;
|
import com.wudsn.ide.hex.parser.AtariMADSParser;
|
||||||
import com.wudsn.ide.hex.parser.AtariParser;
|
import com.wudsn.ide.hex.parser.AtariParser;
|
||||||
import com.wudsn.ide.hex.parser.AtariSDXParser;
|
import com.wudsn.ide.hex.parser.AtariSDXParser;
|
||||||
|
import com.wudsn.ide.hex.parser.IFFParser;
|
||||||
|
|
||||||
final class HexEditorParserComponent {
|
final class HexEditorParserComponent {
|
||||||
|
|
||||||
@ -256,16 +257,22 @@ final class HexEditorParserComponent {
|
|||||||
|
|
||||||
// IFF files always have an even number of bytes
|
// IFF files always have an even number of bytes
|
||||||
if (fileContent.getLength() > 8 && (fileContent.getLength() & 0x1) == 0) {
|
if (fileContent.getLength() > 8 && (fileContent.getLength() & 0x1) == 0) {
|
||||||
possibleFileContentModes.add(HexEditorFileContentMode.IFF_FILE);
|
|
||||||
char[] id = new char[4];
|
char[] id = new char[4];
|
||||||
|
int offset = 0;
|
||||||
id[0] = (char) fileContent.getByte(0);
|
id[0] = (char) fileContent.getByte(0);
|
||||||
id[1] = (char) fileContent.getByte(1);
|
id[1] = (char) fileContent.getByte(1);
|
||||||
id[2] = (char) fileContent.getByte(2);
|
id[2] = (char) fileContent.getByte(2);
|
||||||
id[3] = (char) fileContent.getByte(3);
|
id[3] = (char) fileContent.getByte(3);
|
||||||
String chunk = String.copyValueOf(id);
|
String chunkName = String.copyValueOf(id);
|
||||||
boolean iff = chunk.equals("FORM") || chunk.equals("LIST") || chunk.equals("CAT ");
|
offset += 4;
|
||||||
if (result.equals(HexEditorFileContentMode.BINARY) && iff) {
|
var chunkLength = fileContent.getDoubleWordBigEndian(4);
|
||||||
result = HexEditorFileContentMode.IFF_FILE;
|
offset += 4;
|
||||||
|
if (IFFParser.isValidChunkName(chunkName) && offset + chunkLength <= fileContent.getLength()) {
|
||||||
|
possibleFileContentModes.add(HexEditorFileContentMode.IFF_FILE);
|
||||||
|
boolean iff = chunkName.equals("FORM") || chunkName.equals("LIST") || chunkName.equals("CAT ");
|
||||||
|
if (result.equals(HexEditorFileContentMode.BINARY) && iff) {
|
||||||
|
result = HexEditorFileContentMode.IFF_FILE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -30,6 +30,22 @@ import com.wudsn.ide.hex.Texts;
|
|||||||
|
|
||||||
public final class IFFParser extends HexEditorParser {
|
public final class IFFParser extends HexEditorParser {
|
||||||
|
|
||||||
|
public static boolean isValidChunkName(String chunkName) {
|
||||||
|
if (chunkName == null) {
|
||||||
|
throw new IllegalArgumentException("Parameter 'chunkName' must not be null.");
|
||||||
|
}
|
||||||
|
if (chunkName.length() != 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < chunkName.length(); i++) {
|
||||||
|
char c = chunkName.charAt(i);
|
||||||
|
if (c < 'A' || c > 'Z') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean parse(StyledString contentBuilder) {
|
public final boolean parse(StyledString contentBuilder) {
|
||||||
if (contentBuilder == null) {
|
if (contentBuilder == null) {
|
||||||
@ -45,19 +61,23 @@ public final class IFFParser extends HexEditorParser {
|
|||||||
private boolean parse(StyledString contentBuilder, long offset, long fileContentLength,
|
private boolean parse(StyledString contentBuilder, long offset, long fileContentLength,
|
||||||
HexEditorContentOutlineTreeObject treeObject) {
|
HexEditorContentOutlineTreeObject treeObject) {
|
||||||
boolean error;
|
boolean error;
|
||||||
|
String chunkName = null;
|
||||||
error = (fileContentLength - offset) < 8;
|
error = (fileContentLength - offset) < 8;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
while ((fileContentLength - offset) >= 8 && !error) {
|
while ((fileContentLength - offset) >= 8 && !error) {
|
||||||
long headerLength = 8;
|
long headerLength = 8;
|
||||||
String chunkName = getChunkName(offset);
|
chunkName = getChunkName(offset);
|
||||||
long chunkLength = fileContent.getDoubleWordBigEndian(offset + 4);
|
if (!isValidChunkName(chunkName)) {
|
||||||
|
error = true; // Non ASCII chunk name
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var chunkLength = fileContent.getDoubleWordBigEndian(offset + 4);
|
||||||
String headerText;
|
String headerText;
|
||||||
String formTypeName = "";
|
String formTypeName = "";
|
||||||
boolean hasInnerChunks = false;
|
boolean hasInnerChunks = false;
|
||||||
if (chunkName.equals("FORM")) {
|
if (chunkName.equals("FORM")) {
|
||||||
if (chunkLength >= 4) {
|
if (chunkLength >= 4) {
|
||||||
formTypeName = getChunkName(offset + 8);
|
formTypeName = getChunkName(offset);
|
||||||
headerText = TextUtility.format(Texts.HEX_EDITOR_IFF_FORM_CHUNK, chunkName, formTypeName,
|
headerText = TextUtility.format(Texts.HEX_EDITOR_IFF_FORM_CHUNK, chunkName, formTypeName,
|
||||||
HexUtility.getLongValueHexString(chunkLength),
|
HexUtility.getLongValueHexString(chunkLength),
|
||||||
NumberUtility.getLongValueDecimalString(chunkLength));
|
NumberUtility.getLongValueDecimalString(chunkLength));
|
||||||
@ -75,6 +95,7 @@ public final class IFFParser extends HexEditorParser {
|
|||||||
headerText = TextUtility.format(Texts.HEX_EDITOR_IFF_CHUNK, chunkName,
|
headerText = TextUtility.format(Texts.HEX_EDITOR_IFF_CHUNK, chunkName,
|
||||||
HexUtility.getLongValueHexString(chunkLength),
|
HexUtility.getLongValueHexString(chunkLength),
|
||||||
NumberUtility.getLongValueDecimalString(chunkLength));
|
NumberUtility.getLongValueDecimalString(chunkLength));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@ -98,11 +119,10 @@ public final class IFFParser extends HexEditorParser {
|
|||||||
if ((offset & 0x1) == 1) {
|
if ((offset & 0x1) == 1) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
printBlockWithError(contentBuilder, Texts.HEX_EDITOR_IFF_FILE_ERROR, fileContentLength, offset);
|
printBlockWithError(contentBuilder, Texts.HEX_EDITOR_IFF_FILE_ERROR, fileContentLength, offset);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user