X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.compressions%2Fsrc%2Forg%2Fsimantics%2Fcompressions%2Fimpl%2FDecompressingInputStream.java;h=9a4bca9ac9fd858feac1d698c0e7028a4e32ad65;hp=8c7987177fb32145fe27d62a0c0a7585d998ab38;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.compressions/src/org/simantics/compressions/impl/DecompressingInputStream.java b/bundles/org.simantics.compressions/src/org/simantics/compressions/impl/DecompressingInputStream.java index 8c7987177..9a4bca9ac 100644 --- a/bundles/org.simantics.compressions/src/org/simantics/compressions/impl/DecompressingInputStream.java +++ b/bundles/org.simantics.compressions/src/org/simantics/compressions/impl/DecompressingInputStream.java @@ -1,165 +1,169 @@ -/******************************************************************************* - * Copyright (c) 2007, 2012 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.compressions.impl; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; -import java.nio.channels.ReadableByteChannel; - -/** - * @author Hannu Niemistö - * @author Tuukka Lehtonen - */ -public abstract class DecompressingInputStream extends InputStream { - - protected InputStream stream; - protected ReadableByteChannel channel; - protected ByteBuffer header; - protected IntBuffer intHeader; - protected ByteBuffer compressed; - protected ByteBuffer uncompressed; - protected byte[] compressedArray; - - public DecompressingInputStream(File file) throws FileNotFoundException { - this(new FileInputStream(file)); - } - - public DecompressingInputStream(FileInputStream stream) { - this(stream, stream.getChannel()); - } - - public DecompressingInputStream(InputStream stream) { - this(stream, null); - } - - public DecompressingInputStream(InputStream stream, ReadableByteChannel channel) { - this.stream = stream; - this.channel = channel; - header = ByteBuffer.allocate(8); - header.order(ByteOrder.LITTLE_ENDIAN); - intHeader = header.asIntBuffer(); - } - - @Override - public int read() throws IOException { - if(uncompressed == null || uncompressed.remaining() == 0) - if(!fillBuffer()) - return -1; - return uncompressed.get(); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int bytes = 0; - while(len > 0) { - if(uncompressed == null || uncompressed.remaining() == 0) { - if(!fillBuffer()) { - return bytes == 0 ? -1 : bytes; - } - } - int s = Math.min(len, uncompressed.remaining()); - uncompressed.get(b, off, s); - off += s; - len -= s; - bytes += s; - } - return bytes; - } - - @Override - public void close() throws IOException { - if (channel != null) { - channel.close(); - channel = null; - } - if (stream != null) { - stream.close(); - stream = null; - } - } - - private boolean fillBuffer() throws IOException { - header.position(0); - if (channel != null) { - if (Channels.read(channel, header) < 8) - return false; - } else { - if (Channels.readStream(stream, header.array(), 8) < 8) - return false; - } - - intHeader.position(0); - int compressedSize = intHeader.get(); - int uncompressedSize = intHeader.get(); - - if(uncompressedSize == 0) - return false; - - uncompressed = ensureBufferSize(uncompressed, uncompressedSize); - compressed = ensureBufferSize(compressed, compressedSize); - - compressed.position(0); - compressed.limit(compressedSize); - if (channel != null) { - if (Channels.read(channel, compressed) < compressedSize) - return false; - } else { - if (compressedArray == null || compressedArray.length < compressedSize) - compressedArray = new byte[compressedSize]; - if (Channels.readStream(stream, compressedArray, compressedSize) < 8) - return false; - compressed.put(compressedArray, 0, compressedSize); - } - - decompress(compressed, 0, compressedSize, uncompressed, 0, uncompressedSize); - - uncompressed.position(0); - uncompressed.limit(uncompressedSize); - - return true; - } - - private static ByteBuffer ensureBufferSize(ByteBuffer buffer, int minCapacity) { - int oldCapacity = buffer != null ? buffer.capacity() : 0; - if (buffer == null || oldCapacity < minCapacity) { - int newCapacity = grow(oldCapacity, minCapacity); - //System.out.println("ensureBufferSize(" + oldCapacity + ", " + minCapacity + "), new capacity " + newCapacity); - buffer = ByteBuffer.allocateDirect(newCapacity); - } - return buffer; - } - - /** - * @param oldCapacity current capacity of a buffer - * @param minCapacity - * @return new capacity - */ - private static int grow(int oldCapacity, int minCapacity) { - // overflow-conscious code - int newCapacity = oldCapacity + (oldCapacity >> 1); - if (newCapacity - minCapacity < 0) - newCapacity = minCapacity; - if (newCapacity < 0) // overflow - throw new OutOfMemoryError(); - return newCapacity; - } - - public abstract void decompress(ByteBuffer compressed, int compressedOffset, int compressedSize, - ByteBuffer uncompressed, int uncompressedOffset, int uncompressedSize) throws IOException; - +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.compressions.impl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.nio.channels.ReadableByteChannel; + +/** + * @author Hannu Niemistö + * @author Tuukka Lehtonen + */ +public abstract class DecompressingInputStream extends InputStream { + + protected InputStream stream; + protected ReadableByteChannel channel; + protected ByteBuffer header; + protected IntBuffer intHeader; + protected ByteBuffer compressed; + protected ByteBuffer uncompressed; + protected byte[] compressedArray; + + public DecompressingInputStream(File file) throws FileNotFoundException { + this(new FileInputStream(file)); + } + + public DecompressingInputStream(FileInputStream stream) { + this(stream, stream.getChannel()); + } + + public DecompressingInputStream(InputStream stream) { + this(stream, null); + } + + public DecompressingInputStream(InputStream stream, ReadableByteChannel channel) { + this.stream = stream; + this.channel = channel; + header = ByteBuffer.allocate(8); + header.order(ByteOrder.LITTLE_ENDIAN); + intHeader = header.asIntBuffer(); + } + + @Override + public int read() throws IOException { + if(uncompressed == null || uncompressed.remaining() == 0) + if(!fillBuffer()) + return -1; + return uncompressed.get(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int bytes = 0; + while(len > 0) { + if(uncompressed == null || uncompressed.remaining() == 0) { + if(!fillBuffer()) { + return bytes == 0 ? -1 : bytes; + } + } + int s = Math.min(len, uncompressed.remaining()); + uncompressed.get(b, off, s); + off += s; + len -= s; + bytes += s; + } + return bytes; + } + + @Override + public void close() throws IOException { + if (channel != null) { + channel.close(); + channel = null; + } + if (stream != null) { + stream.close(); + stream = null; + } + } + + private boolean fillBuffer() throws IOException { + header.position(0); + if (channel != null) { + if (Channels.read(channel, header) < 8) + return false; + } else { + if (Channels.readStream(stream, header.array(), 8) < 8) + return false; + } + + intHeader.position(0); + int compressedSize = intHeader.get(); + int uncompressedSize = intHeader.get(); + + if(uncompressedSize == 0) + return false; + + uncompressed = ensureBufferSize(uncompressed, uncompressedSize); + compressed = ensureBufferSize(compressed, compressedSize); + + compressed.position(0); + compressed.limit(compressedSize); + if (channel != null) { + if (Channels.read(channel, compressed) < compressedSize) + return false; + } else { + if (compressedArray == null || compressedArray.length < compressedSize) + compressedArray = new byte[compressedSize]; + if (Channels.readStream(stream, compressedArray, compressedSize) < 8) + return false; + compressed.put(compressedArray, 0, compressedSize); + } + + decompress(compressed, 0, compressedSize, uncompressed, 0, uncompressedSize); + + uncompressed.position(0); + uncompressed.limit(uncompressedSize); + + return true; + } + + private ByteBuffer ensureBufferSize(ByteBuffer buffer, int minCapacity) { + int oldCapacity = buffer != null ? buffer.capacity() : 0; + if (buffer == null || oldCapacity < minCapacity) { + int newCapacity = grow(oldCapacity, minCapacity); + //System.out.println("ensureBufferSize(" + oldCapacity + ", " + minCapacity + "), new capacity " + newCapacity); + buffer = allocateBuffer(newCapacity); + } + return buffer; + } + + protected ByteBuffer allocateBuffer(int capacity) { + return ByteBuffer.allocateDirect(capacity); + } + + /** + * @param oldCapacity current capacity of a buffer + * @param minCapacity + * @return new capacity + */ + private static int grow(int oldCapacity, int minCapacity) { + // overflow-conscious code + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity < 0) // overflow + throw new OutOfMemoryError(); + return newCapacity; + } + + public abstract void decompress(ByteBuffer compressed, int compressedOffset, int compressedSize, + ByteBuffer uncompressed, int uncompressedOffset, int uncompressedSize) throws IOException; + } \ No newline at end of file