Switching to applesingle library. Closes #25.

This commit is contained in:
Rob Greene 2018-05-26 21:29:30 -05:00
parent 70c715bed9
commit 7b65c2fc7b
5 changed files with 12 additions and 134 deletions

View File

@ -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"

View File

@ -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

View File

@ -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();
}

View File

@ -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;
}
}
}

View File

@ -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.