Author: toad
Date: 2006-07-13 00:20:11 +0000 (Thu, 13 Jul 2006)
New Revision: 9587

Added:
   
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
   trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java
Modified:
   trunk/freenet/src/freenet/client/FetchWaiter.java
   trunk/freenet/src/freenet/client/HighLevelSimpleClient.java
   trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
   trunk/freenet/src/freenet/client/InserterContext.java
   trunk/freenet/src/freenet/client/PutWaiter.java
   trunk/freenet/src/freenet/client/async/BaseClientPutter.java
   trunk/freenet/src/freenet/client/async/ClientCallback.java
   trunk/freenet/src/freenet/client/async/ClientPutState.java
   trunk/freenet/src/freenet/client/async/ClientPutter.java
   trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java
   trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
   trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
   trunk/freenet/src/freenet/client/async/SingleFileInserter.java
   trunk/freenet/src/freenet/client/async/SplitFileInserter.java
   trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
   trunk/freenet/src/freenet/client/async/USKInserter.java
   trunk/freenet/src/freenet/clients/http/NinjaSpider.java
   trunk/freenet/src/freenet/clients/http/Spider.java
   trunk/freenet/src/freenet/node/ARKFetcher.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/node/fcp/ClientGet.java
   trunk/freenet/src/freenet/node/fcp/ClientPut.java
   trunk/freenet/src/freenet/node/fcp/ClientPutBase.java
   trunk/freenet/src/freenet/node/fcp/ClientRequest.java
   trunk/freenet/src/freenet/node/fcp/FCPClient.java
   trunk/freenet/src/freenet/node/fcp/FCPServer.java
   trunk/freenet/src/freenet/node/updater/NodeUpdater.java
   trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
   trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
   trunk/freenet/src/freenet/support/SimpleFieldSet.java
   trunk/freenet/src/freenet/support/io/FileBucket.java
   trunk/freenet/src/freenet/support/io/NullBucket.java
   trunk/freenet/src/freenet/support/io/TempFileBucket.java
Log:
878: Save insert progress to disk (can't restore from it yet). downloads.dat is 
now gzipped (we append .gz to the filename).

Modified: trunk/freenet/src/freenet/client/FetchWaiter.java
===================================================================
--- trunk/freenet/src/freenet/client/FetchWaiter.java   2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/client/FetchWaiter.java   2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -49,4 +49,8 @@
                if(error != null) throw error;
                return result;
        }
+
+       public void onMajorProgress() {
+               // Ignore
+       }
 }

Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClient.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClient.java 2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClient.java 2006-07-13 
00:20:11 UTC (rev 9587)
@@ -46,7 +46,12 @@

        public FetcherContext getFetcherContext();

-       public InserterContext getInserterContext();
+       /**
+        * Get an InserterContext.
+        * @param forceNonPersistent If true, force the request to use the 
non-persistent
+        * bucket pool.
+        */
+       public InserterContext getInserterContext(boolean forceNonPersistent);

        /**
         * Add a ClientEventListener.

Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2006-07-13 00:20:11 UTC (rev 9587)
@@ -23,6 +23,7 @@
        private final ArchiveManager archiveManager;
        private final short priorityClass;
        private final BucketFactory bucketFactory;
+       private final BucketFactory persistentBucketFactory;
        private final Node node;
        /** One CEP for all requests and inserts */
        private final ClientEventProducer globalEventProducer;
@@ -77,6 +78,7 @@
                curMaxTempLength = Long.MAX_VALUE;
                curMaxMetadataLength = 1024 * 1024;
                this.cacheLocalRequests = cacheLocalRequests;
+               this.persistentBucketFactory = 
node.persistentEncryptedTempBucketFactory;
        }

        public void setMaxLength(long maxLength) {
@@ -113,7 +115,7 @@
        }

        public FreenetURI insert(InsertBlock insert, boolean getCHKOnly, 
boolean isMetadata) throws InserterException {
-               InserterContext context = getInserterContext();
+               InserterContext context = getInserterContext(true);
                PutWaiter pw = new PutWaiter();
                ClientPutter put = new ClientPutter(pw, insert.data, 
insert.desiredURI, insert.clientMetadata, 
                                context, node.chkPutScheduler, 
node.sskPutScheduler, priorityClass, getCHKOnly, isMetadata, this);
@@ -141,7 +143,7 @@
        public FreenetURI insertManifest(FreenetURI insertURI, HashMap 
bucketsByName, String defaultName) throws InserterException {
                PutWaiter pw = new PutWaiter();
                SimpleManifestPutter putter =
-                       new SimpleManifestPutter(pw, node.chkPutScheduler, 
node.sskPutScheduler, 
SimpleManifestPutter.bucketsByNameToManifestEntries(bucketsByName), 
priorityClass, insertURI, defaultName, getInserterContext(), false, this);
+                       new SimpleManifestPutter(pw, node.chkPutScheduler, 
node.sskPutScheduler, 
SimpleManifestPutter.bucketsByNameToManifestEntries(bucketsByName), 
priorityClass, insertURI, defaultName, getInserterContext(true), false, this);
                putter.start();
                return pw.waitForCompletion();
        }
@@ -171,8 +173,8 @@
                                cacheLocalRequests, node.uskManager);
        }

