Author: toad
Date: 2008-11-08 00:14:36 +0000 (Sat, 08 Nov 2008)
New Revision: 23400

Modified:
   trunk/freenet/src/freenet/client/async/SingleFileInserter.java
   trunk/freenet/src/freenet/keys/Key.java
   trunk/freenet/src/freenet/support/compress/Bzip2Compressor.java
   trunk/freenet/src/freenet/support/compress/Compressor.java
   trunk/freenet/src/freenet/support/compress/GzipCompressor.java
   trunk/freenet/src/freenet/support/compress/LZMACompressor.java
Log:
Limit the number of bytes read and written separately. Fixes us always using 
gzip.


Modified: trunk/freenet/src/freenet/client/async/SingleFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileInserter.java      
2008-11-08 00:12:08 UTC (rev 23399)
+++ trunk/freenet/src/freenet/client/async/SingleFileInserter.java      
2008-11-08 00:14:36 UTC (rev 23400)
@@ -147,7 +147,7 @@
                                        // Only produce if we are compressing 
*the original data*
                                        if(parent == cb)
                                                
ctx.eventProducer.produceEvent(new StartedCompressionEvent(comp));
-                                       result = comp.compress(origData, new 
BucketChainBucketFactory(ctx.persistentBucketFactory, CHKBlock.DATA_LENGTH), 
bestCompressedDataSize);
+                                       result = comp.compress(origData, new 
BucketChainBucketFactory(ctx.persistentBucketFactory, CHKBlock.DATA_LENGTH), 
origSize, bestCompressedDataSize);
                                        long resultSize = result.size();
                                        if(resultSize < oneBlockCompressedSize) 
{
                                                bestCodec = comp;

Modified: trunk/freenet/src/freenet/keys/Key.java
===================================================================
--- trunk/freenet/src/freenet/keys/Key.java     2008-11-08 00:12:08 UTC (rev 
23399)
+++ trunk/freenet/src/freenet/keys/Key.java     2008-11-08 00:14:36 UTC (rev 
23400)
@@ -188,7 +188,7 @@
                                                ArrayBucket compressedData;
                                                try {
                                                        compressedData = 
(ArrayBucket) comp.compress(
-                                                                       
sourceData, new ArrayBucketFactory(), maxCompressedDataLength);
+                                                                       
sourceData, new ArrayBucketFactory(), Long.MAX_VALUE, maxCompressedDataLength);
                                                } catch (IOException e) {
                                                        throw new Error(e);
                                                } catch 
