Merging in changes from applecommander2 project. API did change a bit on

HeaderBlock.
This commit is contained in:
Rob Greene 2018-03-11 15:13:24 -05:00
parent 8f4ca7fb9f
commit e9469fe5a0
7 changed files with 93 additions and 30 deletions

View File

@ -46,8 +46,9 @@ public class HeaderBlock {
*/
public HeaderBlock(LittleEndianByteInputStream bs) throws IOException {
int type = bs.seekFileType(4);
if (type == 0)
if (type == 0) {
throw new IOException("Unable to decode this archive."); // FIXME - NLS
}
headerCrc = bs.readWord();
attribCount = bs.readWord();
versionNumber = bs.readWord();
@ -82,6 +83,9 @@ public class HeaderBlock {
if (length > 0) {
rawFilename = new String(bs.readBytes(length));
}
if (rawFilename == null) {
rawFilename = "Unknown";
}
}
/**
* Read in all data threads. All ThreadRecords are read and then
@ -128,15 +132,21 @@ public class HeaderBlock {
/**
* Get the data fork.
* Note that this first searches the data fork and then searches for a disk image;
* this may not be correct behavior.
*/
public ThreadRecord getDataForkInputStream() throws IOException {
return findThreadRecord(ThreadKind.DATA_FORK);
public ThreadRecord getDataForkThreadRecord() {
ThreadRecord thread = findThreadRecord(ThreadKind.DATA_FORK);
if (thread == null) {
thread = findThreadRecord(ThreadKind.DISK_IMAGE);
}
return thread;
}
/**
* Get the resource fork.
*/
public ThreadRecord getResourceForkInputStream() throws IOException {
public ThreadRecord getResourceForkThreadRecord() {
return findThreadRecord(ThreadKind.RESOURCE_FORK);
}
@ -149,6 +159,48 @@ public class HeaderBlock {
}
return null;
}
// HELPER METHODS
/**
* Helper method to determine the file system separator.
* Due to some oddities, breaking apart by byte value...
*/
public String getFileSystemSeparator() {
switch (getFileSysInfo() & 0xff) {
case 0xaf:
case 0x2f:
return "/";
case 0x3a:
case 0xba:
case 0x3f: // Note that $3F is per the documentation(!)
return ":";
case 0x5c:
case 0xdc:
return "\\";
default:
return "";
}
}
public long getUncompressedSize() {
long size = 0;
for (ThreadRecord r : threads) {
if (r.getThreadClass() == ThreadClass.DATA) {
size+= r.getThreadEof();
}
}
return size;
}
public long getCompressedSize() {
long size = 0;
for (ThreadRecord r : threads) {
if (r.getThreadClass() == ThreadClass.DATA) {
size+= r.getCompThreadEof();
}
}
return size;
}
// GENERATED CODE

View File

@ -38,8 +38,9 @@ public class MasterHeaderBlock {
bs.readBytes(127 - ByteConstants.NUFILE_ID.length);
headerOffset = 128;
int count = bs.read();
if (count != 0)
if (count != 0) {
throw new IOException("This is actually a Binary II archive with multiple files in it."); // FIXME - NLS
}
fileType = bs.seekFileType();
}
if (!(fileType == NuFileArchive.NUFILE_ARCHIVE)) {

View File

@ -5,19 +5,28 @@ package com.webcodepro.shrinkit;
* @author robgreene@users.sourceforge.net
*/
public enum ThreadFormat {
UNCOMPRESSED(0x0000), HUFFMAN_SQUEEZE(0x0001), DYNAMIC_LZW1(0x0002), DYNAMIC_LZW2(0x0003),
UNIX_12BIT_COMPRESS(0x0004), UNIX_16BIT_COMPRESS(0x0005);
UNCOMPRESSED(0x0000, "Uncompressed"),
HUFFMAN_SQUEEZE(0x0001, "Huffman Squeeze"),
DYNAMIC_LZW1(0x0002, "Dynamic LZW/1"),
DYNAMIC_LZW2(0x0003, "Dynamic LZW/2"),
UNIX_12BIT_COMPRESS(0x0004, "Unix 12-bit Compress"),
UNIX_16BIT_COMPRESS(0x0005, "Unix 16-bit Compress");
/** Associate the hex codes with the enum */
private int threadFormat;
private final int threadFormat;
private final String name;
private ThreadFormat(int threadFormat) {
private ThreadFormat(int threadFormat, String name) {
this.threadFormat = threadFormat;
this.name = name;
}
public int getThreadFormat() {
return threadFormat;
}
public String getName() {
return name;
}
/**
* Find the ThreadFormat.

View File

@ -63,8 +63,9 @@ public class LittleEndianByteInputStream extends InputStream implements ByteCons
int read = inputStream.read(data);
bytesRead+= read;
// In the case where we have a zero-byte file, 'read' stays at -1, which is not correct. Fix it.
if ((bytes == 0) && (read == -1))
if ((bytes == 0) && (read == -1)) {
read = 0;
}
if (read < bytes) {
throw new IOException("Requested " + bytes + " bytes, but " + read + " read");
}

View File

@ -148,6 +148,6 @@ public class HeaderBlockTest {
checkDate(new byte[] {0x00,0x11,0x11,0x5e,0x13,0x01,0x00,0x01}, b.getModWhen());
checkDate(new byte[] {0x38,0x0c,0x14,0x5f,0x08,0x07,0x00,0x04}, b.getArchiveWhen());
Assert.assertEquals(0x0000, b.getOptionSize());
Assert.assertNull(b.getRawFilename());
Assert.assertEquals("Unknown", b.getRawFilename());
}
}

View File

@ -7,6 +7,8 @@ import java.util.GregorianCalendar;
import org.junit.Assert;
import org.junit.Test;
import com.webcodepro.shrinkit.NuFileArchive;
/**
* Exercise the LittleEndianByteInputStream class.
* @author robgreene@users.sourceforge.net
@ -56,24 +58,22 @@ public class LittleEndianByteInputStreamTest {
}
}
}
// This methods got removed at some point but nobody updated the unit tests. Bad developer!
// @Test
// public void testCheckNuFileId() throws IOException {
// LittleEndianByteInputStream bs = new LittleEndianByteInputStream(new byte[] { 0x4e, (byte)0xf5, 0x46, (byte)0xe9, 0x6c, (byte)0xe5 });
// Assert.assertTrue(NuFileArchive.bs.checkNuFileId());
// Assert.assertEquals(6, bs.getTotalBytesRead());
// bs = new LittleEndianByteInputStream("NotNuFile".getBytes());
// Assert.assertFalse(bs.checkNuFileId());
// }
// This methods got removed at some point but nobody updated the unit tests. Bad developer!
// @Test
// public void testCheckNuFxId() throws IOException {
// LittleEndianByteInputStream bs = new LittleEndianByteInputStream(new byte[] { 0x4e, (byte)0xf5, 0x46, (byte)0xd8 });
// Assert.assertTrue(bs.checkNuFxId());
// Assert.assertEquals(4, bs.getTotalBytesRead());
// bs = new LittleEndianByteInputStream("NotNuFx".getBytes());
// Assert.assertFalse(bs.checkNuFxId());
// }
@Test
public void testCheckNuFileId() throws IOException {
try (LittleEndianByteInputStream bs = new LittleEndianByteInputStream(
new byte[] { 0x4e, (byte)0xf5, 0x46, (byte)0xe9, 0x6c, (byte)0xe5 })) {
Assert.assertEquals(NuFileArchive.NUFILE_ARCHIVE, bs.seekFileType(6));
Assert.assertEquals(6, bs.getTotalBytesRead());
}
}
@Test
public void testCheckNuFxId() throws IOException {
try (LittleEndianByteInputStream bs = new LittleEndianByteInputStream(
new byte[] { 0x4e, (byte)0xf5, 0x46, (byte)0xd8 })) {
Assert.assertEquals(NuFileArchive.NUFX_ARCHIVE, bs.seekFileType(4));
Assert.assertEquals(4, bs.getTotalBytesRead());
}
}
@Test
public void testReadWord() throws IOException {
try (LittleEndianByteInputStream bs = new LittleEndianByteInputStream(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 })) {

View File

@ -60,7 +60,7 @@ public class NufxLzwTest extends TestBase {
byte[] actual = null;
for (HeaderBlock header : headers) {
if (archiveFile.equals(header.getFilename())) {
ThreadRecord r = header.getDataForkInputStream();
ThreadRecord r = header.getDataForkThreadRecord();
long bytes = r.getThreadEof();
ByteArrayOutputStream buf = new ByteArrayOutputStream();
InputStream is = r.getInputStream();