-       public InserterContext getInserterContext() {
-               return new InserterContext(bucketFactory, random, 
INSERT_RETRIES, CONSECUTIVE_RNFS_ASSUME_SUCCESS,
+       public InserterContext getInserterContext(boolean forceNonPersistent) {
+               return new InserterContext(bucketFactory, forceNonPersistent ? 
bucketFactory : persistentBucketFactory, random, INSERT_RETRIES, 
CONSECUTIVE_RNFS_ASSUME_SUCCESS,
                                SPLITFILE_INSERT_THREADS, 
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT, 
                                globalEventProducer, cacheLocalRequests, 
node.uskManager);
        }

Modified: trunk/freenet/src/freenet/client/InserterContext.java
===================================================================
--- trunk/freenet/src/freenet/client/InserterContext.java       2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/InserterContext.java       2006-07-13 
00:20:11 UTC (rev 9587)
@@ -10,6 +10,7 @@
 public class InserterContext {

        public final BucketFactory bf;
+       public final BucketFactory persistentBucketFactory;
        /** If true, don't try to compress the data */
        public boolean dontCompress;
        public final RandomSource random;
@@ -24,10 +25,11 @@
        public final boolean cacheLocalRequests;
        public final USKManager uskManager;

-       public InserterContext(BucketFactory bf, RandomSource random,
+       public InserterContext(BucketFactory bf, BucketFactory persistentBF, 
RandomSource random,
                        int maxRetries, int rnfsToSuccess, int maxThreads, int 
splitfileSegmentDataBlocks, int splitfileSegmentCheckBlocks,
                        ClientEventProducer eventProducer, boolean 
cacheLocalRequests, USKManager uskManager) {
                this.bf = bf;
+               this.persistentBucketFactory = persistentBF;
                this.uskManager = uskManager;
                this.random = random;
                dontCompress = false;
@@ -41,9 +43,10 @@
                this.cacheLocalRequests = cacheLocalRequests;
        }

-       public InserterContext(InserterContext ctx) {
+       public InserterContext(InserterContext ctx, SimpleEventProducer 
producer, boolean forceNonPersistent) {
                this.uskManager = ctx.uskManager;
                this.bf = ctx.bf;
+               this.persistentBucketFactory = forceNonPersistent ? ctx.bf : 
ctx.persistentBucketFactory;
                this.random = ctx.random;
                this.dontCompress = ctx.dontCompress;
                this.splitfileAlgorithm = ctx.splitfileAlgorithm;
@@ -59,6 +62,7 @@
        public InserterContext(InserterContext ctx, SimpleEventProducer 
producer) {
                this.uskManager = ctx.uskManager;
                this.bf = ctx.bf;
+               this.persistentBucketFactory = ctx.persistentBucketFactory;
                this.random = ctx.random;
                this.dontCompress = ctx.dontCompress;
                this.splitfileAlgorithm = ctx.splitfileAlgorithm;

Modified: trunk/freenet/src/freenet/client/PutWaiter.java
===================================================================
--- trunk/freenet/src/freenet/client/PutWaiter.java     2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/client/PutWaiter.java     2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -58,4 +58,8 @@
                throw new InserterException(InserterException.INTERNAL_ERROR, 
"Did not succeed but no error", uri);
        }

+       public void onMajorProgress() {
+               // Ignore
+       }
+
 }

Modified: trunk/freenet/src/freenet/client/async/BaseClientPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/BaseClientPutter.java        
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/BaseClientPutter.java        
2006-07-13 00:20:11 UTC (rev 9587)
@@ -6,4 +6,6 @@
                super(priorityClass, chkScheduler, sskScheduler, context);
        }

+       public abstract void onMajorProgress();
+       
 }

Modified: trunk/freenet/src/freenet/client/async/ClientCallback.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientCallback.java  2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/ClientCallback.java  2006-07-13 
00:20:11 UTC (rev 9587)
@@ -22,4 +22,7 @@

        public void onGeneratedURI(FreenetURI uri, BaseClientPutter state);

+       /** Called when freenet.async thinks that the request should be 
serialized to
+        * disk, if it is a persistent request. */
+       public void onMajorProgress();
 }

Modified: trunk/freenet/src/freenet/client/async/ClientPutState.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientPutState.java  2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/ClientPutState.java  2006-07-13 
00:20:11 UTC (rev 9587)
@@ -1,6 +1,7 @@
 package freenet.client.async;

 import freenet.client.InserterException;
+import freenet.support.SimpleFieldSet;

 /**
  * ClientPutState
@@ -9,11 +10,22 @@
  */
 public interface ClientPutState {

+       /** Get the BaseClientPutter responsible for this request state. */
        public abstract BaseClientPutter getParent();

+       /** Cancel the request. */
        public abstract void cancel();

+       /** Schedule the request. */
        public abstract void schedule() throws InserterException;

+       /**
+        * Get the token, an object which is passed around with the insert and 
may be
+        * used by callers.
+        */
        public Object getToken();
+
+       /** Serialize current progress to a SimpleFieldSet.
+        * Does not have to be complete! */
+       public abstract SimpleFieldSet getProgressFieldset();
 }

Modified: trunk/freenet/src/freenet/client/async/ClientPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientPutter.java    2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/ClientPutter.java    2006-07-13 
00:20:11 UTC (rev 9587)
@@ -10,6 +10,7 @@
 import freenet.keys.FreenetURI;
 import freenet.support.Bucket;
 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;

 public class ClientPutter extends BaseClientPutter implements 
PutCompletionCallback {

@@ -51,14 +52,18 @@
                this.cancelled = false;
        }

-       public synchronized void start() throws InserterException {
+       public void start() throws InserterException {
                try {
-                       currentState =
-                               new SingleFileInserter(this, this, new 
InsertBlock(data, cm, targetURI), isMetadata, ctx, false, getCHKOnly, false, 
null, false);
+                       synchronized(this) {
+                               currentState =
+                                       new SingleFileInserter(this, this, new 
InsertBlock(data, cm, targetURI), isMetadata, ctx, false, getCHKOnly, false, 
null, false);
+                       }
                        ((SingleFileInserter)currentState).start();
                } catch (InserterException e) {
-                       finished = true;
-                       currentState = null;
+                       synchronized(this) {
+                               finished = true;
+                               currentState = null;
+                       }
                        // notify the client that the insert could not even be 
started
                        if (this.client!=null) {
                                this.client.onFailure(e, this);
@@ -66,18 +71,26 @@
                }
        }

-       public synchronized void onSuccess(ClientPutState state) {
-               finished = true;
-               currentState = null;
+       public void onSuccess(ClientPutState state) {
+               synchronized(this) {
+                       finished = true;
+                       currentState = null;
+               }
                client.onSuccess(this);
        }

-       public synchronized void onFailure(InserterException e, ClientPutState 
state) {
-               finished = true;
-               currentState = null;
+       public void onFailure(InserterException e, ClientPutState state) {
+               synchronized(this) {
+                       finished = true;
+                       currentState = null;
+               }
                client.onFailure(e, this);
        }

+       public void onMajorProgress() {
+               client.onMajorProgress();
+       }
+       
        public void onEncode(BaseClientKey key, ClientPutState state) {
                this.uri = key.getURI();
                client.onGeneratedURI(uri, this);
@@ -116,5 +129,9 @@
                Logger.minor(this, "Set finished", new Exception("debug"));
                blockSetFinalized();
        }
+
+       public SimpleFieldSet getProgressFieldset() {
+               return currentState.getProgressFieldset();
+       }

 }

Modified: trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java
===================================================================
--- trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java      
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/MultiPutCompletionCallback.java      
2006-07-13 00:20:11 UTC (rev 9587)
@@ -7,6 +7,7 @@
 import freenet.client.Metadata;
 import freenet.keys.BaseClientKey;
 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;

 public class MultiPutCompletionCallback implements PutCompletionCallback, 
ClientPutState {

@@ -147,4 +148,8 @@
                return token;
        }

+       public SimpleFieldSet getProgressFieldset() {
+               return null;
+       }
+
 }

Modified: trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java    
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java    
2006-07-13 00:20:11 UTC (rev 9587)
@@ -160,6 +160,10 @@
                        }
                        SimpleManifestPutter.this.blockSetFinalized();
                }
+
+               public void onMajorProgress() {
+                       SimpleManifestPutter.this.onMajorProgress();
+               }
        }

        private final HashMap putHandlersByName;
@@ -659,4 +663,8 @@
        public long totalSize() {
                return totalSize;
        }
+
+       public void onMajorProgress() {
+               cb.onMajorProgress();
+       }
 }

Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java     
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java     
2006-07-13 00:20:11 UTC (rev 9587)
@@ -18,6 +18,7 @@
 import freenet.node.Node;
 import freenet.support.Bucket;
 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;

 /**
  * Insert *ONE KEY*.
@@ -284,4 +285,8 @@
                return tokenObject;
        }

+       public SimpleFieldSet getProgressFieldset() {
+               return null;
+       }
+
 }

Modified: trunk/freenet/src/freenet/client/async/SingleFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileInserter.java      
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/SingleFileInserter.java      
2006-07-13 00:20:11 UTC (rev 9587)
@@ -18,6 +18,7 @@
 import freenet.support.Bucket;
 import freenet.support.BucketTools;
 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;
 import freenet.support.compress.CompressionOutputSizeException;
 import freenet.support.compress.Compressor;

@@ -125,7 +126,7 @@
                                                
ctx.eventProducer.produceEvent(new StartedCompressionEvent(i));
                                        Compressor comp = 
Compressor.getCompressionAlgorithmByDifficulty(i);
                                        Bucket result;
-                                       result = comp.compress(origData, 
ctx.bf, Long.MAX_VALUE);
+                                       result = comp.compress(origData, 
ctx.persistentBucketFactory, Long.MAX_VALUE);
                                        if(result.size() < blockSize) {
                                                bestCodec = comp;
                                                data = result;
@@ -387,6 +388,16 @@
                public Object getToken() {
                        return token;
                }
+
+               public synchronized SimpleFieldSet getProgressFieldset() {
+                       SimpleFieldSet fs = new SimpleFieldSet(true);
+                       fs.put("Type", "SplitHandler");
+                       if(sfi != null)
+                               fs.put("SplitFileInserter", 
sfi.getProgressFieldset());
+                       if(metadataPutter != null)
+                               fs.put("MetadataPutter", 
metadataPutter.getProgressFieldset());
+                       return fs;
+               }

        }

@@ -404,4 +415,8 @@
        public Object getToken() {
                return token;
        }
+
+       public SimpleFieldSet getProgressFieldset() {
+               return null;
+       }
 }

Modified: trunk/freenet/src/freenet/client/async/SplitFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserter.java       
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserter.java       
2006-07-13 00:20:11 UTC (rev 9587)
@@ -14,6 +14,7 @@
 import freenet.support.Bucket;
 import freenet.support.BucketTools;
 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;
 import freenet.support.compress.Compressor;

 public class SplitFileInserter implements ClientPutState {
@@ -37,6 +38,23 @@
        public final Object token;
        final boolean insertAsArchiveManifest;

+       public SimpleFieldSet getProgressFieldset() {
+               SimpleFieldSet fs = new SimpleFieldSet(true);
+               // don't save basic infrastructure such as ctx and parent
+               // only save details of the request
+               fs.put("Type", "SplitFileInserter");
+               fs.put("DataLength", Long.toString(dataLength));
+               fs.put("CompressionCodec", Short.toString(compressionCodec));
+               fs.put("Finished", Boolean.toString(finished));
+               SimpleFieldSet segs = new SimpleFieldSet(true);
+               for(int i=0;i<segments.length;i++) {
+                       segs.put(Integer.toString(i), 
segments[i].getProgressFieldset());
+               }
+               segs.put("Count", Integer.toString(segments.length));
+               fs.put("Segments", segs);
+               return fs;
+       }
+
        public SplitFileInserter(BaseClientPutter put, PutCompletionCallback 
cb, Bucket data, Compressor bestCodec, ClientMetadata clientMetadata, 
InserterContext ctx, boolean getCHKOnly, boolean isMetadata, Object token, 
boolean insertAsArchiveManifest) throws InserterException {
                this.parent = put;
                this.insertAsArchiveManifest = insertAsArchiveManifest;
@@ -49,7 +67,7 @@
                this.ctx = ctx;
                Bucket[] dataBuckets;
                try {
-                       dataBuckets = BucketTools.split(data, 
CHKBlock.DATA_LENGTH, ctx.bf);
+                       dataBuckets = BucketTools.split(data, 
CHKBlock.DATA_LENGTH, ctx.persistentBucketFactory);
                } catch (IOException e) {
                        throw new 
InserterException(InserterException.BUCKET_ERROR, e, null);
                }
@@ -111,6 +129,8 @@
        public void start() throws InserterException {
                for(int i=0;i<segments.length;i++)
                        segments[i].start();
+               if(countDataBlocks > 32)
+                       parent.onMajorProgress();
        }

        public void encodedSegment(SplitFileInserterSegment segment) {
@@ -122,6 +142,8 @@
                        }
                }
                cb.onBlockSetFinished(this);
+               if(countDataBlocks > 32)
+                       parent.onMajorProgress();
        }

        public void segmentHasURIs(SplitFileInserterSegment segment) {
@@ -223,6 +245,8 @@
        public void segmentFinished(SplitFileInserterSegment segment) {
                Logger.minor(this, "Segment finished: "+segment);
                boolean allGone = true;
+               if(countDataBlocks > 32)
+                       parent.onMajorProgress();
                synchronized(this) {
                        if(finished) return;
                        for(int i=0;i<segments.length;i++)

Modified: trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java        
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java        
2006-07-13 00:20:11 UTC (rev 9587)
@@ -11,7 +11,12 @@
 import freenet.keys.CHKBlock;
 import freenet.keys.FreenetURI;
 import freenet.support.Bucket;
+import freenet.support.HexUtil;
 import freenet.support.Logger;
+import freenet.support.PaddedEphemerallyEncryptedBucket;
+import freenet.support.SimpleFieldSet;
+import freenet.support.io.FileBucket;
+import freenet.support.io.SerializableToFieldSetBucket;

 public class SplitFileInserterSegment implements PutCompletionCallback {

@@ -33,6 +38,7 @@
        private final FailureCodeTracker errors;
        private int blocksGotURI;
        private int blocksCompleted;
+       private boolean started;

        public SplitFileInserterSegment(SplitFileInserter parent, FECCodec 
splitfileAlgo, Bucket[] origDataBlocks, InserterContext blockInsertContext, 
boolean getCHKOnly, int segNo) {
                this.parent = parent;
@@ -52,12 +58,84 @@
                this.segNo = segNo;
        }

+       public synchronized SimpleFieldSet getProgressFieldset() {
+               SimpleFieldSet fs = new SimpleFieldSet(true);
+               fs.put("Type", "SplitFileInserterSegment");
+               fs.put("Finished", Boolean.toString(finished));
+               // If true, check blocks which are null are finished 
+               fs.put("Encoded", Boolean.toString(encoded));
+               // If true, data blocks which are null are finished
+               fs.put("Started", Boolean.toString(started));
+               errors.copyToFieldSet(fs, "Errors.", false);
+               SimpleFieldSet dataFS = new SimpleFieldSet(true);
+               dataFS.put("Count", Integer.toString(dataBlocks.length));
+               for(int i=0;i<dataBlocks.length;i++) {
+                       SimpleFieldSet block = new SimpleFieldSet(true);
+                       if(dataURIs[i] != null)
+                               block.put("URI", dataURIs[i].toString());
+                       SingleBlockInserter sbi =
+                               dataBlockInserters[i];
+                       // If started, then sbi = null => block finished.
+                       boolean finished = started && sbi == null;
+                       if(started) {
+                               block.put("Finished", finished);
+                       }
+                       if(finished) continue;
+                       if(!finished) {
+                               Bucket data = dataBlocks[i];
+                               if(data instanceof 
SerializableToFieldSetBucket) {
+                                       SimpleFieldSet tmp = 
((SerializableToFieldSetBucket)data).toFieldSet();
+                                       if(tmp == null) {
+                                               Logger.minor(this, "Could not 
save to disk: "+data);
+                                               return null;
+                                       }
+                                       block.put("Data", tmp);
+                               } else {
+                                       Logger.minor(this, "Could not save to 
disk (not serializable to fieldset): "+data);
+                                       return null;
+                               }
+                       }
+                       if(!block.isEmpty())
+                               dataFS.put(Integer.toString(i), block);
+               }
+               fs.put("DataBlocks", dataFS);
+               SimpleFieldSet checkFS = new SimpleFieldSet(true);
+               checkFS.put("Count", Integer.toString(dataBlocks.length));
+               for(int i=0;i<checkBlocks.length;i++) {
+                       SimpleFieldSet block = new SimpleFieldSet(true);
+                       if(checkURIs[i] != null)
+                               block.put("URI", checkURIs[i].toString());
+                       SingleBlockInserter sbi =
+                               checkBlockInserters[i];
+                       // If encoded, then sbi == null => block finished
+                       boolean finished = encoded && sbi == null;
+                       if(encoded) {
+                               block.put("Finished", finished);
+                       }
+                       if(!finished) {
+                               Bucket data = checkBlocks[i];
+                               if(data != null &&
+                                               data instanceof 
SerializableToFieldSetBucket) {
+                                       block.put("Data", 
((SerializableToFieldSetBucket)data).toFieldSet());
+                               } else if(encoded) {
+                                       Logger.minor(this, "Could not save to 
disk (null or not serializable to fieldset): "+data);
+                                       return null;
+                               }
+                       }
+                       if(!block.isEmpty())
+                               checkFS.put(Integer.toString(i), block);
+               }
+               fs.put("CheckBlocks", checkFS);
+               return fs;
+       }
+       
        public void start() throws InserterException {
                for(int i=0;i<dataBlockInserters.length;i++) {
                        dataBlockInserters[i] = 
                                new SingleBlockInserter(parent.parent, 
dataBlocks[i], (short)-1, FreenetURI.EMPTY_CHK_URI, blockInsertContext, this, 
false, CHKBlock.DATA_LENGTH, i, getCHKOnly, false, false, parent.token);
                        dataBlockInserters[i].schedule();
                }
+               started = true;
                if(splitfileAlgo != null) {
                        // Encode blocks
                        Thread t = new Thread(new EncodeBlocksRunnable(), 
"Blocks encoder");
@@ -75,7 +153,7 @@

        void encode() {
                try {
-                       splitfileAlgo.encode(dataBlocks, checkBlocks, 
CHKBlock.DATA_LENGTH, blockInsertContext.bf);
+                       splitfileAlgo.encode(dataBlocks, checkBlocks, 
CHKBlock.DATA_LENGTH, blockInsertContext.persistentBucketFactory);
                        // Start the inserts
                        for(int i=0;i<checkBlockInserters.length;i++) {
                                checkBlockInserters[i] = 

Modified: trunk/freenet/src/freenet/client/async/USKInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKInserter.java     2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/client/async/USKInserter.java     2006-07-13 
00:20:11 UTC (rev 9587)
@@ -14,6 +14,7 @@
 import freenet.support.Bucket;
 import freenet.support.BucketTools;
 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;

 /**
  * Insert a USK. The algorithm is simply to do a thorough search for the 
latest edition, and insert at the
@@ -216,4 +217,8 @@
                return tokenObject;
        }

+       public SimpleFieldSet getProgressFieldset() {
+               return null;
+       }
+
 }

Modified: trunk/freenet/src/freenet/clients/http/NinjaSpider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/NinjaSpider.java     2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/clients/http/NinjaSpider.java     2006-07-13 
00:20:11 UTC (rev 9587)
@@ -737,6 +737,10 @@
                }
        }

+       public void onMajorProgress() {
+               // Ignore
+       }


+
 }

Modified: trunk/freenet/src/freenet/clients/http/Spider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Spider.java  2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/clients/http/Spider.java  2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -471,4 +471,8 @@
                }
        }

+       public void onMajorProgress() {
+               // Ignore
+       }
+
 }

Modified: trunk/freenet/src/freenet/node/ARKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/node/ARKFetcher.java      2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/node/ARKFetcher.java      2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -249,4 +249,8 @@
        private synchronized long getStartedEdition() {
                return startedEdition;
        }
+
+       public void onMajorProgress() {
+               // Ignore
+       }
 }

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-07-12 20:50:23 UTC (rev 
9586)
+++ trunk/freenet/src/freenet/node/Node.java    2006-07-13 00:20:11 UTC (rev 
9587)
@@ -122,6 +122,7 @@
 import freenet.support.SimpleReadOnlyArrayBucket;
 import freenet.support.TokenBucket;
 import freenet.support.io.FilenameGenerator;
+import freenet.support.io.PersistentEncryptedTempBucketFactory;
 import freenet.support.io.PersistentTempBucketFactory;
 import freenet.support.io.TempBucketFactory;
 import freenet.support.math.BootstrappingDecayingRunningAverage;
@@ -236,7 +237,7 @@

                        inserter = new ClientPutter(this, b, uri,
                                                new 
ClientMetadata("text/plain") /* it won't quite fit in an SSK anyway */, 
-                                               
Node.this.makeClient((short)0).getInserterContext(),
+                                               
Node.this.makeClient((short)0).getInserterContext(true),
                                                chkPutScheduler, 