(CompressionOutputSizeException e) {

Modified: trunk/freenet/src/freenet/support/compress/Bzip2Compressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/Bzip2Compressor.java     
2008-11-08 00:12:08 UTC (rev 23399)
+++ trunk/freenet/src/freenet/support/compress/Bzip2Compressor.java     
2008-11-08 00:14:36 UTC (rev 23400)
@@ -12,36 +12,38 @@
 import freenet.support.Logger;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
+import freenet.support.io.CountedOutputStream;
+
 import org.apache.tools.bzip2.CBZip2InputStream;
 import org.apache.tools.bzip2.CBZip2OutputStream;

 public class Bzip2Compressor implements Compressor {

-       public Bucket compress(Bucket data, BucketFactory bf, long maxLength) 
throws IOException, CompressionOutputSizeException {
-               if(maxLength <= 0)
+       public Bucket compress(Bucket data, BucketFactory bf, long 
maxReadLength, long maxWriteLength) throws IOException, 
CompressionOutputSizeException {
+               if(maxReadLength <= 0)
                        throw new IllegalArgumentException();
-               Bucket output = bf.makeBucket(maxLength);
+               Bucket output = bf.makeBucket(maxWriteLength);
                InputStream is = null;
                OutputStream os = null;
                CBZip2OutputStream bz2os = null;
                try {
                        is = data.getInputStream();
                        os = output.getOutputStream();
-                       bz2os = new CBZip2OutputStream(os);
-                       long written = 0;
+                       CountedOutputStream cos = new CountedOutputStream(os);
+                       bz2os = new CBZip2OutputStream(cos);
+                       long read = 0;
                        // Bigger input buffer, so can compress all at once.
                        // Won't hurt on I/O either, although most OSs will 
only return a page at a time.
                        byte[] buffer = new byte[32768];
                        while(true) {
-                               int l = (int) Math.min(buffer.length, maxLength 
- written);
-                               int x = is.read(buffer, 0, buffer.length);
-                               if(l < x) {
-                                       throw new 
CompressionOutputSizeException();
-                               }
+                               int l = (int) Math.min(buffer.length, 
maxReadLength - read);
+                               int x = l == 0 ? -1 : is.read(buffer, 0, 
buffer.length);
                                if(x <= -1) break;
                                if(x == 0) throw new IOException("Returned zero 
from read()");
                                bz2os.write(buffer, 0, x);
-                               written += x;
+                               read += x;
+                               if(cos.written() > maxWriteLength)
+                                       throw new 
CompressionOutputSizeException();
                        }
                        bz2os.flush();
                        bz2os.close();

Modified: trunk/freenet/src/freenet/support/compress/Compressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/Compressor.java  2008-11-08 
00:12:08 UTC (rev 23399)
+++ trunk/freenet/src/freenet/support/compress/Compressor.java  2008-11-08 
00:14:36 UTC (rev 23400)
@@ -41,8 +41,8 @@
                        return null;
                }

-               public Bucket compress(Bucket data, BucketFactory bf, long 
maxLength) throws IOException, CompressionOutputSizeException {
-                       return compressor.compress(data, bf, maxLength);
+               public Bucket compress(Bucket data, BucketFactory bf, long 
maxReadLength, long maxWriteLength) throws IOException, 
CompressionOutputSizeException {
+                       return compressor.compress(data, bf, maxReadLength, 
maxWriteLength);
                }

                public Bucket decompress(Bucket data, BucketFactory 
bucketFactory, long maxLength, long maxEstimateSizeLength, Bucket preferred) 
throws IOException, CompressionOutputSizeException {
@@ -81,7 +81,17 @@
                }
        }

-       public abstract Bucket compress(Bucket data, BucketFactory bf, long 
maxLength) throws IOException, CompressionOutputSizeException;
+       /**
+        * Compress the data.
+        * @param data The bucket to read from.
+        * @param bf The means to create a new bucket.
+        * @param maxReadLength The maximum number of bytes to read from the 
input bucket.
+        * @param maxWriteLength The maximum number of bytes to write to the 
output bucket. If this is exceeded, throw a CompressionOutputSizeException.
+        * @return The compressed data.
+        * @throws IOException If an error occurs reading or writing data.
+        * @throws CompressionOutputSizeException If the compressed data is 
larger than maxWriteLength. 
+        */
+       public abstract Bucket compress(Bucket data, BucketFactory bf, long 
maxReadLength, long maxWriteLength) throws IOException, 
CompressionOutputSizeException;

        /**
         * Decompress data.

Modified: trunk/freenet/src/freenet/support/compress/GzipCompressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/GzipCompressor.java      
2008-11-08 00:12:08 UTC (rev 23399)
+++ trunk/freenet/src/freenet/support/compress/GzipCompressor.java      
2008-11-08 00:14:36 UTC (rev 23400)
@@ -11,34 +11,35 @@
 import freenet.support.Logger;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
+import freenet.support.io.CountedOutputStream;

 public class GzipCompressor implements Compressor {

-       public Bucket compress(Bucket data, BucketFactory bf, long maxLength) 
throws IOException, CompressionOutputSizeException {
-               if(maxLength <= 0)
+       public Bucket compress(Bucket data, BucketFactory bf, long 
maxReadLength, long maxWriteLength) throws IOException, 
CompressionOutputSizeException {
+               if(maxReadLength < 0)
                        throw new IllegalArgumentException();
-               Bucket output = bf.makeBucket(maxLength);
+               Bucket output = bf.makeBucket(maxWriteLength);
                InputStream is = null;
                OutputStream os = null;
                GZIPOutputStream gos = null;
                try {
                        is = data.getInputStream();
                        os = output.getOutputStream();
-                       gos = new GZIPOutputStream(os);
-                       long written = 0;
+                       CountedOutputStream cos = new CountedOutputStream(os);
+                       gos = new GZIPOutputStream(cos);
+                       long read = 0;
                        // Bigger input buffer, so can compress all at once.
                        // Won't hurt on I/O either, although most OSs will 
only return a page at a time.
                        byte[] buffer = new byte[32768];
                        while(true) {
-                               int l = (int) Math.min(buffer.length, maxLength 
- written);
-                               int x = is.read(buffer, 0, buffer.length);
-                               if(l < x) {
-                                       throw new 
CompressionOutputSizeException();
-                               }
+                               int l = (int) Math.min(buffer.length, 
maxReadLength - read);
+                               int x = l == 0 ? -1 : is.read(buffer, 0, l);
                                if(x <= -1) break;
                                if(x == 0) throw new IOException("Returned zero 
from read()");
                                gos.write(buffer, 0, x);
-                               written += x;
+                               read += x;
+                               if(cos.written() > maxWriteLength)
+                                       throw new 
CompressionOutputSizeException();
                        }
                        gos.flush();
                } finally {

Modified: trunk/freenet/src/freenet/support/compress/LZMACompressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/LZMACompressor.java      
2008-11-08 00:12:08 UTC (rev 23399)
+++ trunk/freenet/src/freenet/support/compress/LZMACompressor.java      
2008-11-08 00:14:36 UTC (rev 23400)
@@ -12,36 +12,37 @@
 import freenet.support.Logger;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
+import freenet.support.io.CountedOutputStream;
 import net.contrapunctus.lzma.LzmaInputStream;
 import net.contrapunctus.lzma.LzmaOutputStream;

 public class LZMACompressor implements Compressor {

-       public Bucket compress(Bucket data, BucketFactory bf, long maxLength) 
throws IOException, CompressionOutputSizeException {
-               if(maxLength <= 0)
+       public Bucket compress(Bucket data, BucketFactory bf, long 
maxReadLength, long maxWriteLength) throws IOException, 
CompressionOutputSizeException {
+               if(maxReadLength <= 0)
                        throw new IllegalArgumentException();
-               Bucket output = bf.makeBucket(maxLength);
+               Bucket output = bf.makeBucket(maxWriteLength);
                InputStream is = null;
                OutputStream os = null;
                LzmaOutputStream lzmaOS = null;
                try {
                        is = data.getInputStream();
                        os = output.getOutputStream();
-                       lzmaOS = new LzmaOutputStream(os);
-                       long written = 0;
+                       CountedOutputStream cos = new CountedOutputStream(os);
+                       lzmaOS = new LzmaOutputStream(cos);
+                       long read = 0;
                        // Bigger input buffer, so can compress all at once.
                        // Won't hurt on I/O either, although most OSs will 
only return a page at a time.
                        byte[] buffer = new byte[32768];
                        while(true) {
-                               int l = (int) Math.min(buffer.length, maxLength 
- written);
-                               int x = is.read(buffer, 0, buffer.length);
-                               if(l < x) {
-                                       throw new 
CompressionOutputSizeException();
-                               }
+                               int l = (int) Math.min(buffer.length, 
maxReadLength - read);
+                               int x = l == 0 ? -1 : is.read(buffer, 0, 
buffer.length);
                                if(x <= -1) break;
                                if(x == 0) throw new IOException("Returned zero 
from read()");
                                lzmaOS.write(buffer, 0, x);
-                               written += x;
+                               read += x;
+                               if(cos.written() > maxWriteLength)
+                                       throw new 
CompressionOutputSizeException();
                        }
                        lzmaOS.flush();
                        os = null;


Reply via email to