Package com.emc.vipr.transform.compression

Source Code of com.emc.vipr.transform.compression.DeflateInputFilter

package com.emc.vipr.transform.compression;

import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.Deflater;
import java.util.zip.DeflaterInputStream;

import com.emc.vipr.transform.TransformConstants;
import com.emc.vipr.transform.encryption.KeyUtils;
import com.emc.vipr.transform.util.CountingInputStream;

public class DeflateInputFilter extends InputStream implements
        CompressionStream {
    private CountingInputStream uncompressedCounter;
    private CountingInputStream compressedCounter;
    private DigestInputStream digester;
    private boolean closed;
    private byte[] uncompressedDigest;

    public DeflateInputFilter(InputStream in, int level) throws IOException {
        Deflater def = new Deflater(level);
        uncompressedCounter = new CountingInputStream(in);
        try {
            digester = new DigestInputStream(uncompressedCounter, MessageDigest.getInstance("SHA1"));
        } catch (NoSuchAlgorithmException e) {
            throw new IOException("Unable to initialize digest", e);
        }
        DeflaterInputStream deflateFilter = new DeflaterInputStream(digester, def);
        compressedCounter = new CountingInputStream(deflateFilter);
    }
   
    @Override
    public int read() throws IOException {
        return compressedCounter.read();
    }
   
    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        return compressedCounter.read(b, off, len);
    }
   
    @Override
    public int read(byte[] b) throws IOException {
        return compressedCounter.read(b);
    }
   
    @Override
    public void close() throws IOException {
        if(closed) return;
        closed = true;
        compressedCounter.close();
        // Store digest (can only call this once).
        uncompressedDigest = digester.getMessageDigest().digest();
    }
   
    @Override
    public int available() throws IOException {
        return compressedCounter.available();
    }

    @Override
    public Map<String, String> getStreamMetadata() {
        if(!closed) {
            throw new IllegalStateException("Stream must be closed before getting metadata");
        }
       
        Map<String,String> metadata = new HashMap<String, String>();
       
        long compSize = compressedCounter.getByteCount();
        long uncompSize = uncompressedCounter.getByteCount();
        String compRatioString = String.format("%.1f%%", 100.0 - (compSize*100.0/uncompSize));
       
        metadata.put(TransformConstants.META_COMPRESSION_UNCOMP_SIZE, ""+uncompSize);
        metadata.put(TransformConstants.META_COMPRESSION_COMP_SIZE, ""+compSize);
        metadata.put(TransformConstants.META_COMPRESSION_COMP_RATIO, ""+compRatioString);
        metadata.put(TransformConstants.META_COMPRESSION_UNCOMP_SHA1, KeyUtils.toHexPadded(uncompressedDigest));
       
        return metadata;
    }

}
TOP

Related Classes of com.emc.vipr.transform.compression.DeflateInputFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.