com.webcodepro.shrinkit.HeaderBlock Maven / Gradle / Ivy
package com.webcodepro.shrinkit;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.webcodepro.shrinkit.io.LittleEndianByteInputStream;
/**
* The Header Block contains information and content
* about a single entry (be it a file or disk image).
*
* Note that we need to support multiple versions of the NuFX
* archive format. Some details may be invalid, depending on
* version, and those are documented in the getter methods.
*
* @author [email protected]
* @see Apple II File Type Note $E0/$8002
*/
public class HeaderBlock {
private int headerCrc;
private int attribCount;
private int versionNumber;
private long totalThreads;
private int fileSysId;
private int fileSysInfo;
private long access;
private long fileType;
private long extraType;
private int storageType;
private Date createWhen;
private Date modWhen;
private Date archiveWhen;
private int optionSize;
private byte[] optionListBytes;
private byte[] attribBytes;
private String filename;
private String rawFilename;
private long headerSize = 0;
private List threads = new ArrayList();
/**
* Create the Header Block. This is done dynamically since
* the Header Block size varies significantly.
*/
public HeaderBlock(LittleEndianByteInputStream bs) throws IOException {
int type = bs.seekFileType(4);
if (type == 0) {
throw new IOException("Unable to decode this archive."); // FIXME - NLS
}
headerCrc = bs.readWord();
attribCount = bs.readWord();
versionNumber = bs.readWord();
totalThreads = bs.readLong();
fileSysId = bs.readWord();
fileSysInfo = bs.readWord();
access = bs.readLong();
fileType = bs.readLong();
extraType = bs.readLong();
storageType = bs.readWord();
createWhen = bs.readDate();
modWhen = bs.readDate();
archiveWhen = bs.readDate();
// Read the mysterious option_list
if (versionNumber >= 1) {
optionSize = bs.readWord();
if (optionSize > 0) {
optionListBytes = bs.readBytes(optionSize-2);
}
}
// Compute attribute bytes that exist and read (if needed)
int sizeofAttrib = attribCount - 58;
if (versionNumber >= 1) {
if (optionSize == 0) sizeofAttrib -= 2;
else sizeofAttrib -= optionSize;
}
if (sizeofAttrib > 0) {
attribBytes = bs.readBytes(sizeofAttrib);
}
// Read the (defunct) filename
int length = bs.readWord();
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
* each thread's data is read (per NuFX spec).
*/
public void readThreads(LittleEndianByteInputStream bs) throws IOException {
for (long l=0; l getThreadRecords() {
return threads;
}
public void setThreadRecords(List threads) {
this.threads = threads;
}
public long getHeaderSize() {
return headerSize;
}
}