sskPutScheduler, RequestStarter.INTERACTIVE_PRIORITY_CLASS, false, false, this);

                        try {
@@ -339,6 +340,10 @@

                        startInserter();
                }
+
+               public void onMajorProgress() {
+                       // Ignore
+               }

        }

@@ -675,6 +680,7 @@

        // Persistent temporary buckets
        public final PersistentTempBucketFactory persistentTempBucketFactory;
+       public final PersistentEncryptedTempBucketFactory 
persistentEncryptedTempBucketFactory;

        // Things that's needed to keep track of
        public final PluginManager pluginManager;
@@ -1451,6 +1457,7 @@
                });
                try {
                        persistentTempBucketFactory = new 
PersistentTempBucketFactory(new 
File(nodeConfig.getString("persistentTempDir")), "freenet-temp-", random);
+                       persistentEncryptedTempBucketFactory = new 
PersistentEncryptedTempBucketFactory(persistentTempBucketFactory);
                } catch (IOException e2) {
                        String msg = "Could not find or create persistent 
temporary directory";
                        throw new NodeInitException(EXIT_BAD_TEMP_DIR, msg);

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-07-12 20:50:23 UTC (rev 
9586)
+++ trunk/freenet/src/freenet/node/Version.java 2006-07-13 00:20:11 UTC (rev 
9587)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 877;
+       private static final int buildNumber = 878;

        /** Oldest build of Fred we will talk to */
        private static final int oldLastGoodBuild = 870;

Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -374,6 +374,8 @@
                Logger.minor(this, "Caught "+e, e);
                trySendDataFoundOrGetFailed(null);
                finish();
+               if(persistenceType != PERSIST_CONNECTION)
+                       client.server.forceStorePersistentRequests();
        }

        public void onSuccess(BaseClientPutter state) {

Modified: trunk/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -171,7 +171,6 @@
        public synchronized SimpleFieldSet getFieldSet() {
                SimpleFieldSet fs = super.getFieldSet();
                fs.put("Metadata.ContentType", clientMetadata.getMIMEType());
-               fs.put("GetCHKOnly", Boolean.toString(getCHKOnly));
                fs.put("UploadFrom", 
ClientPutMessage.uploadFromString(uploadFrom));
                if(uploadFrom == ClientPutMessage.UPLOAD_FROM_DISK) {
                        fs.put("Filename", origFilename.getPath());
@@ -184,6 +183,10 @@
                } else if(uploadFrom == ClientPutMessage.UPLOAD_FROM_REDIRECT) {
                        fs.put("TargetURI", targetURI.toString());
                }
+               if(inserter != null)  {
+                       SimpleFieldSet sfs = inserter.getProgressFieldset();
+                       fs.put("progress", sfs);
+               }
                return fs;
        }


Modified: trunk/freenet/src/freenet/node/fcp/ClientPutBase.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutBase.java       2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutBase.java       2006-07-13 
00:20:11 UTC (rev 9587)
@@ -53,7 +53,7 @@
                        boolean dontCompress, int maxRetries) {
                super(uri, identifier, verbosity, handler, priorityClass, 
persistenceType, clientToken, global);
                this.getCHKOnly = getCHKOnly;
-               ctx = new InserterContext(client.defaultInsertContext, new 
SimpleEventProducer());
+               ctx = new InserterContext(client.defaultInsertContext, new 
SimpleEventProducer(), persistenceType == ClientRequest.PERSIST_CONNECTION);
                ctx.dontCompress = dontCompress;
                ctx.eventProducer.addEventListener(this);
                ctx.maxInsertRetries = maxRetries;
@@ -94,6 +94,8 @@
                trySendFinalMessage(null);
                freeData();
                finish();
+               if(persistenceType != PERSIST_CONNECTION)
+                       client.server.forceStorePersistentRequests();
        }

        public void onFailure(InserterException e, BaseClientPutter state) {
@@ -104,6 +106,8 @@
                trySendFinalMessage(null);
                freeData();
                finish();
+               if(persistenceType != PERSIST_CONNECTION)
+                       client.server.forceStorePersistentRequests();
        }

        public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {

Modified: trunk/freenet/src/freenet/node/fcp/ClientRequest.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientRequest.java       2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/node/fcp/ClientRequest.java       2006-07-13 
00:20:11 UTC (rev 9587)
@@ -223,6 +223,8 @@
        protected void finish() {
                if(persistenceType == ClientRequest.PERSIST_CONNECTION)
                        origHandler.finishedClientRequest(this);
+               else
+                       client.server.forceStorePersistentRequests();
                client.finishedClientRequest(this);
        }

@@ -259,4 +261,12 @@
         * Has the total number of blocks to insert been determined yet?
         */
        public abstract boolean isTotalFinalized();
+       
+       public void onMajorProgress() {
+               if(persistenceType != ClientRequest.PERSIST_CONNECTION) {
+                       if(client != null)
+                               client.server.forceStorePersistentRequests();
+               }
+       }
+
 }

