All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.archive.format.gzip.GZIPHeader Maven / Gradle / Ivy

There is a newer version: 1.1.9
Show newest version
package org.archive.format.gzip;

import java.io.IOException;
import java.io.OutputStream;

import org.archive.util.ByteOp;
import org.archive.util.io.CRCOutputStream;

public class GZIPHeader implements GZIPConstants {


	GZIPStaticHeader staticHeader = null;
	GZIPFExtraRecords records = null;
	byte fileName[] = null;
	int fileNameLength = -1;
	byte comment[] = null;
	int commentLength = -1;
	int crc = -1;

	/*
     * +----+----+----+----+----+----+----+----+----+----+----+----+
     * |ID1 |ID2 | CM |FLG |       MTIME       |XFL | OS | (more-->)
     * +----+----+----+----+----+----+----+----+----+----+----+----+
     * (if FLG.FEXTRA set)
     * +---+---+=================================+
     * | XLEN  |...XLEN bytes of "extra field"...| (more-->)
     * +---+---+=================================+
     * ("extra field" is then composed of a series of)
	 *         +---+---+---+---+==================================+
     *         |SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
     *         +---+---+---+---+==================================+
     * (if FLG.FNAME set)
     * +=========================================+
     * |...original file name, zero-terminated...| (more-->)
     * +=========================================+
     * (if FLG.FCOMMENT set)
     * +===================================+
     * |...file comment, zero-terminated...| (more-->)
     * +===================================+
     * (if FLG.FHCRC set)
     * +---+---+
     * | CRC16 |
     * +---+---+
     */


	public GZIPHeader() {
		staticHeader = new GZIPStaticHeader();
		records = null;
		fileName = null;
		fileNameLength = 0;
		comment = null;
		commentLength = 0;
		crc = -1;
	}

	public GZIPHeader(GZIPStaticHeader staticHeader) {
		this.staticHeader = staticHeader;
		records = null;
		fileName = null;
		fileNameLength = 0;
		comment = null;
		commentLength = 0;
		crc = -1;
	}
	public GZIPStaticHeader getStaticHeader() {
		return staticHeader;
	}
	public byte[] getFileName() {
		return fileName;
	}
	public byte[] getComment() {
		return comment;
	}
	public long getFNameLength() {
		return fileNameLength;
	}
	public int getHeaderCRC() {
		return crc;
	}
	public void setFName(byte fileName[]) {
		if(fileName != null) {
			this.fileName = ByteOp.copy(fileName);
			staticHeader.setFNameFlag(true);
			fileNameLength = fileName.length;
		} else {
			this.fileName = null;
			staticHeader.setFNameFlag(false);
			fileNameLength = 0;
		}
		crc = -1;
	}

	public long getCommentLength() {
		return commentLength;
	}
	public void setFComment(byte comment[]) {
		if(comment != null) {
			this.comment = ByteOp.copy(comment);
			staticHeader.setFCommentFlag(true);
			commentLength = comment.length;
		} else {
			this.comment = null;
			staticHeader.setFCommentFlag(false);
			commentLength = 0;
		}
		crc = -1;
	}

	public void replaceRecord(byte name[], byte value[])
		throws GZIPFormatException {

		if(records != null) {
			removeAllRecords(name);
		}
		addRecord(name,value);
	}

	public void removeAllRecords(byte name[]) {
		int removed = 0;
		if(records != null) {
			int kept = 0;
			for(int i = 0; i < records.size(); i++) {
				if(records.get(i).matchesName(name)) {
					records.remove(i);
					removed++;
					i--;
				} else {
					kept++;
				}
			}
			if(kept == 0) {
				records = null;
				staticHeader.setFExtraFlag(false);
			}
		}
		if(removed > 0) {
			crc = -1;
		}
	}

	public void addRecord(byte name[], long intVal) throws GZIPFormatException {
		if(records == null) {
			records = new GZIPFExtraRecords();
		}
		records.add(new GZIPFExtraRecord(name,intVal));
		staticHeader.setFExtraFlag(true);
		crc = -1;
	}

	public void addRecord(byte name[], byte value[]) throws GZIPFormatException {
		if(records == null) {
			records = new GZIPFExtraRecords();
		}
		records.add(new GZIPFExtraRecord(name,value));
		staticHeader.setFExtraFlag(true);
		crc = -1;
	}

	public GZIPFExtraRecord getRecord(int i) {
		if(records == null || records.isEmpty()) {
			throw new IndexOutOfBoundsException();
		}
		return records.get(i);
	}

	public int getRecordCount() {
		return (records == null) ? 0 : records.size();
	}

	public GZIPFExtraRecord getRecord(byte[] name) {
		if(records != null) {
			for(GZIPFExtraRecord rec : records) {
				if(rec.matchesName(name)) {
					return rec;
				}
			}
		}
		return null;
	}

	public long getIntRecord(byte[] name) {
		if(records != null) {
			for(GZIPFExtraRecord rec : records) {
				if(rec.matchesName(name)) {
					return ByteOp.bytesToInt(rec.getValue());
				}
			}
		}
		return -1;
	}

	public int getLength() {
		int size = staticHeader.getLength();
		if(records != null) {
			size += records.getByteLength();
		}
		size += fileNameLength;
		size += commentLength;
		if(staticHeader.isFHCRCSet()) {
			size += 2;
		}
		return size;
	}

	public void writeBytes(OutputStream os) throws IOException {
		OutputStream origOS = os;
		if(staticHeader.isFHCRCSet()) {
			if(crc == -1) {
				os = new CRCOutputStream(origOS);
			}
		}
		staticHeader.writeTo(os);
		if(staticHeader.isFExtraSet()) {
			records.writeTo(os);
		}
		if(staticHeader.isFNameSet()) {
			os.write(fileName);
		}
		if(staticHeader.isFCommentSet()) {
			os.write(comment);
		}
		if(staticHeader.isFHCRCSet()) {

			if(crc == -1) {
				crc = (int) ((CRCOutputStream) os).getCRCValue() & 0xffff;
			}
			ByteOp.writeShort(origOS, crc);
		}
	}
	public static boolean isValidCompressionMethod(int cm) {
		return cm == GZIP_COMPRESSION_METHOD_DEFLATE;
	}

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy