tikhomirov@530: /* tikhomirov@530: * Copyright (c) 2013 TMate Software Ltd tikhomirov@530: * tikhomirov@530: * This program is free software; you can redistribute it and/or modify tikhomirov@530: * it under the terms of the GNU General Public License as published by tikhomirov@530: * the Free Software Foundation; version 2 of the License. tikhomirov@530: * tikhomirov@530: * This program is distributed in the hope that it will be useful, tikhomirov@530: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@530: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@530: * GNU General Public License for more details. tikhomirov@530: * tikhomirov@530: * For information on how to redistribute this software under tikhomirov@530: * the terms of a license other than GNU General Public License tikhomirov@530: * contact TMate Software at support@hg4j.com tikhomirov@530: */ tikhomirov@530: package org.tmatesoft.hg.internal; tikhomirov@530: tikhomirov@530: import java.io.IOException; tikhomirov@530: import java.io.OutputStream; tikhomirov@530: import java.util.zip.Deflater; tikhomirov@530: import java.util.zip.DeflaterOutputStream; tikhomirov@530: tikhomirov@530: /** tikhomirov@530: * tikhomirov@530: * @author Artem Tikhomirov tikhomirov@530: * @author TMate Software Ltd. tikhomirov@530: */ tikhomirov@530: public class RevlogCompressor { tikhomirov@530: private final Deflater zip; tikhomirov@530: private byte[] sourceData; tikhomirov@530: private int compressedLenEstimate; tikhomirov@530: tikhomirov@530: public RevlogCompressor() { tikhomirov@530: zip = new Deflater(); tikhomirov@530: } tikhomirov@530: tikhomirov@530: public void reset(byte[] source) { tikhomirov@530: sourceData = source; tikhomirov@530: compressedLenEstimate = -1; tikhomirov@530: } tikhomirov@530: tikhomirov@530: public int writeCompressedData(OutputStream out) throws IOException { tikhomirov@530: zip.reset(); tikhomirov@530: DeflaterOutputStream dos = new DeflaterOutputStream(out, zip, Math.min(2048, sourceData.length)); tikhomirov@530: dos.write(sourceData); tikhomirov@530: dos.finish(); tikhomirov@530: return zip.getTotalOut(); tikhomirov@530: } tikhomirov@530: tikhomirov@530: public int getCompressedLengthEstimate() { tikhomirov@530: if (compressedLenEstimate != -1) { tikhomirov@530: return compressedLenEstimate; tikhomirov@530: } tikhomirov@530: zip.reset(); tikhomirov@530: int rv = 0; tikhomirov@530: // from DeflaterOutputStream: tikhomirov@530: byte[] buffer = new byte[Math.min(2048, sourceData.length)]; tikhomirov@530: for (int i = 0, stride = buffer.length; i < sourceData.length; i+= stride) { tikhomirov@530: zip.setInput(sourceData, i, Math.min(stride, sourceData.length - i)); tikhomirov@530: while (!zip.needsInput()) { tikhomirov@530: rv += zip.deflate(buffer, 0, buffer.length); tikhomirov@530: } tikhomirov@530: } tikhomirov@530: zip.finish(); tikhomirov@530: while (!zip.finished()) { tikhomirov@530: rv += zip.deflate(buffer, 0, buffer.length); tikhomirov@530: } tikhomirov@530: return compressedLenEstimate = rv; tikhomirov@530: } tikhomirov@530: }