Modified: trunk/freenet/src/freenet/node/fcp/FCPClient.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPClient.java   2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/node/fcp/FCPClient.java   2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -33,7 +33,7 @@
                this.client = node.makeClient((short)0);
                this.isGlobalQueue = isGlobalQueue;
                defaultFetchContext = client.getFetcherContext();
-               defaultInsertContext = client.getInserterContext();
+               defaultInsertContext = client.getInserterContext(false);
                clientsWatching = new LinkedList();
                watchGlobalVerbosityMask = Integer.MAX_VALUE;
        }

Modified: trunk/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPServer.java   2006-07-12 20:50:23 UTC 
(rev 9586)
+++ trunk/freenet/src/freenet/node/fcp/FCPServer.java   2006-07-13 00:20:11 UTC 
(rev 9587)
@@ -9,6 +9,7 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.net.BindException;
@@ -16,6 +17,8 @@
 import java.util.Iterator;
 import java.util.Vector;
 import java.util.WeakHashMap;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;

 import freenet.client.DefaultMIMETypes;
 import freenet.client.FetcherContext;
@@ -90,7 +93,7 @@
                // will make their own.
                HighLevelSimpleClient client = node.makeClient((short)0);
                defaultFetchContext = client.getFetcherContext();
-               defaultInsertContext = client.getInserterContext();
+               defaultInsertContext = client.getInserterContext(false);


                globalClient = new FCPClient("Global Queue", this, null, true);
