Package org.anarres.lzo

Source Code of org.anarres.lzo.LzopOutputStream

/*
* This file is part of lzo-java, an implementation of LZO in Java.
* https://github.com/Karmasphere/lzo-java
*
* The Java portion of this library is:
* Copyright (C) 2011 Shevek <shevek@anarres.org>
* All Rights Reserved.
*
* The preprocessed C portion of this library is:
* Copyright (C) 2006-2011 Markus Franz Xaver Johannes Oberhumer
* All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with the LZO library; see the file COPYING.
* If not, see <http://www.gnu.org/licenses/> or write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.

* As a special exception, the copyright holders of this file
* give you permission to link this file with independent
* modules to produce an executable, regardless of the license
* terms of these independent modules, and to copy and distribute
* the resulting executable under terms of your choice, provided
* that you also meet, for each linked independent module,
* the terms and conditions of the license of that module. An
* independent module is a module which is not derived from or
* based on this library or file. If you modify this file, you may
* extend this exception to your version of the file, but
* you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version.
*/
package org.anarres.lzo;

import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.io.DataOutputBuffer;

/**
*
* @author shevek
*/
public class LzopOutputStream extends LzoOutputStream {

    private static final Log LOG = LogFactory.getLog(LzopOutputStream.class);
    private final long flags;
    private final CRC32 c_crc32_c;
    private final CRC32 c_crc32_d;
    private final Adler32 c_adler32_c;
    private final Adler32 c_adler32_d;
    private boolean closed = false;

    /**
     * Constructs a new LzopOutputStream.
     *
     * I recommend limiting flags to the following unless you REALLY know what
     * you are doing:
     * <ul>
     * <li>{@link LzopConstants#F_ADLER32_C}</li>
     * <li>{@link LzopConstants#F_ADLER32_D}</li>
     * <li>{@link LzopConstants#F_CRC32_C}</li>
     * <li>{@link LzopConstants#F_CRC32_D}</li>
     * </ul>
     */
    public LzopOutputStream(OutputStream out, LzoCompressor compressor, int inputBufferSize, long flags) throws IOException {
        super(out, compressor, inputBufferSize);
        this.flags = flags;
        this.c_crc32_c = ((flags & LzopConstants.F_CRC32_C) == 0) ? null : new CRC32();
        this.c_crc32_d = ((flags & LzopConstants.F_CRC32_D) == 0) ? null : new CRC32();
        this.c_adler32_c = ((flags & LzopConstants.F_ADLER32_C) == 0) ? null : new Adler32();
        this.c_adler32_d = ((flags & LzopConstants.F_ADLER32_D) == 0) ? null : new Adler32();
        writeLzopHeader();
    }

    public LzopOutputStream(OutputStream out, LzoCompressor compressor, int inputBufferSize) throws IOException {
        this(out, compressor, inputBufferSize, 0L);
    }

    public LzopOutputStream(OutputStream out, LzoCompressor compressor) throws IOException {
        this(out, compressor, 256 * 1024);
    }

    /**
     * Writes an lzop-compatible header to the OutputStream provided.
     */
    protected void writeLzopHeader() throws IOException {
        DataOutputBuffer dob = new DataOutputBuffer();
        try {
            dob.writeShort(LzopConstants.LZOP_VERSION);
            dob.writeShort(LzoVersion.LZO_LIBRARY_VERSION);
            dob.writeShort(LzopConstants.LZOP_COMPAT_VERSION);
            switch (getAlgorithm()) {
                case LZO1X:
                    // case LZO1X_1:
                    dob.writeByte(LzopConstants.M_LZO1X_1);
                    dob.writeByte(5);
                    break;
                /*
                case LZO1X_15:
                dob.writeByte(LzopConstants.M_LZO1X_1_15);
                dob.writeByte(1);
                break;
                case LZO1X_999:
                dob.writeByte(LzopConstants.M_LZO1X_999);
                dob.writeByte(9);
                break;
                 */
                default:
                    throw new IOException("Incompatible lzop algorithm " + getAlgorithm());
            }
            long mask = LzopConstants.F_ADLER32_C | LzopConstants.F_ADLER32_D;
            mask = mask | LzopConstants.F_CRC32_C | LzopConstants.F_CRC32_D;
            dob.writeInt((int) (flags & mask & 0xFFFFFFFF)); // all flags 0
            dob.writeInt(33188); // mode
            dob.writeInt((int) (System.currentTimeMillis() / 1000)); // mtime
            dob.writeInt(0); // gmtdiff ignored
            dob.writeByte(0); // no filename
            Adler32 headerChecksum = new Adler32();
            headerChecksum.update(dob.getData(), 0, dob.getLength());
            int hc = (int) headerChecksum.getValue();
            dob.writeInt(hc);
            out.write(LzopConstants.LZOP_MAGIC);
            out.write(dob.getData(), 0, dob.getLength());
        } finally {
            dob.close();
        }
    }

    private void writeChecksum(Checksum csum, byte[] data, int off, int len) throws IOException {
        if (csum == null)
            return;
        csum.reset();
        csum.update(data, off, len);
        long value = csum.getValue();
        // LOG.info("Writing checksum " + csum);
        writeInt((int) (value & 0xFFFFFFFF));
    }

    @Override
    protected void writeBlock(byte[] inputData, int inputPos, int inputLen, byte[] outputData, int outputPos, int outputLen) throws IOException {
        // LOG.info("inputLen=" + inputLen + "; outputLen=" + outputLen);
        writeInt(inputLen);
        if (outputLen < inputLen)
            writeInt(outputLen);
        else
            writeInt(inputLen);

        // This is where we put checksums, if any.
        writeChecksum(c_adler32_d, inputData, inputPos, inputLen);
        writeChecksum(c_crc32_d, inputData, inputPos, inputLen);
        if (outputLen < inputLen) {
            writeChecksum(c_adler32_c, outputData, outputPos, outputLen);
            writeChecksum(c_crc32_c, outputData, outputPos, outputLen);
        }

        if (outputLen < inputLen)
            out.write(outputData, outputPos, outputLen);
        else
            out.write(inputData, inputPos, inputLen);
    }

    /**
     * Writes a null word to the underlying output stream, then closes it.
     */
    @Override
    public void close() throws IOException {
        if (!closed) {
            flush();
            out.write(new byte[]{0, 0, 0, 0});
            super.close();
            closed = true;
        }
    }
}
TOP

Related Classes of org.anarres.lzo.LzopOutputStream

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.