Switching to applesingle library. Closes #25.
This commit is contained in:
parent
70c715bed9
commit
7b65c2fc7b
|
@ -51,13 +51,18 @@ tasks.withType(Jar) {
|
|||
doFirst {
|
||||
// Jar files with an appendix are standalone applications and need to have ShrinkIt included.
|
||||
if (appendix) {
|
||||
from { configurations.runtime.collect { it.name.startsWith('ShrinkItArchive') ? zipTree(it) : 'fake' } }
|
||||
from {
|
||||
configurations.runtime.collect {
|
||||
it.name.startsWith('ShrinkItArchive') || it.name.startsWith('applesingle-api') ? zipTree(it) : 'fake'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "net.sf.applecommander:ShrinkItArchive:$shkVersion"
|
||||
compile "net.sf.applecommander:applesingle-api:$asVersion"
|
||||
compileOnly "org.apache.ant:ant:$antVersion"
|
||||
|
||||
testCompile "junit:junit:$junitVersion"
|
||||
|
|
|
@ -5,6 +5,7 @@ version=1.5.0-BETA
|
|||
|
||||
# Dependency versions
|
||||
shkVersion=1.2.2
|
||||
asVersion=1.0.0
|
||||
swtVersion=4.6.1
|
||||
junitVersion=4.12
|
||||
antVersion=1.8.2
|
||||
|
|
|
@ -50,8 +50,6 @@ import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout;
|
|||
import com.webcodepro.applecommander.storage.physical.DosOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.ProdosOrder;
|
||||
import com.webcodepro.applecommander.util.AppleSingle;
|
||||
import com.webcodepro.applecommander.util.AppleSingle.ProdosFileInfo;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.StreamUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
@ -60,6 +58,9 @@ import com.webcodepro.applecommander.util.applesoft.Program;
|
|||
import com.webcodepro.applecommander.util.applesoft.Token;
|
||||
import com.webcodepro.applecommander.util.applesoft.TokenReader;
|
||||
|
||||
import io.github.applecommander.applesingle.AppleSingle;
|
||||
import io.github.applecommander.applesingle.ProdosFileInfo;
|
||||
|
||||
/**
|
||||
* ac provides a command line interface to key AppleCommander functions. Text
|
||||
* similar to this is produced in response to the -h option.
|
||||
|
@ -331,7 +332,7 @@ public class ac {
|
|||
public static void putAppleSingle(String imageName, String fileName, InputStream inputStream)
|
||||
throws IOException, DiskException {
|
||||
|
||||
AppleSingle as = new AppleSingle(inputStream);
|
||||
AppleSingle as = AppleSingle.read(inputStream);
|
||||
if (fileName == null) {
|
||||
fileName = as.getRealName();
|
||||
}
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
package com.webcodepro.applecommander.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Support reading of data from and AppleSingle source.
|
||||
* Does not implement all components at this time, extend as required.
|
||||
*
|
||||
* @see <a href="https://github.com/AppleCommander/AppleCommander/issues/20">AppleCommander issue #20</a>
|
||||
*/
|
||||
public class AppleSingle {
|
||||
public static final int MAGIC_NUMBER = 0x0051600;
|
||||
public static final int VERSION_NUMBER = 0x00020000;
|
||||
|
||||
private byte[] dataFork;
|
||||
private byte[] resourceFork;
|
||||
private String realName;
|
||||
private ProdosFileInfo prodosFileInfo;
|
||||
|
||||
public AppleSingle(String filename) throws IOException {
|
||||
byte[] fileData = Files.readAllBytes(Paths.get(filename));
|
||||
load(fileData);
|
||||
}
|
||||
public AppleSingle(InputStream stream) throws IOException {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
StreamUtil.copy(stream, os);
|
||||
os.flush();
|
||||
load(os.toByteArray());
|
||||
}
|
||||
|
||||
private void load(byte[] fileData) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(fileData)
|
||||
.order(ByteOrder.BIG_ENDIAN)
|
||||
.asReadOnlyBuffer();
|
||||
required(buffer, MAGIC_NUMBER, "Not an AppleSingle file - magic number does not match.");
|
||||
required(buffer, VERSION_NUMBER, "Only AppleSingle version 2 supported.");
|
||||
buffer.position(buffer.position() + 16); // Skip filler
|
||||
int entries = buffer.getShort();
|
||||
for (int i = 0; i < entries; i++) {
|
||||
int entryId = buffer.getInt();
|
||||
int offset = buffer.getInt();
|
||||
int length = buffer.getInt();
|
||||
buffer.mark();
|
||||
buffer.position(offset);
|
||||
byte[] entryData = new byte[length];
|
||||
buffer.get(entryData);
|
||||
if (entryId == 1) {
|
||||
dataFork = entryData;
|
||||
} else if (entryId == 2) {
|
||||
resourceFork = entryData;
|
||||
} else if (entryId == 11) {
|
||||
ByteBuffer infoData = ByteBuffer.wrap(entryData)
|
||||
.order(ByteOrder.BIG_ENDIAN)
|
||||
.asReadOnlyBuffer();
|
||||
int access = infoData.getShort();
|
||||
int fileType = infoData.getShort();
|
||||
int auxType = infoData.getInt();
|
||||
prodosFileInfo = new ProdosFileInfo(access, fileType, auxType);
|
||||
} else {
|
||||
throw new IOException(String.format("Unknown entry type of %04x", entryId));
|
||||
}
|
||||
buffer.reset();
|
||||
}
|
||||
}
|
||||
private void required(ByteBuffer buffer, int expected, String message) throws IOException {
|
||||
int actual = buffer.getInt();
|
||||
if (actual != expected) {
|
||||
throw new IOException(String.format("%s Expected 0x%08x but read 0x%08x.", message, expected, actual));
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getDataFork() {
|
||||
return dataFork;
|
||||
}
|
||||
public byte[] getResourceFork() {
|
||||
return resourceFork;
|
||||
}
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
public ProdosFileInfo getProdosFileInfo() {
|
||||
return prodosFileInfo;
|
||||
}
|
||||
|
||||
public class ProdosFileInfo {
|
||||
private int access;
|
||||
private int fileType;
|
||||
private int auxType;
|
||||
|
||||
public ProdosFileInfo(int access, int fileType, int auxType) {
|
||||
this.access = access;
|
||||
this.fileType = fileType;
|
||||
this.auxType = auxType;
|
||||
}
|
||||
|
||||
public int getAccess() {
|
||||
return access;
|
||||
}
|
||||
public int getFileType() {
|
||||
return fileType;
|
||||
}
|
||||
public int getAuxType() {
|
||||
return auxType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package com.webcodepro.applecommander.util;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -16,26 +15,10 @@ import com.webcodepro.applecommander.storage.FileEntry;
|
|||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosFileEntry;
|
||||
import com.webcodepro.applecommander.ui.ac;
|
||||
import com.webcodepro.applecommander.util.AppleSingle.ProdosFileInfo;
|
||||
|
||||
public class AppleSingleTest {
|
||||
private static final String AS_HELLO_BIN = "/hello.applesingle.bin";
|
||||
|
||||
@Test
|
||||
public void testSampleFromCc65() throws IOException {
|
||||
AppleSingle as = new AppleSingle(getClass().getResourceAsStream(AS_HELLO_BIN));
|
||||
|
||||
assertNull(as.getRealName());
|
||||
assertNull(as.getResourceFork());
|
||||
assertNotNull(as.getDataFork());
|
||||
assertNotNull(as.getProdosFileInfo());
|
||||
|
||||
ProdosFileInfo info = as.getProdosFileInfo();
|
||||
assertEquals(0xc3, info.getAccess());
|
||||
assertEquals(0x06, info.getFileType());
|
||||
assertEquals(0x0803, info.getAuxType());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testViaAcTool() throws IOException, DiskException {
|
||||
// Create a file that the JVM *should* delete for us.
|
||||
|
|
Loading…
Reference in New Issue