@@ -428,6 +431,11 @@

                public void run() {
                        while(true) {
+                               try {
+                                       storePersistentRequests();
+                               } catch (Throwable t) {
+                                       Logger.error(this, "Caught "+t, t);
+                               }
                                synchronized(this) {
                                        if(killed) return;
                                        long startTime = 
System.currentTimeMillis();
@@ -444,11 +452,6 @@
                                        }
                                        storeNow = false;
                                }
-                               try {
-                                       storePersistentRequests();
-                               } catch (Throwable t) {
-                                       Logger.error(this, "Caught "+t, t);
-                               }
                        }
                }

@@ -470,19 +473,22 @@
                Logger.minor(this, "Persistent requests count: 
"+persistentRequests.length);
                synchronized(persistenceSync) {
                        try {
-                               FileOutputStream fos = new 
FileOutputStream(persistentDownloadsTempFile);
+                               File compressedTemp = new 
File(persistentDownloadsTempFile+".gz");
+                               File compressedFinal = new 
File(persistentDownloadsFile.toString()+".gz");
+                               FileOutputStream fos = new 
FileOutputStream(compressedTemp);
                                BufferedOutputStream bos = new 
BufferedOutputStream(fos);
-                               OutputStreamWriter osw = new 
OutputStreamWriter(bos);
+                               GZIPOutputStream gos = new 
GZIPOutputStream(bos);
+                               OutputStreamWriter osw = new 
OutputStreamWriter(gos);
                                BufferedWriter w = new BufferedWriter(osw);
                                
w.write(Integer.toString(persistentRequests.length)+"\n");
                                for(int i=0;i<persistentRequests.length;i++)
                                        persistentRequests[i].write(w);
                                w.close();
-                               
if(!persistentDownloadsTempFile.renameTo(persistentDownloadsFile)) {
+                               if(!compressedTemp.renameTo(compressedFinal)) {
                                        Logger.minor(this, "Rename failed");
-                                       persistentDownloadsFile.delete();
-                                       
if(!persistentDownloadsTempFile.renameTo(persistentDownloadsFile)) {
-                                               Logger.error(this, "Could not 
rename persisted requests temp file "+persistentDownloadsTempFile+" to 
"+persistentDownloadsFile);
+                                       compressedFinal.delete();
+                                       
if(!compressedTemp.renameTo(compressedFinal)) {
+                                               Logger.error(this, "Could not 
rename persisted requests temp file "+persistentDownloadsTempFile+".gz to 
"+persistentDownloadsFile);
                                        }
                                }
                        } catch (IOException e) {
@@ -493,42 +499,58 @@
        }

        private void loadPersistentRequests() {
-               synchronized(persistenceSync) {
-                       FileInputStream fis;
+               FileInputStream fis = null;
+               try {
+                       fis = new 
FileInputStream(persistentDownloadsFile+".gz");
+                       GZIPInputStream gis = new GZIPInputStream(fis);
+                       BufferedInputStream bis = new BufferedInputStream(gis);
+                       loadPersistentRequests(bis);
+               } catch (IOException e) {
+                       if(fis != null) {
+                               try {
+                                       fis.close();
+                               } catch (IOException e1) {
+                                       // Ignore
+                               }
+                               fis = null;
+                       }
                        try {
                                fis = new 
FileInputStream(persistentDownloadsFile);
-                       } catch (FileNotFoundException e) {
-                               Logger.normal(this, "Not reading any persistent 
requests from disk because no file exists");
+                               BufferedInputStream bis = new 
BufferedInputStream(fis);
+                               loadPersistentRequests(bis);
+                       } catch (IOException e1) {
+                               Logger.normal(this, "Not reading any persistent 
requests from disk: "+e1);
                                return;
                        }
-                       try {
-                               BufferedInputStream bis = new 
BufferedInputStream(fis);
-                               InputStreamReader ris = new 
InputStreamReader(bis);
-                               BufferedReader br = new BufferedReader(ris);
-                               String r = br.readLine();
-                               int count;
+               } finally {
+                       if(fis != null) {
                                try {
-                                       count = Integer.parseInt(r);
-                               } catch (NumberFormatException e) {
-                                       Logger.error(this, "Corrupt persistent 
downloads file: "+persistentDownloadsFile);
-                                       return;
-                               }
-                               for(int i=0;i<count;i++) {
-                                       ClientRequest.readAndRegister(br, this);
-                               }
-                       } catch (IOException e) {
-                               Logger.error(this, "Error reading persistent 
downloads file: "+persistentDownloadsFile+" : "+e, e);
-                               return;
-                       } finally {
-                               try {
                                        fis.close();
-                               } catch (IOException e1) {
-                                       Logger.error(this, "Error closing: 
"+e1, e1);
+                               } catch (IOException e) {
+                                       // Ignore
                                }
                        }
-                       return;
                }
        }
+       
+       private void loadPersistentRequests(InputStream is) throws IOException {
+               synchronized(persistenceSync) {
+                       InputStreamReader ris = new InputStreamReader(is);
+                       BufferedReader br = new BufferedReader(ris);
+                       String r = br.readLine();
+                       int count;
+                       try {
+                               count = Integer.parseInt(r);
+                       } catch (NumberFormatException e) {
+                               Logger.error(this, "Corrupt persistent 
downloads file: "+persistentDownloadsFile);
+                               throw new IOException(e.toString());
+                       }
+                       for(int i=0;i<count;i++) {
+                               ClientRequest.readAndRegister(br, this);
+                       }
+                       br.close();
+               }
+       }

        private ClientRequest[] getPersistentRequests() {
                Vector v = new Vector();

Modified: trunk/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdater.java     2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdater.java     2006-07-13 
00:20:11 UTC (rev 9587)
@@ -565,4 +565,8 @@
        public boolean inFinalCheck() {
                return finalCheck;
        }
+
+       public void onMajorProgress() {
+               // Ignore
+       }
 }

Modified: 
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java     
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java     
2006-07-13 00:20:11 UTC (rev 9587)
@@ -10,13 +10,14 @@
 import freenet.crypt.RandomSource;
 import freenet.crypt.UnsupportedCipherException;
 import freenet.crypt.ciphers.Rijndael;
+import freenet.support.io.SerializableToFieldSetBucket;

 /**
  * A proxy Bucket which adds:
  * - Encryption with the supplied cipher, and a random, ephemeral key.
  * - Padding to the next PO2 size.
  */
-public class PaddedEphemerallyEncryptedBucket implements Bucket {
+public class PaddedEphemerallyEncryptedBucket implements Bucket, 
SerializableToFieldSetBucket {

        private final Bucket bucket;
        private final int minPaddedSize;
@@ -295,4 +296,23 @@
                return key;
        }

+       public SimpleFieldSet toFieldSet() {
+               SimpleFieldSet fs = new SimpleFieldSet(true);
+               fs.put("Type", "PaddedEphemerallyEncryptedBucket");
+               fs.put("DataLength", dataLength);
+               if(key != null) {
+                       fs.put("DecryptKey", HexUtil.bytesToHex(key));
+               } else {
+                       Logger.error(this, "Cannot serialize because no key");
+                       return null;
+               }
+               if(bucket instanceof SerializableToFieldSetBucket) {
+                       fs.put("Underlying", 
((SerializableToFieldSetBucket)bucket).toFieldSet());
+               } else {
+                       Logger.error(this, "Cannot serialize underlying bucket: 
"+bucket);
+                       return null;
+               }
+               return fs;
+       }
+
 }

Modified: trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/RandomAccessFileBucket.java       
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/RandomAccessFileBucket.java       
2006-07-13 00:20:11 UTC (rev 9587)
@@ -8,12 +8,14 @@
 import java.io.RandomAccessFile;
 import java.util.Vector;

+import freenet.support.io.SerializableToFieldSetBucket;
+
 /**
  * Bucket implementation that can efficiently access any arbitrary byte-range
  * of a file.
  *
  **/
-public class RandomAccessFileBucket implements Bucket {
+public class RandomAccessFileBucket implements Bucket, 
SerializableToFieldSetBucket {

     public RandomAccessFileBucket(File file, long offset, long len, boolean 
readOnly)
         throws IOException {
@@ -136,7 +138,7 @@
             }
         }
         streams.removeAllElements();
-       streams.trimToSize();
+        streams.trimToSize();
         // We don't delete anything because we don't own anything.
         released = true;
         return true;
@@ -422,7 +424,7 @@
     }
     ////////////////////////////////////////////////////////////

-    private File file = null;
+    private final File file;
     private long offset = -1;
     private long localOffset = 0;
     private long len = -1;
@@ -441,4 +443,13 @@
        public void free() {
                release();
        }
+
+       public SimpleFieldSet toFieldSet() {
+               SimpleFieldSet fs = new SimpleFieldSet(true);
+               fs.put("Type", "RandomAccessFileBucket");
+               fs.put("Filename", file.toString());
+               fs.put("Offset", offset);
+               fs.put("Length", len);
+               return fs;
+       }
 }

Modified: trunk/freenet/src/freenet/support/SimpleFieldSet.java
===================================================================
--- trunk/freenet/src/freenet/support/SimpleFieldSet.java       2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/SimpleFieldSet.java       2006-07-13 
00:20:11 UTC (rev 9587)
@@ -190,6 +190,26 @@
                }
     }

+       public void put(String key, int value) {
+               put(key, Integer.toString(value));
+       }
+       
+       public void put(String key, long value) {
+               put(key, Long.toString(value));
+       }
+       
+       public void put(String key, short value) {
+               put(key, Short.toString(value));
+       }
+       
+       public void put(String key, char c) {
+               put(key, ""+c);
+       }
+       
+       public void put(String key, boolean b) {
+               put(key, Boolean.toString(b));
+       }
+       
     /**
      * Write the contents of the SimpleFieldSet to a Writer.
      * @param osr
@@ -306,6 +326,7 @@
        }

        public void put(String key, SimpleFieldSet fs) {
+               if(fs == null) return; // legal no-op, because used everywhere
                if(fs.isEmpty())
                        throw new IllegalArgumentException("Empty");
                if(!multiLevel)
@@ -387,6 +408,5 @@
                while(i.hasNext()) v.add(i.next());
                return (String[]) v.toArray(new String[v.size()]);
        }
-       

 }

Modified: trunk/freenet/src/freenet/support/io/FileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/FileBucket.java        2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/io/FileBucket.java        2006-07-13 
00:20:11 UTC (rev 9587)
@@ -12,13 +12,14 @@
 import freenet.support.Bucket;
 import freenet.support.Logger;
 import freenet.support.ReadOnlyFileSliceBucket;
+import freenet.support.SimpleFieldSet;

 /**
  * A file Bucket is an implementation of Bucket that writes to a file.
  * 
  * @author oskar
  */
-public class FileBucket implements Bucket {
+public class FileBucket implements Bucket, SerializableToFieldSetBucket {

        protected File file;
        protected boolean readOnly;
@@ -325,4 +326,13 @@
        public String toString() {
                return super.toString()+":"+file.getPath();
        }
+
+       public SimpleFieldSet toFieldSet() {
+               if(deleteOnFinalize) return null;
+               SimpleFieldSet fs = new SimpleFieldSet(true);
+               fs.put("Type", "FileBucket");
+               fs.put("Filename", file.toString());
+               fs.put("Length", length);
+               return fs;
+       }
 }

Modified: trunk/freenet/src/freenet/support/io/NullBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/NullBucket.java        2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/io/NullBucket.java        2006-07-13 
00:20:11 UTC (rev 9587)
@@ -3,8 +3,9 @@
 import java.io.OutputStream;

 import freenet.support.Bucket;
+import freenet.support.SimpleFieldSet;

-public class NullBucket implements Bucket {
+public class NullBucket implements Bucket, SerializableToFieldSetBucket {

     public final OutputStream nullOut = new NullOutputStream();
     public final InputStream  nullIn  = new NullInputStream();
@@ -60,5 +61,11 @@
        public void free() {
                // Do nothing
        }
+
+       public SimpleFieldSet toFieldSet() {
+               SimpleFieldSet fs = new SimpleFieldSet(true);
+               fs.put("Type", "NullBucket");
+               return fs;
+       }
 }


Added: 
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
===================================================================
--- 
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java  
    2006-07-12 20:50:23 UTC (rev 9586)
+++ 
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java  
    2006-07-13 00:20:11 UTC (rev 9587)
@@ -0,0 +1,23 @@
+package freenet.support.io;
+
+import java.io.IOException;
+
+import freenet.support.Bucket;
+import freenet.support.BucketFactory;
+
+public class PersistentEncryptedTempBucketFactory implements BucketFactory {
+
+       PersistentTempBucketFactory bf;
+       
+       public PersistentEncryptedTempBucketFactory(PersistentTempBucketFactory 
bf) {
+               this.bf = bf;
+       }
+
+       public Bucket makeBucket(long size) throws IOException {
+               return bf.makeEncryptedBucket();
+       }
+
+       public void freeBucket(Bucket b) throws IOException {
+               bf.freeBucket(b);
+       }
+}

Added: trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java      
2006-07-12 20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java      
2006-07-13 00:20:11 UTC (rev 9587)
@@ -0,0 +1,10 @@
+package freenet.support.io;
+
+import freenet.support.Bucket;
+import freenet.support.SimpleFieldSet;
+
+public interface SerializableToFieldSetBucket extends Bucket {
+       
+       public SimpleFieldSet toFieldSet();
+
+}

Modified: trunk/freenet/src/freenet/support/io/TempFileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/TempFileBucket.java    2006-07-12 
20:50:23 UTC (rev 9586)
+++ trunk/freenet/src/freenet/support/io/TempFileBucket.java    2006-07-13 
00:20:11 UTC (rev 9587)
@@ -7,6 +7,7 @@
 import java.util.Vector;

 import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;

 /*
  *  This code is part of FProxy, an HTTP proxy server for Freenet.
@@ -425,4 +426,9 @@

        }

+       public SimpleFieldSet toFieldSet() {
+               SimpleFieldSet fs = super.toFieldSet();
+               fs.put("Type", "TempFileBucket");
+               return fs;
+       }
 }


Reply via email to