Package info.ata4.util.io.lzma

Source Code of info.ata4.util.io.lzma.LzmaBufferUtils$ByteBufferProgress

/*
** 2014 April 8
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
*/
package info.ata4.util.io.lzma;

import info.ata4.io.buffer.ByteBufferInputStream;
import info.ata4.io.buffer.ByteBufferOutputStream;
import info.ata4.log.LogUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import lzma.LzmaDecoder;
import lzma.LzmaEncoder;

/**
* LZMA byte buffer utility class.
*
* @author Nico Bergemann <barracuda415 at yahoo.de>
*/
public class LzmaBufferUtils {
   
    private static final Logger L = LogUtils.getLogger();

    private LzmaBufferUtils() {
    }
   
    public static ByteBuffer decode(ByteBuffer bb) throws IOException {
        ByteBuffer bbc = bb.duplicate();
        bbc.order(ByteOrder.LITTLE_ENDIAN);
       
        byte[] lzmaProps = new byte[5];
        bbc.get(lzmaProps);
       
        long lzmaSize = bbc.getLong();

        if (lzmaSize < 0) {
            throw new IOException("Invalid LZMA size");
        } else if (lzmaSize > Integer.MAX_VALUE) {
            throw new IOException("Uncompressed LZMA buffer is too large for byte buffers");
        }
       
        ByteBuffer bbu = ByteBuffer.allocateDirect((int) lzmaSize);
       
        LzmaDecoder dec = new LzmaDecoder();
        if (!dec.setDecoderProperties(lzmaProps)) {
            throw new IOException("Invalid LZMA props");
        }
       
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleAtFixedRate(new ByteBufferProgress(bbc), 2, 1, TimeUnit.SECONDS);
       
        try {
            InputStream is = new ByteBufferInputStream(bbc);
            OutputStream os = new ByteBufferOutputStream(bbu);
            if (!dec.code(is, os, lzmaSize)) {
                throw new IOException("LZMA decoding error");
            }
        } finally {   
            executor.shutdown();
        }
       
        bbu.flip();
        bbu.order(bb.order());
       
        return bbu;
    }
   
    public static ByteBuffer encode(ByteBuffer bb, int lc, int lp, int pb, int dictSize) throws IOException {
        ByteBuffer bbu = bb.duplicate();
        ByteBuffer bbc = ByteBuffer.allocateDirect(bbu.limit() + 13);
        bbc.order(ByteOrder.LITTLE_ENDIAN);
       
        LzmaEncoder enc = new LzmaEncoder();
        if (!enc.setLcLpPb(lc, lp, pb)) {
            throw new IOException("Invalid LZMA props");
        }
        if (!enc.setDictionarySize(dictSize)) {
            throw new IOException("Invalid dictionary size");
        }
        enc.setEndMarkerMode(true);
       
        bbc.put(enc.getCoderProperties());
        bbc.putLong(bbu.limit());
       
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleAtFixedRate(new ByteBufferProgress(bbu), 2, 2, TimeUnit.SECONDS);
       
        try {
            InputStream is = new ByteBufferInputStream(bbu);
            OutputStream os = new ByteBufferOutputStream(bbc);
            enc.code(is, os);
        } finally {
            executor.shutdown();
        }
       
        bbc.flip();
        bbc.order(bb.order());
       
        return bbc;
    }
   
    public static ByteBuffer encode(ByteBuffer bb) throws IOException {
        return encode(bb, 3, 0, 2, 1 << 19);
    }
   
    private static class ByteBufferProgress implements Runnable {
       
        private final ByteBuffer bb;
       
        ByteBufferProgress(ByteBuffer bb) {
            this.bb = bb;
        }
       
        @Override
        public void run() {
            double progress = Math.round(bb.position() / (double) bb.limit() * 100);
            L.log(Level.INFO, "{0}%", progress);
        }
       
    }
}
TOP

Related Classes of info.ata4.util.io.lzma.LzmaBufferUtils$ByteBufferProgress

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.