com.github.junrar.rarfile.FileHeader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of junrar Show documentation
Show all versions of junrar Show documentation
rar decompression library in plain java
The newest version!
/*
* 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 "&"
* "<": "<" or "<"
* ">": ">" or ">"
* "@": "@"
*/
package com.github.junrar.rarfile;
import java.util.Calendar;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy