/** * JHOVE2 - Next-generation architecture for format-aware characterization * * Copyright (c) 2009 by The Regents of the University of California, * Ithaka Harbors, Inc., and The Board of Trustees of the Leland Stanford * Junior University. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * o Neither the name of the University of California/California Digital * Library, Ithaka Harbors/Portico, or Stanford University, nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package org.jhove2.module.format.gzip.properties; import java.util.Date; import org.jhove2.annotation.ReportableProperty; import org.jhove2.core.reportable.AbstractReportable; import org.jhove2.module.format.gzip.field.CompressionMethod; import org.jhove2.module.format.gzip.field.CompressionType; import org.jhove2.module.format.gzip.field.OperatingSystem; import com.sleepycat.persist.model.Persistent; /** * A GZip file entry. */ @Persistent public class GzipEntryProperties extends AbstractReportable { /** WARC record data container. */ protected GzipEntryData entry; /** * Constructor required by the persistence layer. */ public GzipEntryProperties() { } /** * Construct GZip entry base property instance with the supplied data. * @param entry GZip entry data */ public GzipEntryProperties(GzipEntryData entry) { this.entry = entry; } /** * Returns the index of this entry in the GZip file. * @return the index (0-based) of the entry. */ /* public int getIndex() { return entry.index; } */ /** * Returns whether the entry is compliant or not. * @return whether the entry is compliant or not */ @ReportableProperty(order = 1, value = "Is non compliant.") public boolean getIsNonCompliant() { return entry.isNonCompliant; } /** * Returns the offset of the beginning of this entry in the GZip * file. * @return the offset of this entry, as a number of bytes from the * start of the GZip file. */ @ReportableProperty(order = 2, value = "Offset value.") public long getOffset() { return entry.offset; } /** * Returns the name of the compressed file. * @return the name of the compressed file or <code>null</code> if * the compressed data did not come from a file. */ @ReportableProperty(order = 3, value = "GZip entry name.") public String getName() { return entry.fileName; } /** * Returns the GZip member comment. * @return the GZip member comment or <code>null</code> if absent. */ @ReportableProperty(order = 4, value = "GZip entry comment.") public String getComment() { return entry.comment; } /** * Returns the most recent modification time of the original * compressed file as a {@link Date} object. * @return last modification date of the compressed file or * <code>null</code> if none is present in the GZip header. */ @ReportableProperty(order = 5, value = "GZip entry date.") public Date getLastModified() { return (entry.date != null)? new Date(entry.date.getTime()): null; } /** * Returns the most recent modification time of the original * compressed file as a number of milliseconds since 00:00:00 GMT, * Jan. 1, 1970. * @return last modification time of the compressed file or * <code>-1</code> if none is present in the GZip header. */ public long getTime() { return (entry.date != null)? entry.date.getTime(): -1L; } /** * Returns the compression method used for this entry. * @return the compression method. */ @ReportableProperty(order = 6, value = "GZip entry compression method.") public CompressionMethod getCompressionMethod() { return entry.method; } /** * Returns the compression type indicated in the extra flags of * the member header. * @return the compression type or <code>null</code> if absent. * * @see #isExtraFlagsValid */ public CompressionType getCompressionFlags() { return entry.extraFlags; } /** * Returns the operating system on which the GZip member was * compressed. * @return the operating system. * * @see #isOperatingSystemValid */ @ReportableProperty(order = 7, value = "GZip entry operating system.") public OperatingSystem getOperatingSystem() { return entry.os; } /** * Returns whether the GZip member is announced as containing only * ASCII text. * @return the ASCII text flag from the member header. */ public boolean isAscii() { return entry.asciiFlag; } /** * Returns the extra fields of the GZip member header. * @return the extra fields as an array of bytes or * <code>null</code> if none are present. */ /* public byte[] getExtra() { int len = entry.extraFields.length; byte[] copy = new byte[len]; System.arraycopy(entry.extraFields, 0, copy, 0, len); return copy; } */ /** * Returns the CRC16 read from the GZip member header. * @return the CRC16 of the GZip member header or <code>-1</code> * if absent. * * @see #getComputedHeaderCrc * @see #isHeaderCrcValid */ @ReportableProperty(order = 8, value = "GZip entry header crc16.") public String getCrc16() { String crc16; if (entry.readCrc16 != null) { crc16 = "0x" + Integer.toHexString(entry.readCrc16 & 0xffff); } else { crc16 = null; } return crc16; } /** * Returns the CRC16 computed from the GZip member header. * @return the computed CRC16. * * @see #getHeaderCrc * @see #isHeaderCrcValid */ public long getComputedCrc16() { return entry.computedCrc16; } /** * Returns the data CRC (a.k.a. CRC32) read from the GZip member * trailer. * @return the CRC32 of the GZip member trailer or <code>-1</code> * if the member trailer has not yet been read. * * @see #getComputedDataCrc * @see #isDataCrcValid */ @ReportableProperty(order = 9, value = "GZip entry crc32.") public String getCrc32() { return "0x" + Integer.toHexString(entry.readCrc32); } /** * Returns the data CRC (a.k.a. CRC32) computed from the read * member data. * @return the computed CRC32 or <code>-1</code> if the member * trailer has not yet been read. * * @see #getDataCrc * @see #isDataCrcValid */ public long getComputedCrc32() { return entry.computedCrc32; } /** * Returns the ISIZE of the GZip member trailer, i.e. the announced * compressed size of the member data modulo 32. * @return the ISIZE value of the member trailer or * <code>-1</code> if the member trailer has not yet * been read. * * @see #isISizeValid */ @ReportableProperty(order = 10, value = "GZip entry extracted size (ISIZE) value.") public long getISize() { return entry.readISize; } /** * Returns the (computed) uncompressed size of the member data. * @return the uncompressed size of the member data or * <code>-1</code> if the member trailer has not yet * been read. */ @ReportableProperty(order = 11, value = "GZip entry (computed) uncompressed size, in bytes.") public long getSize() { return entry.size; } /** * Returns the (computed) compressed size of the member data. * @return the compressed size of the member data or * <code>-1</code> if the member trailer has not yet * been read. */ @ReportableProperty(order = 12, value = "GZip entry (computed) compressed size, in bytes.") public long getCompressedSize() { return entry.csize; } /** * Returns the (computed) ISIZE of the GZip member trailer, i.e. * the compressed size of the member data modulo 32. * @return the computed ISIZE value of the member data or * <code>-1</code> if the member trailer has not yet * been read. * * @see #isISizeValid */ public long getComputedISize() { return entry.computedISize; } @ReportableProperty(order = 13, value = "GZip entry (computed) compression ratio.") public double getCompressionRatio() { double ratio = -1.0; long size = entry.size; long csize = entry.csize; if ((size > 0L) && (csize > 0L)) { // Compute compression ratio with 2 decimals only. long l = ((size - csize) * 10000L) / size; ratio = l / 100.00; } return ratio; } /** * Returns whether this entry is compliant with the rules listed * in section 2.3.1.2 of RFC 1952. * <blockquote> * Compliant decompressors shall only check ID1 + ID2 (magic * number), CM (compression method) and unset reserved flags. They * may ignore FTEXT and OS header fields. * <blockquote> * <p> * As no GzipEntry instance can be created with invalid magic number * or unsupported compression method (deflate), this method only * checks that no reserved flag is set.</p> * * @return <code>true</code> if the entry is compliant with RFC 1952 * rules; <code>false</code> otherwise. */ /* public boolean isCompliant() { return entry.isReservedFlagsValid(); } */ /** * Returns whether this entry is valid, i.e. is compliant and no * error (invalid CRC or ISize) was found. * * @return <code>true</code> if the entry is valid; * <code>false</code> otherwise. */ /* public boolean isValid() { return (entry.errors == 0); } */ }