summaryrefslogtreecommitdiff
path: root/org.fox.ttcomics/src/main/java/com/github/junrar/rarfile/FileHeader.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.fox.ttcomics/src/main/java/com/github/junrar/rarfile/FileHeader.java')
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/junrar/rarfile/FileHeader.java421
1 files changed, 421 insertions, 0 deletions
diff --git a/org.fox.ttcomics/src/main/java/com/github/junrar/rarfile/FileHeader.java b/org.fox.ttcomics/src/main/java/com/github/junrar/rarfile/FileHeader.java
new file mode 100644
index 0000000..84dce5e
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/junrar/rarfile/FileHeader.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
+ * Original author: Edmund Wagner
+ * Creation date: 22.05.2007
+ *
+ * Source: $HeadURL$
+ * Last changed: $LastChangedDate$
+ *
+ *
+ * the unrar licence applies to all junrar source and binary distributions
+ * you are not allowed to use this source to re-create the RAR compression algorithm
+ *
+ * Here some html entities which can be used for escaping javadoc tags:
+ * "&": "&" or "&"
+ * "<": "&#060;" or "&lt;"
+ * ">": "&#062;" or "&gt;"
+ * "@": "&#064;"
+ */
+package com.github.junrar.rarfile;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+
+import com.github.junrar.io.Raw;
+
+
+/**
+ * DOCUMENT ME
+ *
+ * @author $LastChangedBy$
+ * @version $LastChangedRevision$
+ */
+public class FileHeader extends BlockHeader {
+
+ //private final Log //logger = LogFactory.getLog(FileHeader.class.getName());
+
+ private static final byte SALT_SIZE = 8;
+
+ private static final byte NEWLHD_SIZE = 32;
+
+ private long unpSize;
+
+ private final HostSystem hostOS;
+
+ private final int fileCRC;
+
+ private final int fileTime;
+
+ private byte unpVersion;
+
+ private byte unpMethod;
+
+ private short nameSize;
+
+ private int highPackSize;
+
+ private int highUnpackSize;
+
+ private final byte[] fileNameBytes;
+
+ private String fileName;
+ private String fileNameW;
+
+ private byte[] subData;
+
+ private final byte[] salt = new byte[SALT_SIZE];
+
+ private Date mTime;
+
+ private Date cTime;
+
+ private Date aTime;
+
+ private Date arcTime;
+
+ private long fullPackSize;
+
+ private long fullUnpackSize;
+
+ private int fileAttr;
+
+ private int subFlags; // same as fileAttr (in header)
+
+ private int recoverySectors = -1;
+
+ public FileHeader(BlockHeader bh, byte[] fileHeader) {
+ super(bh);
+
+ int position = 0;
+ unpSize = Raw.readIntLittleEndianAsLong(fileHeader, position);
+ position += 4;
+ hostOS = HostSystem.findHostSystem(fileHeader[4]);
+ position++;
+
+ fileCRC = Raw.readIntLittleEndian(fileHeader, position);
+ position += 4;
+
+ fileTime = Raw.readIntLittleEndian(fileHeader, position);
+ position += 4;
+
+ unpVersion |= fileHeader[13] & 0xff;
+ position++;
+ unpMethod |= fileHeader[14] & 0xff;
+ position++;
+ nameSize = Raw.readShortLittleEndian(fileHeader, position);
+ position += 2;
+
+ fileAttr = Raw.readIntLittleEndian(fileHeader, position);
+ position += 4;
+ if (isLargeBlock()) {
+ highPackSize = Raw.readIntLittleEndian(fileHeader, position);
+ position += 4;
+
+ highUnpackSize = Raw.readIntLittleEndian(fileHeader, position);
+ position += 4;
+ } else {
+ highPackSize = 0;
+ highUnpackSize = 0;
+ if (unpSize == 0xffffffff) {
+
+ unpSize = 0xffffffff;
+ highUnpackSize = Integer.MAX_VALUE;
+ }
+
+ }
+ fullPackSize |= highPackSize;
+ fullPackSize <<= 32;
+ fullPackSize |= getPackSize();
+
+ fullUnpackSize |= highUnpackSize;
+ fullUnpackSize <<= 32;
+ fullUnpackSize += unpSize;
+
+ nameSize = nameSize > 4 * 1024 ? 4 * 1024 : nameSize;
+
+ fileNameBytes = new byte[nameSize];
+ for (int i = 0; i < nameSize; i++) {
+ fileNameBytes[i] = fileHeader[position];
+ position++;
+ }
+
+ if (isFileHeader()) {
+ if (isUnicode()) {
+ int length = 0;
+ fileName = "";
+ fileNameW = "";
+ while (length < fileNameBytes.length
+ && fileNameBytes[length] != 0) {
+ length++;
+ }
+ byte[] name = new byte[length];
+ System.arraycopy(fileNameBytes, 0, name, 0, name.length);
+ fileName = new String(name);
+ if (length != nameSize) {
+ length++;
+ fileNameW = FileNameDecoder.decode(fileNameBytes, length);
+ }
+ } else {
+ fileName = new String(fileNameBytes);
+ fileNameW = "";
+ }
+ }
+
+ if (UnrarHeadertype.NewSubHeader.equals(headerType)) {
+ int datasize = headerSize - NEWLHD_SIZE - nameSize;
+ if (hasSalt()) {
+ datasize -= SALT_SIZE;
+ }
+ if (datasize > 0) {
+ subData = new byte[datasize];
+ for (int i = 0; i < datasize; i++) {
+ subData[i] = (fileHeader[position]);
+ position++;
+ }
+ }
+
+ if (NewSubHeaderType.SUBHEAD_TYPE_RR.byteEquals(fileNameBytes)) {
+ recoverySectors = subData[8] + (subData[9] << 8)
+ + (subData[10] << 16) + (subData[11] << 24);
+ }
+ }
+
+ if (hasSalt()) {
+ for (int i = 0; i < SALT_SIZE; i++) {
+ salt[i] = fileHeader[position];
+ position++;
+ }
+ }
+ mTime = getDateDos(fileTime);
+ // TODO rartime -> extended
+
+ }
+
+ @Override
+ public void print() {
+ super.print();
+ StringBuilder str = new StringBuilder();
+ str.append("unpSize: " + getUnpSize());
+ str.append("\nHostOS: " + hostOS.name());
+ str.append("\nMDate: " + mTime);
+ str.append("\nFileName: " + getFileNameString());
+ str.append("\nunpMethod: " + Integer.toHexString(getUnpMethod()));
+ str.append("\nunpVersion: " + Integer.toHexString(getUnpVersion()));
+ str.append("\nfullpackedsize: " + getFullPackSize());
+ str.append("\nfullunpackedsize: " + getFullUnpackSize());
+ str.append("\nisEncrypted: " + isEncrypted());
+ str.append("\nisfileHeader: " + isFileHeader());
+ str.append("\nisSolid: " + isSolid());
+ str.append("\nisSplitafter: " + isSplitAfter());
+ str.append("\nisSplitBefore:" + isSplitBefore());
+ str.append("\nunpSize: " + getUnpSize());
+ str.append("\ndataSize: " + getDataSize());
+ str.append("\nisUnicode: " + isUnicode());
+ str.append("\nhasVolumeNumber: " + hasVolumeNumber());
+ str.append("\nhasArchiveDataCRC: " + hasArchiveDataCRC());
+ str.append("\nhasSalt: " + hasSalt());
+ str.append("\nhasEncryptVersions: " + hasEncryptVersion());
+ str.append("\nisSubBlock: " + isSubBlock());
+ //logger.info(str.toString());
+ }
+
+ private Date getDateDos(int time) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.YEAR, (time >>> 25) + 1980);
+ cal.set(Calendar.MONTH, ((time >>> 21) & 0x0f) - 1);
+ cal.set(Calendar.DAY_OF_MONTH, (time >>> 16) & 0x1f);
+ cal.set(Calendar.HOUR_OF_DAY, (time >>> 11) & 0x1f);
+ cal.set(Calendar.MINUTE, (time >>> 5) & 0x3f);
+ cal.set(Calendar.SECOND, (time & 0x1f) * 2);
+ return cal.getTime();
+ }
+
+ public Date getArcTime() {
+ return arcTime;
+ }
+
+ public void setArcTime(Date arcTime) {
+ this.arcTime = arcTime;
+ }
+
+ public Date getATime() {
+ return aTime;
+ }
+
+ public void setATime(Date time) {
+ aTime = time;
+ }
+
+ public Date getCTime() {
+ return cTime;
+ }
+
+ public void setCTime(Date time) {
+ cTime = time;
+ }
+
+ public int getFileAttr() {
+ return fileAttr;
+ }
+
+ public void setFileAttr(int fileAttr) {
+ this.fileAttr = fileAttr;
+ }
+
+ public int getFileCRC() {
+ return fileCRC;
+ }
+
+ public byte[] getFileNameByteArray() {
+ return fileNameBytes;
+ }
+
+ public String getFileNameString() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getFileNameW() {
+ return fileNameW;
+ }
+
+ public void setFileNameW(String fileNameW) {
+ this.fileNameW = fileNameW;
+ }
+
+ public int getHighPackSize() {
+ return highPackSize;
+ }
+
+ public int getHighUnpackSize() {
+ return highUnpackSize;
+ }
+
+ public HostSystem getHostOS() {
+ return hostOS;
+ }
+
+ public Date getMTime() {
+ return mTime;
+ }
+
+ public void setMTime(Date time) {
+ mTime = time;
+ }
+
+ public short getNameSize() {
+ return nameSize;
+ }
+
+ public int getRecoverySectors() {
+ return recoverySectors;
+ }
+
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ public byte[] getSubData() {
+ return subData;
+ }
+
+ public int getSubFlags() {
+ return subFlags;
+ }
+
+ public byte getUnpMethod() {
+ return unpMethod;
+ }
+
+ public long getUnpSize() {
+ return unpSize;
+ }
+
+ public byte getUnpVersion() {
+ return unpVersion;
+ }
+
+ public long getFullPackSize() {
+ return fullPackSize;
+ }
+
+ public long getFullUnpackSize() {
+ return fullUnpackSize;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString();
+ }
+
+ /**
+ * the file will be continued in the next archive part
+ *
+ * @return
+ */
+ public boolean isSplitAfter() {
+ return (this.flags & BlockHeader.LHD_SPLIT_AFTER) != 0;
+ }
+
+ /**
+ * the file is continued in this archive
+ *
+ * @return
+ */
+ public boolean isSplitBefore() {
+ return (this.flags & LHD_SPLIT_BEFORE) != 0;
+ }
+
+ /**
+ * this file is compressed as solid (all files handeled as one)
+ *
+ * @return
+ */
+ public boolean isSolid() {
+ return (this.flags & LHD_SOLID) != 0;
+ }
+
+ /**
+ * the file is encrypted
+ *
+ * @return
+ */
+ public boolean isEncrypted() {
+ return (this.flags & BlockHeader.LHD_PASSWORD) != 0;
+ }
+
+ /**
+ * the filename is also present in unicode
+ *
+ * @return
+ */
+ public boolean isUnicode() {
+ return (flags & LHD_UNICODE) != 0;
+ }
+
+ public boolean isFileHeader() {
+ return UnrarHeadertype.FileHeader.equals(headerType);
+ }
+
+ public boolean hasSalt() {
+ return (flags & LHD_SALT) != 0;
+ }
+
+ public boolean isLargeBlock() {
+ return (flags & LHD_LARGE) != 0;
+ }
+
+ /**
+ * whether this fileheader represents a directory
+ *
+ * @return
+ */
+ public boolean isDirectory() {
+ return (flags & LHD_WINDOWMASK) == LHD_DIRECTORY;
+ }
+}