Author: toad
Date: 2006-07-25 16:18:57 +0000 (Tue, 25 Jul 2006)
New Revision: 9752
Added:
trunk/freenet/src/freenet/support/io/ArrayBucket.java
trunk/freenet/src/freenet/support/io/ArrayBucketFactory.java
trunk/freenet/src/freenet/support/io/Bucket.java
trunk/freenet/src/freenet/support/io/BucketFactory.java
trunk/freenet/src/freenet/support/io/BucketTools.java
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
trunk/freenet/src/freenet/support/io/RandomAccessFileBucket.java
trunk/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java
Removed:
trunk/freenet/src/freenet/support/ArrayBucket.java
trunk/freenet/src/freenet/support/ArrayBucketFactory.java
trunk/freenet/src/freenet/support/Bucket.java
trunk/freenet/src/freenet/support/BucketFactory.java
trunk/freenet/src/freenet/support/BucketTools.java
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
trunk/freenet/src/freenet/support/ReadOnlyFileSliceBucket.java
Modified:
trunk/freenet/src/freenet/client/ArchiveHandler.java
trunk/freenet/src/freenet/client/ArchiveManager.java
trunk/freenet/src/freenet/client/ArchiveStoreContext.java
trunk/freenet/src/freenet/client/ArchiveStoreItem.java
trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java
trunk/freenet/src/freenet/client/FECCodec.java
trunk/freenet/src/freenet/client/FetchResult.java
trunk/freenet/src/freenet/client/FetcherContext.java
trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
trunk/freenet/src/freenet/client/InsertBlock.java
trunk/freenet/src/freenet/client/InserterContext.java
trunk/freenet/src/freenet/client/Metadata.java
trunk/freenet/src/freenet/client/RealArchiveStoreItem.java
trunk/freenet/src/freenet/client/SplitfileBlock.java
trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
trunk/freenet/src/freenet/client/TempStoreElement.java
trunk/freenet/src/freenet/client/async/ClientGetter.java
trunk/freenet/src/freenet/client/async/ClientPutter.java
trunk/freenet/src/freenet/client/async/ManifestElement.java
trunk/freenet/src/freenet/client/async/MinimalSplitfileBlock.java
trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
trunk/freenet/src/freenet/client/async/SingleFileInserter.java
trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
trunk/freenet/src/freenet/client/async/SplitFileInserter.java
trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
trunk/freenet/src/freenet/client/async/USKFetcher.java
trunk/freenet/src/freenet/client/async/USKInserter.java
trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
trunk/freenet/src/freenet/clients/http/HTTPRequest.java
trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
trunk/freenet/src/freenet/clients/http/NinjaSpider.java
trunk/freenet/src/freenet/clients/http/PluginToadlet.java
trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
trunk/freenet/src/freenet/clients/http/QueueToadlet.java
trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
trunk/freenet/src/freenet/clients/http/Spider.java
trunk/freenet/src/freenet/clients/http/StaticToadlet.java
trunk/freenet/src/freenet/clients/http/Toadlet.java
trunk/freenet/src/freenet/clients/http/ToadletContext.java
trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java
trunk/freenet/src/freenet/clients/http/filter/CharsetExtractor.java
trunk/freenet/src/freenet/clients/http/filter/ContentDataFilter.java
trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java
trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java
trunk/freenet/src/freenet/keys/ClientCHKBlock.java
trunk/freenet/src/freenet/keys/ClientKeyBlock.java
trunk/freenet/src/freenet/keys/ClientSSKBlock.java
trunk/freenet/src/freenet/keys/InsertableClientSSK.java
trunk/freenet/src/freenet/keys/Key.java
trunk/freenet/src/freenet/node/ARKFetcher.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/fcp/AllDataMessage.java
trunk/freenet/src/freenet/node/fcp/BaseDataCarryingMessage.java
trunk/freenet/src/freenet/node/fcp/ClientGet.java
trunk/freenet/src/freenet/node/fcp/ClientPut.java
trunk/freenet/src/freenet/node/fcp/ClientPutComplexDirMessage.java
trunk/freenet/src/freenet/node/fcp/ClientPutDir.java
trunk/freenet/src/freenet/node/fcp/ClientPutDiskDirMessage.java
trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java
trunk/freenet/src/freenet/node/fcp/DataCarryingMessage.java
trunk/freenet/src/freenet/node/fcp/DirPutFile.java
trunk/freenet/src/freenet/node/fcp/DirectDirPutFile.java
trunk/freenet/src/freenet/node/fcp/DiskDirPutFile.java
trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
trunk/freenet/src/freenet/node/fcp/FCPMessage.java
trunk/freenet/src/freenet/node/fcp/FCPServer.java
trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java
trunk/freenet/src/freenet/node/fcp/RedirectDirPutFile.java
trunk/freenet/src/freenet/node/updater/NodeUpdater.java
trunk/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java
trunk/freenet/src/freenet/support/compress/Compressor.java
trunk/freenet/src/freenet/support/compress/GzipCompressor.java
trunk/freenet/src/freenet/support/io/FileBucket.java
trunk/freenet/src/freenet/support/io/FileBucketFactory.java
trunk/freenet/src/freenet/support/io/NullBucket.java
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java
trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
trunk/freenet/src/freenet/support/io/TempBucketFactory.java
Log:
Move some Bucket's to freenet/support/io.
Modified: trunk/freenet/src/freenet/client/ArchiveHandler.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveHandler.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/ArchiveHandler.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,6 +1,6 @@
package freenet.client;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
/**
* The public face (to Fetcher, for example) of ArchiveStoreContext.
Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -12,13 +12,13 @@
import freenet.crypt.RandomSource;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.LRUHashtable;
import freenet.support.Logger;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
import freenet.support.io.FileBucket;
import freenet.support.io.FilenameGenerator;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
/**
* Cache of recently decoded archives:
Modified: trunk/freenet/src/freenet/client/ArchiveStoreContext.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveStoreContext.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/ArchiveStoreContext.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,9 +1,9 @@
package freenet.client;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
import freenet.support.DoublyLinkedListImpl;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
/**
* Tracks all files currently in the cache from a given key.
Modified: trunk/freenet/src/freenet/client/ArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveStoreItem.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/ArchiveStoreItem.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,7 +1,7 @@
package freenet.client;
-import freenet.support.Bucket;
import freenet.support.DoublyLinkedListImpl;
+import freenet.support.io.Bucket;
/**
* Base class for items stored in the archive cache.
Modified: trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,7 +1,7 @@
package freenet.client;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
class ErrorArchiveStoreItem extends ArchiveStoreItem {
Modified: trunk/freenet/src/freenet/client/FECCodec.java
===================================================================
--- trunk/freenet/src/freenet/client/FECCodec.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/client/FECCodec.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -2,8 +2,8 @@
import java.io.IOException;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
/**
* FEC (forward error correction) handler.
Modified: trunk/freenet/src/freenet/client/FetchResult.java
===================================================================
--- trunk/freenet/src/freenet/client/FetchResult.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/client/FetchResult.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -2,8 +2,8 @@
import java.io.IOException;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
/**
* Class to contain the result of a key fetch.
Modified: trunk/freenet/src/freenet/client/FetcherContext.java
===================================================================
--- trunk/freenet/src/freenet/client/FetcherContext.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/FetcherContext.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -4,7 +4,7 @@
import freenet.client.events.ClientEventProducer;
import freenet.client.events.SimpleEventProducer;
import freenet.crypt.RandomSource;
-import freenet.support.BucketFactory;
+import freenet.support.io.BucketFactory;
/** Context for a Fetcher. Contains all the settings a Fetcher needs to know
about. */
public class FetcherContext implements Cloneable {
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -13,10 +13,10 @@
import freenet.crypt.RandomSource;
import freenet.keys.FreenetURI;
import freenet.node.Node;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
import freenet.support.io.NullPersistentFileTracker;
import freenet.support.io.PersistentFileTracker;
Modified: trunk/freenet/src/freenet/client/InsertBlock.java
===================================================================
--- trunk/freenet/src/freenet/client/InsertBlock.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/client/InsertBlock.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -1,7 +1,7 @@
package freenet.client;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
/**
* Class to contain everything needed for an insert.
Modified: trunk/freenet/src/freenet/client/InserterContext.java
===================================================================
--- trunk/freenet/src/freenet/client/InserterContext.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/InserterContext.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -4,7 +4,7 @@
import freenet.client.events.ClientEventProducer;
import freenet.client.events.SimpleEventProducer;
import freenet.crypt.RandomSource;
-import freenet.support.BucketFactory;
+import freenet.support.io.BucketFactory;
import freenet.support.io.NullPersistentFileTracker;
import freenet.support.io.PersistentFileTracker;
Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/client/Metadata.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -14,11 +14,11 @@
import freenet.keys.BaseClientKey;
import freenet.keys.ClientCHK;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.Fields;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
/** Metadata parser/writer class. */
Modified: trunk/freenet/src/freenet/client/RealArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/RealArchiveStoreItem.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/RealArchiveStoreItem.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -3,10 +3,10 @@
import java.io.File;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
+import freenet.support.io.Bucket;
import freenet.support.io.FileBucket;
import freenet.support.io.FileUtil;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
class RealArchiveStoreItem extends ArchiveStoreItem {
Modified: trunk/freenet/src/freenet/client/SplitfileBlock.java
===================================================================
--- trunk/freenet/src/freenet/client/SplitfileBlock.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/SplitfileBlock.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,6 +1,6 @@
package freenet.client;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
public interface SplitfileBlock {
Modified: trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
===================================================================
--- trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -10,11 +10,11 @@
import com.onionnetworks.fec.FECCodeFactory;
import com.onionnetworks.util.Buffer;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.LRUHashtable;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
/**
* FECCodec implementation using the onion code.
Modified: trunk/freenet/src/freenet/client/TempStoreElement.java
===================================================================
--- trunk/freenet/src/freenet/client/TempStoreElement.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/TempStoreElement.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -5,8 +5,8 @@
import java.io.File;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
import freenet.support.io.FileBucket;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
class TempStoreElement {
TempStoreElement(File myFile, FileBucket fb,
PaddedEphemerallyEncryptedBucket encryptedBucket) {
Modified: trunk/freenet/src/freenet/client/async/ClientGetter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientGetter.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/ClientGetter.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -10,9 +10,9 @@
import freenet.client.FetcherContext;
import freenet.client.events.SplitfileProgressEvent;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
/**
* A high level data request.
Modified: trunk/freenet/src/freenet/client/async/ClientPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientPutter.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/ClientPutter.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -8,9 +8,9 @@
import freenet.client.events.SplitfileProgressEvent;
import freenet.keys.BaseClientKey;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
public class ClientPutter extends BaseClientPutter implements
PutCompletionCallback {
Modified: trunk/freenet/src/freenet/client/async/ManifestElement.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ManifestElement.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/ManifestElement.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,7 +1,7 @@
package freenet.client.async;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
/**
* Represents an element in a manifest. Fed to SimpleManifestPutter.
Modified: trunk/freenet/src/freenet/client/async/MinimalSplitfileBlock.java
===================================================================
--- trunk/freenet/src/freenet/client/async/MinimalSplitfileBlock.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/MinimalSplitfileBlock.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,7 +1,7 @@
package freenet.client.async;
import freenet.client.SplitfileBlock;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
public class MinimalSplitfileBlock implements SplitfileBlock {
Modified: trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -21,9 +21,9 @@
import freenet.client.events.SplitfileProgressEvent;
import freenet.keys.BaseClientKey;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
public class SimpleManifestPutter extends BaseClientPutter implements
PutCompletionCallback {
// Only implements PutCompletionCallback for the final metadata insert
Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -16,9 +16,9 @@
import freenet.keys.SSKEncodeException;
import freenet.node.LowLevelPutException;
import freenet.node.Node;
-import freenet.support.Bucket;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
/**
* Insert *ONE KEY*.
Modified: trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -23,11 +23,11 @@
import freenet.keys.KeyDecodeException;
import freenet.keys.USK;
import freenet.node.LowLevelGetException;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Logger;
import freenet.support.compress.CompressionOutputSizeException;
import freenet.support.compress.Compressor;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
public class SingleFileFetcher extends BaseSingleFileFetcher implements
ClientGetState {
Modified: trunk/freenet/src/freenet/client/async/SingleFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileInserter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SingleFileInserter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -15,12 +15,12 @@
import freenet.keys.ClientCHKBlock;
import freenet.keys.FreenetURI;
import freenet.keys.SSKBlock;
-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;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
/**
* Attempt to insert a file. May include metadata.
Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcher.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -12,11 +12,11 @@
import freenet.client.Metadata;
import freenet.client.MetadataParseException;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
import freenet.support.Fields;
import freenet.support.Logger;
import freenet.support.compress.CompressionOutputSizeException;
import freenet.support.compress.Compressor;
+import freenet.support.io.Bucket;
/**
* Fetch a splitfile, decompress it if need be, and return it to the
GetCompletionCallback.
Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -14,9 +14,9 @@
import freenet.client.MetadataParseException;
import freenet.client.SplitfileBlock;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
/**
* A single segment within a SplitFileFetcher.
Modified: trunk/freenet/src/freenet/client/async/SplitFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -11,11 +11,11 @@
import freenet.client.Metadata;
import freenet.keys.CHKBlock;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
import freenet.support.compress.Compressor;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
public class SplitFileInserter implements ClientPutState {
Modified: trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -11,10 +11,10 @@
import freenet.keys.BaseClientKey;
import freenet.keys.CHKBlock;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
import freenet.support.Fields;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
import freenet.support.io.CannotCreateFromFieldSetException;
import freenet.support.io.SerializableToFieldSetBucket;
import freenet.support.io.SerializableToFieldSetBucketUtil;
Modified: trunk/freenet/src/freenet/client/async/USKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKFetcher.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/USKFetcher.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -12,8 +12,8 @@
import freenet.keys.KeyDecodeException;
import freenet.keys.USK;
import freenet.node.RequestStarter;
-import freenet.support.Bucket;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
/**
*
Modified: trunk/freenet/src/freenet/client/async/USKInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKInserter.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/client/async/USKInserter.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -11,10 +11,10 @@
import freenet.keys.FreenetURI;
import freenet.keys.InsertableUSK;
import freenet.keys.USK;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
/**
* Insert a USK. The algorithm is simply to do a thorough search for the
latest edition, and insert at the
Modified: trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConfigToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/ConfigToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -9,11 +9,11 @@
import freenet.config.Option;
import freenet.config.SubConfig;
import freenet.node.Node;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
// FIXME: add logging, comments
Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -17,10 +17,10 @@
import freenet.node.FSParseException;
import freenet.node.Node;
import freenet.node.PeerNode;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.MultiValueTable;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
public class DarknetConnectionsToadlet extends Toadlet {
Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -25,13 +25,13 @@
import freenet.node.Node;
import freenet.node.RequestStarter;
import freenet.support.Base64;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.HexUtil;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
import freenet.support.SizeUtil;
import freenet.support.URLEncoder;
+import freenet.support.io.Bucket;
public class FProxyToadlet extends Toadlet {
Modified: trunk/freenet/src/freenet/clients/http/HTTPRequest.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/HTTPRequest.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/HTTPRequest.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -14,13 +14,13 @@
import java.util.Map;
import java.util.StringTokenizer;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
import freenet.support.URLDecoder;
import freenet.support.URLEncodedFormatException;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
import freenet.support.io.LineReadingInputStream;
/**
Modified: trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -10,10 +10,10 @@
import freenet.io.comm.UdpSocketManager;
import freenet.node.Node;
import freenet.node.PeerNode;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
public class N2NTMToadlet extends Toadlet {
Modified: trunk/freenet/src/freenet/clients/http/NinjaSpider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/NinjaSpider.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/NinjaSpider.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -46,10 +46,10 @@
import freenet.node.RequestStarter;
import freenet.plugin.HttpPlugin;
import freenet.plugin.PluginManager;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
/**
* NinjaSpider. Produces a ninj^W err ... an XML index.
Modified: trunk/freenet/src/freenet/clients/http/PluginToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PluginToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/PluginToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -11,9 +11,9 @@
import freenet.plugin.HttpPlugin;
import freenet.plugin.Plugin;
import freenet.plugin.PluginManager;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
/**
* Toadlet for the plugin manager.
@@ -98,7 +98,7 @@
}
/**
- * @see freenet.clients.http.Toadlet#handlePost(java.net.URI,
freenet.support.Bucket, freenet.clients.http.ToadletContext)
+ * @see freenet.clients.http.Toadlet#handlePost(java.net.URI,
freenet.support.io.Bucket, freenet.clients.http.ToadletContext)
*/
public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws
ToadletContextClosedException, IOException, RedirectException {
HTTPRequest httpRequest = new HTTPRequest(uri, data, ctx);
Modified: trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PproxyToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/PproxyToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -13,11 +13,11 @@
import freenet.pluginmanager.PluginHTTPException;
import freenet.pluginmanager.PluginInfoWrapper;
import freenet.pluginmanager.PluginManager;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
public class PproxyToadlet extends Toadlet {
private final PluginManager pm;
Modified: trunk/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/QueueToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/QueueToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -17,13 +17,13 @@
import freenet.node.fcp.FCPServer;
import freenet.node.fcp.MessageInvalidException;
import freenet.node.Node;
-import freenet.support.Bucket;
import freenet.support.HTMLDecoder;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
import freenet.support.SizeUtil;
import freenet.support.URLEncoder;
+import freenet.support.io.Bucket;
public class QueueToadlet extends Toadlet {
Modified: trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -26,10 +26,10 @@
import freenet.crypt.DummyRandomSource;
import freenet.io.NetworkInterface;
import freenet.node.Node;
-import freenet.support.BucketFactory;
import freenet.support.FileLoggerHook;
import freenet.support.Logger;
import freenet.support.FileLoggerHook.IntervalParseException;
+import freenet.support.io.BucketFactory;
import freenet.support.io.FilenameGenerator;
import freenet.support.io.TempBucketFactory;
Modified: trunk/freenet/src/freenet/clients/http/Spider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Spider.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/clients/http/Spider.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -35,10 +35,10 @@
import freenet.node.RequestStarter;
import freenet.plugin.HttpPlugin;
import freenet.plugin.PluginManager;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
/**
* Spider. Produces an index.
Modified: trunk/freenet/src/freenet/clients/http/StaticToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/StaticToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/StaticToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -7,7 +7,7 @@
import freenet.client.DefaultMIMETypes;
import freenet.client.HighLevelSimpleClient;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
/**
* Static Toadlet.
Modified: trunk/freenet/src/freenet/clients/http/Toadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Toadlet.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/clients/http/Toadlet.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -10,11 +10,11 @@
import freenet.client.InsertBlock;
import freenet.client.InserterException;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
/**
* Replacement for servlets. Just an easy to use HTTP interface, which is
Modified: trunk/freenet/src/freenet/clients/http/ToadletContext.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContext.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/ToadletContext.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -2,9 +2,9 @@
import java.io.IOException;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
/**
* Object represents context for a single request. Is used as a token,
Modified: trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -11,11 +11,11 @@
import java.util.Enumeration;
import java.util.TimeZone;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
import freenet.support.io.LineReadingInputStream;
import freenet.support.io.TooLongException;
Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -16,9 +16,9 @@
import freenet.node.NodeStarter;
import freenet.node.Version;
import freenet.node.useralerts.UserAlert;
-import freenet.support.Bucket;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
public class WelcomeToadlet extends Toadlet {
private final static int MODE_ADD = 1;
Modified: trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/filter/CSSReadFilter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -12,10 +12,10 @@
import java.io.Writer;
import java.util.HashMap;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
import freenet.support.io.NullWriter;
public class CSSReadFilter implements ContentDataFilter, CharsetExtractor {
Modified: trunk/freenet/src/freenet/clients/http/filter/CharsetExtractor.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/CharsetExtractor.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/filter/CharsetExtractor.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -2,7 +2,7 @@
import java.io.IOException;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
/**
* For a specific text/-based MIME type, extracts the charset if
Modified: trunk/freenet/src/freenet/clients/http/filter/ContentDataFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/ContentDataFilter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/filter/ContentDataFilter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -3,8 +3,8 @@
import java.io.IOException;
import java.util.HashMap;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
/**
* Data filter for a specific MIME type.
Modified: trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/filter/ContentFilter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -8,9 +8,9 @@
import java.util.HashMap;
import java.util.Hashtable;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
/**
* Freenet content filter. This doesn't actually do any filtering,
Modified: trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/clients/http/filter/HTMLFilter.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -22,11 +22,11 @@
import java.util.StringTokenizer;
import java.util.Vector;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.HTMLDecoder;
import freenet.support.HTMLEncoder;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
import freenet.support.io.NullBucket;
import freenet.support.io.NullWriter;
Modified: trunk/freenet/src/freenet/keys/ClientCHKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientCHKBlock.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/keys/ClientCHKBlock.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -13,11 +13,11 @@
import freenet.crypt.ciphers.Rijndael;
import freenet.keys.Key.Compressed;
import freenet.node.Node;
-import freenet.support.ArrayBucket;
-import freenet.support.ArrayBucketFactory;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
+import freenet.support.io.ArrayBucket;
+import freenet.support.io.ArrayBucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
/**
* @author amphibian
Modified: trunk/freenet/src/freenet/keys/ClientKeyBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientKeyBlock.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/keys/ClientKeyBlock.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -2,8 +2,8 @@
import java.io.IOException;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
public interface ClientKeyBlock {
Modified: trunk/freenet/src/freenet/keys/ClientSSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -5,9 +5,9 @@
import freenet.crypt.PCFBMode;
import freenet.crypt.UnsupportedCipherException;
import freenet.crypt.ciphers.Rijndael;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
public class ClientSSKBlock extends SSKBlock implements ClientKeyBlock {
Modified: trunk/freenet/src/freenet/keys/InsertableClientSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -20,7 +20,7 @@
import freenet.crypt.UnsupportedCipherException;
import freenet.crypt.ciphers.Rijndael;
import freenet.keys.Key.Compressed;
-import freenet.support.Bucket;
+import freenet.support.io.Bucket;
public class InsertableClientSSK extends ClientSSK {
Modified: trunk/freenet/src/freenet/keys/Key.java
===================================================================
--- trunk/freenet/src/freenet/keys/Key.java 2006-07-25 16:14:02 UTC (rev
9751)
+++ trunk/freenet/src/freenet/keys/Key.java 2006-07-25 16:18:57 UTC (rev
9752)
@@ -7,16 +7,16 @@
import java.security.NoSuchAlgorithmException;
import freenet.io.WritableToDataOutputStream;
-import freenet.support.ArrayBucket;
-import freenet.support.ArrayBucketFactory;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.Fields;
import freenet.support.Logger;
import freenet.support.SimpleReadOnlyArrayBucket;
import freenet.support.compress.CompressionOutputSizeException;
import freenet.support.compress.Compressor;
+import freenet.support.io.ArrayBucket;
+import freenet.support.io.ArrayBucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
/**
* @author amphibian
Modified: trunk/freenet/src/freenet/node/ARKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/node/ARKFetcher.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/node/ARKFetcher.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -11,9 +11,9 @@
import freenet.client.async.ClientGetter;
import freenet.keys.FreenetURI;
import freenet.keys.USK;
-import freenet.support.ArrayBucket;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.ArrayBucket;
/**
* Fetch an ARK. Permanent, tied to a PeerNode, stops itself after a
successful fetch.
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-07-25 16:14:02 UTC (rev
9751)
+++ trunk/freenet/src/freenet/node/Node.java 2006-07-25 16:18:57 UTC (rev
9752)
@@ -107,8 +107,6 @@
import freenet.store.FreenetStore;
import freenet.store.KeyCollisionException;
import freenet.support.Base64;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.DoubleTokenBucket;
import freenet.support.Fields;
import freenet.support.FileLoggerHook;
@@ -118,11 +116,13 @@
import freenet.support.LRUHashtable;
import freenet.support.LRUQueue;
import freenet.support.Logger;
-import freenet.support.PaddedEphemerallyEncryptedBucketFactory;
import freenet.support.SimpleFieldSet;
import freenet.support.SimpleReadOnlyArrayBucket;
import freenet.support.TokenBucket;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
import freenet.support.io.FilenameGenerator;
+import freenet.support.io.PaddedEphemerallyEncryptedBucketFactory;
import freenet.support.io.PersistentEncryptedTempBucketFactory;
import freenet.support.io.PersistentTempBucketFactory;
import freenet.support.io.TempBucketFactory;
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -32,12 +32,12 @@
import freenet.io.comm.PeerParseException;
import freenet.keys.FreenetURI;
import freenet.keys.InsertableClientSSK;
-import freenet.support.ArrayBucket;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.HexUtil;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.ArrayBucket;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
import freenet.support.io.FileBucket;
/**
Modified: trunk/freenet/src/freenet/node/fcp/AllDataMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/AllDataMessage.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/AllDataMessage.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,8 +1,8 @@
package freenet.node.fcp;
import freenet.node.Node;
-import freenet.support.Bucket;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
/**
* All the data, all in one big chunk. Obviously we must already have
Modified: trunk/freenet/src/freenet/node/fcp/BaseDataCarryingMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/BaseDataCarryingMessage.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/BaseDataCarryingMessage.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -4,7 +4,7 @@
import java.io.InputStream;
import java.io.OutputStream;
-import freenet.support.BucketFactory;
+import freenet.support.io.BucketFactory;
public abstract class BaseDataCarryingMessage extends FCPMessage {
Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -17,15 +17,15 @@
import freenet.client.events.ClientEventListener;
import freenet.client.events.SplitfileProgressEvent;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-import freenet.support.BucketTools;
import freenet.support.Fields;
import freenet.support.HexUtil;
import freenet.support.Logger;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketTools;
import freenet.support.io.FileBucket;
import freenet.support.io.NullBucket;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
/**
* A simple client fetch. This can of course fetch arbitrarily large
Modified: trunk/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPut.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/ClientPut.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -9,13 +9,13 @@
import freenet.client.MetadataUnresolvedException;
import freenet.client.async.ClientPutter;
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.SimpleReadOnlyArrayBucket;
+import freenet.support.io.Bucket;
import freenet.support.io.FileBucket;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
public class ClientPut extends ClientPutBase {
Modified: trunk/freenet/src/freenet/node/fcp/ClientPutComplexDirMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutComplexDirMessage.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutComplexDirMessage.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -9,9 +9,9 @@
import freenet.client.async.ManifestElement;
import freenet.node.Node;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.BucketFactory;
import freenet.support.io.PersistentTempBucketFactory;
/**
Modified: trunk/freenet/src/freenet/node/fcp/ClientPutDir.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutDir.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutDir.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -13,12 +13,12 @@
import freenet.client.async.SimpleManifestPutter;
import freenet.client.events.ClientEventListener;
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.Bucket;
import freenet.support.io.FileBucket;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
public class ClientPutDir extends ClientPutBase implements
ClientEventListener, ClientCallback {
Modified: trunk/freenet/src/freenet/node/fcp/ClientPutDiskDirMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutDiskDirMessage.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutDiskDirMessage.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -8,10 +8,10 @@
import freenet.client.async.ManifestElement;
import freenet.node.Node;
-import freenet.support.BucketFactory;
import freenet.support.Fields;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.BucketFactory;
import freenet.support.io.FileBucket;
/**
Modified: trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -7,10 +7,10 @@
import freenet.keys.FreenetURI;
import freenet.node.Node;
import freenet.node.RequestStarter;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.Fields;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
import freenet.support.io.FileBucket;
/**
Modified: trunk/freenet/src/freenet/node/fcp/DataCarryingMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/DataCarryingMessage.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/DataCarryingMessage.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -4,10 +4,10 @@
import java.io.InputStream;
import java.io.OutputStream;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
public abstract class DataCarryingMessage extends BaseDataCarryingMessage {
Modified: trunk/freenet/src/freenet/node/fcp/DirPutFile.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/DirPutFile.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/DirPutFile.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -3,10 +3,10 @@
import freenet.client.ClientMetadata;
import freenet.client.DefaultMIMETypes;
import freenet.client.async.ManifestElement;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
/**
* A request to upload a file to a manifest.
Modified: trunk/freenet/src/freenet/node/fcp/DirectDirPutFile.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/DirectDirPutFile.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/DirectDirPutFile.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -4,10 +4,10 @@
import java.io.InputStream;
import java.io.OutputStream;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
-import freenet.support.BucketTools;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.BucketTools;
/**
* Specialized DirPutFile for direct uploads.
Modified: trunk/freenet/src/freenet/node/fcp/DiskDirPutFile.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/DiskDirPutFile.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/DiskDirPutFile.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -3,8 +3,8 @@
import java.io.File;
import freenet.client.DefaultMIMETypes;
-import freenet.support.Bucket;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
import freenet.support.io.FileBucket;
public class DiskDirPutFile extends DirPutFile {
Modified: trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -4,8 +4,8 @@
import java.net.Socket;
import java.util.HashMap;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
+import freenet.support.io.BucketFactory;
public class FCPConnectionHandler {
Modified: trunk/freenet/src/freenet/node/fcp/FCPMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPMessage.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/FCPMessage.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -4,8 +4,8 @@
import java.io.OutputStream;
import freenet.node.Node;
-import freenet.support.BucketFactory;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.BucketFactory;
import freenet.support.io.PersistentTempBucketFactory;
public abstract class FCPMessage {
Modified: trunk/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPServer.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/FCPServer.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -35,8 +35,8 @@
import freenet.node.Node;
import freenet.node.RequestStarter;
import freenet.support.Base64;
-import freenet.support.Bucket;
import freenet.support.Logger;
+import freenet.support.io.Bucket;
/**
* FCP server process.
Modified: trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/PersistentPutDir.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -6,10 +6,10 @@
import freenet.client.async.SimpleManifestPutter;
import freenet.keys.FreenetURI;
import freenet.node.Node;
-import freenet.support.Bucket;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
import freenet.support.io.FileBucket;
+import freenet.support.io.PaddedEphemerallyEncryptedBucket;
public class PersistentPutDir extends FCPMessage {
Modified: trunk/freenet/src/freenet/node/fcp/RedirectDirPutFile.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/RedirectDirPutFile.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/fcp/RedirectDirPutFile.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -5,9 +5,9 @@
import freenet.client.ClientMetadata;
import freenet.client.async.ManifestElement;
import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
+import freenet.support.io.Bucket;
public class RedirectDirPutFile extends DirPutFile {
Modified: trunk/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdater.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdater.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -31,8 +31,8 @@
import freenet.node.Version;
import freenet.node.useralerts.RevocationKeyFoundUserAlert;
import freenet.node.useralerts.UpdatedVersionAvailableUserAlert;
-import freenet.support.ArrayBucket;
import freenet.support.Logger;
+import freenet.support.io.ArrayBucket;
public class NodeUpdater implements ClientCallback, USKCallback {
private FetcherContext ctx;
Deleted: trunk/freenet/src/freenet/support/ArrayBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/ArrayBucket.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/support/ArrayBucket.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -1,187 +0,0 @@
-package freenet.support;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * A bucket that stores data in the memory.
- *
- * FIXME: No synchronization, should there be?
- *
- * @author oskar
- */
-public class ArrayBucket implements Bucket {
-
- private final ArrayList data;
- private String name;
- private boolean readOnly;
-
- public ArrayBucket() {
- this("ArrayBucket");
- }
-
- public ArrayBucket(byte[] initdata) {
- this("ArrayBucket");
- data.add(initdata);
- }
-
- public ArrayBucket(String name) {
- data = new ArrayList();
- this.name = name;
- }
-
- public OutputStream getOutputStream() throws IOException {
- if(readOnly) throw new IOException("Read only");
- return new ArrayBucketOutputStream();
- }
-
- public InputStream getInputStream() {
- return new ArrayBucketInputStream();
- }
-
- public String toString() {
- StringBuffer s = new StringBuffer(250);
- for (Iterator i = data.iterator(); i.hasNext();) {
- byte[] b = (byte[]) i.next();
- s.append(new String(b));
- }
- return s.toString();
- }
-
- public void read(InputStream in) throws IOException {
- OutputStream out = new ArrayBucketOutputStream();
- int i;
- byte[] b = new byte[8 * 1024];
- while ((i = in.read(b)) != -1) {
- out.write(b, 0, i);
- }
- out.close();
- }
-
- public long size() {
- long size = 0;
- for (Iterator i = data.iterator(); i.hasNext();) {
- byte[] b = (byte[]) i.next();
- size += b.length;
- }
- return size;
- }
-
- public String getName() {
- return name;
- }
-
- private class ArrayBucketOutputStream extends ByteArrayOutputStream {
-
- public ArrayBucketOutputStream() {
- super();
- }
-
- public void close() throws IOException {
- data.add(toByteArray());
- if(readOnly) throw new IOException("Read only");
- // FIXME maybe we should throw on write instead? :)
- }
- }
-
- private class ArrayBucketInputStream extends InputStream {
-
- private Iterator i;
- private ByteArrayInputStream in;
-
- public ArrayBucketInputStream() {
- i = data.iterator();
- }
-
- public int read() {
- return priv_read();
- }
-
- private int priv_read() {
- if (in == null) {
- if (i.hasNext()) {
- in = new ByteArrayInputStream((byte[])
i.next());
- } else {
- return -1;
- }
- }
- int i = in.read();
- if (i == -1) {
- in = null;
- return priv_read();
- } else {
- return i;
- }
- }
-
- public int read(byte[] b) {
- return priv_read(b, 0, b.length);
- }
-
- public int read(byte[] b, int off, int len) {
- return priv_read(b, off, len);
- }
-
- private int priv_read(byte[] b, int off, int len) {
- if (in == null) {
- if (i.hasNext()) {
- in = new ByteArrayInputStream((byte[])
i.next());
- } else {
- return -1;
- }
- }
- int i = in.read(b, off, len);
- if (i == -1) {
- in = null;
- return priv_read(b, off, len);
- } else {
- return i;
- }
- }
-
- public int available() {
- if (in == null) {
- if (i.hasNext()) {
- in = new ByteArrayInputStream((byte[])
i.next());
- } else {
- return 0;
- }
- }
- return in.available();
- }
-
- }
-
- public boolean isReadOnly() {
- return readOnly;
- }
-
- public void setReadOnly() {
- readOnly = true;
- }
-
- public void free() {
- data.clear();
- // Not much else we can do.
- }
-
- public byte[] toByteArray() {
- long sz = size();
- int size = (int)sz;
- byte[] buf = new byte[size];
- int index = 0;
- for(Iterator i=data.iterator();i.hasNext();) {
- byte[] obuf = (byte[]) i.next();
- System.arraycopy(obuf, 0, buf, index, obuf.length);
- index += obuf.length;
- }
- if(index != buf.length)
- throw new IllegalStateException();
- return buf;
- }
-}
Deleted: trunk/freenet/src/freenet/support/ArrayBucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/ArrayBucketFactory.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/ArrayBucketFactory.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,15 +0,0 @@
-package freenet.support;
-
-import java.io.IOException;
-
-public class ArrayBucketFactory implements BucketFactory {
-
- public Bucket makeBucket(long size) throws IOException {
- return new ArrayBucket();
- }
-
- public void freeBucket(Bucket b) throws IOException {
- // Do nothing
- }
-
-}
Deleted: trunk/freenet/src/freenet/support/Bucket.java
===================================================================
--- trunk/freenet/src/freenet/support/Bucket.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/support/Bucket.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -1,50 +0,0 @@
-package freenet.support;
-import java.io.*;
-/**
- * A bucket is any arbitrary object can temporarily store data.
- *
- * @author oskar
- */
-public interface Bucket {
-
- /**
- * Returns an OutputStream that is used to put data in this Bucket, from
the
- * beginning. It is not possible to append data to a Bucket! This
simplifies the
- * code significantly for some classes. If you need to append, just pass
the
- * OutputStream around.
- */
- public OutputStream getOutputStream() throws IOException;
-
- /**
- * Returns an InputStream that reads data from this Bucket. If there is
- * no data in this bucket, null is returned.
- */
- public InputStream getInputStream() throws IOException;
-
- /**
- * Returns a name for the bucket, may be used to identify them in
- * certain in certain situations.
- */
- public String getName();
-
- /**
- * Returns the amount of data currently in this bucket.
- */
- public long size();
-
- /**
- * Is the bucket read-only?
- */
- public boolean isReadOnly();
-
- /**
- * Make the bucket read-only. Irreversible.
- */
- public void setReadOnly();
-
- /**
- * Free the bucket, if supported.
- */
- public void free();
-
-}
Deleted: trunk/freenet/src/freenet/support/BucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/BucketFactory.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/BucketFactory.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -1,10 +0,0 @@
-package freenet.support;
-
-import java.io.IOException;
-
-
-public interface BucketFactory {
- public Bucket makeBucket(long size) throws IOException;
- public void freeBucket(Bucket b) throws IOException;
-}
-
Deleted: trunk/freenet/src/freenet/support/BucketTools.java
===================================================================
--- trunk/freenet/src/freenet/support/BucketTools.java 2006-07-25 16:14:02 UTC
(rev 9751)
+++ trunk/freenet/src/freenet/support/BucketTools.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -1,476 +0,0 @@
-package freenet.support;
-
-import java.io.DataInputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-
-import freenet.support.io.FileBucket;
-
-/**
- * Helper functions for working with Buckets.
- */
-public class BucketTools {
-
- static final int BLOCK_SIZE = 4096;
-
- /**
- * Copy from the input stream of <code>src</code> to the output stream
of
- * <code>dest</code>.
- *
- * @param src
- * @param dst
- * @throws IOException
- */
- public final static void copy(Bucket src, Bucket dst) throws
IOException {
- OutputStream out = dst.getOutputStream();
- InputStream in = src.getInputStream();
- ReadableByteChannel readChannel = Channels.newChannel(in);
- WritableByteChannel writeChannel = Channels.newChannel(out);
-
- ByteBuffer buffer = ByteBuffer.allocateDirect(BLOCK_SIZE);
- while (readChannel.read(buffer) != -1) {
- buffer.flip();
- writeChannel.write(buffer);
- buffer.clear();
- }
-
- writeChannel.close();
- readChannel.close();
- out.close();
- in.close();
- }
-
- public final static void zeroPad(Bucket b, long size) throws
IOException {
- OutputStream out = b.getOutputStream();
-
- // Initialized to zero by default.
- byte[] buffer = new byte[16384];
-
- long count = 0;
- while (count < size) {
- long nRequired = buffer.length;
- if (nRequired > size - count) {
- nRequired = size - count;
- }
- out.write(buffer, 0, (int) nRequired);
- count += nRequired;
- }
-
- out.close();
- }
-
- public final static void paddedCopy(Bucket from, Bucket to, long nBytes,
- int blockSize) throws IOException {
-
- if (nBytes > blockSize) {
- throw new IllegalArgumentException("nBytes >
blockSize");
- }
-
- OutputStream out = null;
- InputStream in = null;
-
- try {
-
- out = to.getOutputStream();
- byte[] buffer = new byte[16384];
- in = from.getInputStream();
-
- long count = 0;
- while (count != nBytes) {
- long nRequired = nBytes - count;
- if (nRequired > buffer.length) {
- nRequired = buffer.length;
- }
- long nRead = in.read(buffer, 0, (int)
nRequired);
- if (nRead == -1) {
- throw new IOException("Not enough data
in source bucket.");
- }
- out.write(buffer, 0, (int) nRead);
- count += nRead;
- }
-
- if (count < blockSize) {
- // hmmm... better to just allocate a new buffer
- // instead of explicitly zeroing the old one?
- // Zero pad to blockSize
- long padLength = buffer.length;
- if (padLength > blockSize - nBytes) {
- padLength = blockSize - nBytes;
- }
- for (int i = 0; i < padLength; i++) {
- buffer[i] = 0;
- }
-
- while (count != blockSize) {
- long nRequired = blockSize - count;
- if (blockSize - count > buffer.length) {
- nRequired = buffer.length;
- }
- out.write(buffer, 0, (int) nRequired);
- count += nRequired;
- }
- }
- } finally {
- if (in != null)
- in.close();
- if (out != null)
- out.close();
- }
- }
-
- public static class BucketFactoryWrapper implements BucketFactory {
- public BucketFactoryWrapper(BucketFactory bf) {
- BucketFactoryWrapper.this.bf = bf;
- }
- public Bucket makeBucket(long size) throws IOException {
- return bf.makeBucket(size);
- }
-
- public void freeBucket(Bucket b) throws IOException {
- if (b instanceof RandomAccessFileBucket) {
- ((RandomAccessFileBucket) b).release();
- return;
- }
- bf.freeBucket(b);
- }
- private BucketFactory bf = null;
- }
-
- public static Bucket[] makeBuckets(BucketFactory bf, int count, int
size)
- throws IOException {
- Bucket[] ret = new Bucket[count];
- for (int i = 0; i < count; i++) {
- ret[i] = bf.makeBucket(size);
- }
- return ret;
- }
-
- /**
- * Free buckets. Get yer free buckets here! No charge! All you can carry
- * free buckets!
- * <p>
- * If an exception happens the method will attempt to free the remaining
- * buckets then retun the first exception. Buckets successfully freed
are
- * made <code>null</code> in the array.
- * </p>
- *
- * @param bf
- * @param buckets
- * @throws IOException
- * the first exception The <code>buckets</code> array will
- */
- public static void freeBuckets(BucketFactory bf, Bucket[] buckets)
- throws IOException {
- if (buckets == null) {
- return;
- }
-
- IOException firstIoe = null;
-
- for (int i = 0; i < buckets.length; i++) {
- // Make sure we free any temp buckets on exception
- try {
- if (buckets[i] != null) {
- bf.freeBucket(buckets[i]);
- }
- buckets[i] = null;
- } catch (IOException e) {
- if (firstIoe == null) {
- firstIoe = e;
- }
- }
- }
-
- if (firstIoe != null) {
- throw firstIoe;
- }
- }
-
- // Note: Not all buckets are allocated by the bf.
- // You must use the BucketFactoryWrapper class above
- // to free the returned buckets.
- //
- // Always returns blocks, blocks, even if it has to create
- // zero padded ones.
- public static Bucket[] splitFile(
- File file,
- int blockSize,
- long offset,
- int blocks,
- boolean readOnly,
- BucketFactoryWrapper bf)
- throws IOException {
-
- long len = file.length() - offset;
- if (len > blocks * blockSize) {
- len = blocks * blockSize;
- }
-
- long padBlocks = 0;
- if ((blocks * blockSize) - len >= blockSize) {
- padBlocks = ((blocks * blockSize) - len) / blockSize;
- }
-
- Bucket[] ret = new Bucket[blocks];
- Bucket[] rab =
- RandomAccessFileBucket.segment(
- file,
- blockSize,
- offset,
- (int) (blocks - padBlocks),
- true);
- System.arraycopy(rab, 0, ret, 0, rab.length);
-
- boolean groovy = false;
- try {
- if (len % blockSize != 0) {
- // Copy and zero pad final partial block
- Bucket partial = ret[rab.length - 1];
- ret[rab.length - 1] = bf.makeBucket(blockSize);
- paddedCopy(
- partial,
- ret[rab.length - 1],
- len % blockSize,
- blockSize);
- }
-
- // Trailing zero padded blocks
- for (int i = rab.length; i < ret.length; i++) {
- ret[i] = bf.makeBucket(blockSize);
- zeroPad(ret[i], blockSize);
- }
- groovy = true;
- } finally {
- if (!groovy) {
- freeBuckets(bf, ret);
- }
- }
- return ret;
- }
-
- public final static int[] nullIndices(Bucket[] array) {
- List list = new ArrayList();
- for (int i = 0; i < array.length; i++) {
- if (array[i] == null) {
- list.add(new Integer(i));
- }
- }
-
- int[] ret = new int[list.size()];
- for (int i = 0; i < list.size(); i++) {
- ret[i] = ((Integer) list.get(i)).intValue();
- }
- return ret;
- }
-
- public final static int[] nonNullIndices(Bucket[] array) {
- List list = new ArrayList();
- for (int i = 0; i < array.length; i++) {
- if (array[i] != null) {
- list.add(new Integer(i));
- }
- }
-
- int[] ret = new int[list.size()];
- for (int i = 0; i < list.size(); i++) {
- ret[i] = ((Integer) list.get(i)).intValue();
- }
- return ret;
- }
-
- public final static Bucket[] nonNullBuckets(Bucket[] array) {
- List list = new ArrayList(array.length);
- for (int i = 0; i < array.length; i++) {
- if (array[i] != null) {
- list.add(array[i]);
- }
- }
-
- Bucket[] ret = new Bucket[list.size()];
- return (Bucket[]) list.toArray(ret);
- }
-
- /**
- * Read the entire bucket in as a byte array.
- * Not a good idea unless it is very small!
- * Don't call if concurrent writes may be happening.
- * @throws IOException If there was an error reading from the bucket.
- * @throws OutOfMemoryError If it was not possible to allocate enough
- * memory to contain the entire bucket.
- */
- public final static byte[] toByteArray(Bucket bucket) throws
IOException {
- long size = bucket.size();
- if(size > Integer.MAX_VALUE) throw new OutOfMemoryError();
- byte[] data = new byte[(int)size];
- InputStream is = bucket.getInputStream();
- try {
- DataInputStream dis = new DataInputStream(is);
- dis.readFully(data);
- } finally {
- is.close();
- }
- return data;
- }
-
- public static int toByteArray(Bucket bucket, byte[] output) throws
IOException {
- long size = bucket.size();
- if(size > output.length)
- throw new IllegalArgumentException("Data does not fit
in provided buffer");
- InputStream is = bucket.getInputStream();
- int moved = 0;
- while(true) {
- if(moved == size) return moved;
- int x = is.read(output, moved, (int)(size - moved));
- if(x == -1) return moved;
- moved += x;
- }
- }
-
- public static Bucket makeImmutableBucket(BucketFactory bucketFactory,
byte[] data) throws IOException {
- Bucket bucket = bucketFactory.makeBucket(data.length);
- OutputStream os = bucket.getOutputStream();
- os.write(data);
- os.close();
- bucket.setReadOnly();
- return bucket;
- }
-
- public static byte[] hash(Bucket data) throws IOException {
- InputStream is = null;
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- is = data.getInputStream();
- long bucketLength = data.size();
- long bytesRead = 0;
- byte[] buf = new byte[4096];
- while((bytesRead < bucketLength) || (bucketLength ==
-1)) {
- int readBytes = is.read(buf);
- if(readBytes < 0) break;
- bytesRead += readBytes;
- md.update(buf, 0, readBytes);
- }
- if((bytesRead < bucketLength) && (bucketLength > 0))
- throw new EOFException();
- if((bytesRead != bucketLength) && (bucketLength > 0))
- throw new IOException("Read "+bytesRead+" but
bucket length "+bucketLength+"!");
- return md.digest();
- } catch (NoSuchAlgorithmException e) {
- Logger.error(BucketTools.class, "No such digest:
SHA-256 !!");
- throw new Error("No such digest: SHA-256 !!");
- } finally {
- if(is != null) is.close();
- }
- }
-
- /** Copy the given quantity of data from the given bucket to the given
OutputStream.
- * @throws IOException If there was an error reading from the bucket or
writing to the stream. */
- public static void copyTo(Bucket decodedData, OutputStream os, long
truncateLength) throws IOException {
- if(truncateLength == 0) return;
- if(truncateLength < 0) truncateLength = Long.MAX_VALUE;
- InputStream is = decodedData.getInputStream();
- try {
- byte[] buf = new byte[4096];
- long moved = 0;
- while(moved < truncateLength) {
- // DO NOT move the (int) inside the Math.min()!
big numbers truncate to negative numbers.
- int bytes = (int) Math.min(buf.length,
truncateLength - moved);
- if(bytes <= 0)
- throw new
IllegalStateException("bytes="+bytes+", truncateLength="+truncateLength+",
moved="+moved);
- bytes = is.read(buf, 0, bytes);
- if(bytes <= 0) {
- if(truncateLength == Long.MAX_VALUE)
- break;
- throw new IOException("Could not move
required quantity of data: "+bytes+" (moved "+moved+" of "+truncateLength+")");
- }
- os.write(buf, 0, bytes);
- moved += bytes;
- }
- } finally {
- is.close();
- }
- }
-
- /** Copy data from an InputStream into a Bucket. */
- public static void copyFrom(Bucket bucket, InputStream is, long
truncateLength) throws IOException {
- OutputStream os = bucket.getOutputStream();
- byte[] buf = new byte[4096];
- if(truncateLength < 0) truncateLength = Long.MAX_VALUE;
- try {
- long moved = 0;
- while(moved < truncateLength) {
- // DO NOT move the (int) inside the Math.min()!
big numbers truncate to negative numbers.
- int bytes = (int) Math.min(buf.length,
truncateLength - moved);
- if(bytes <= 0)
- throw new
IllegalStateException("bytes="+bytes+", truncateLength="+truncateLength+",
moved="+moved);
- bytes = is.read(buf, 0, bytes);
- if(bytes <= 0) {
- if(truncateLength == Long.MAX_VALUE)
- break;
- throw new IOException("Could not move
required quantity of data: "+bytes+" (moved "+moved+" of "+truncateLength+")");
- }
- os.write(buf, 0, bytes);
- moved += bytes;
- }
- } finally {
- os.close();
- }
- }
-
- /**
- * Split the data into a series of read-only Bucket's.
- * @param origData The original data Bucket.
- * @param splitSize The number of bytes to put into each bucket.
- *
- * FIXME This could be made many orders of magnitude more efficient on
- * time and space if the underlying Bucket happens to be a passed-in
- * plaintext file!
- *
- * Note that this method will allocate a buffer of size splitSize.
- * @throws IOException If there is an error creating buckets, reading
from
- * the provided bucket, or writing to created buckets.
- */
- public static Bucket[] split(Bucket origData, int splitSize,
BucketFactory bf) throws IOException {
- if(origData instanceof FileBucket) {
- return ((FileBucket)origData).split(splitSize);
- }
- long length = origData.size();
- if(length > ((long)Integer.MAX_VALUE) * splitSize)
- throw new IllegalArgumentException("Way too big!:
"+length+" for "+splitSize);
- int bucketCount = (int) (length / splitSize);
- if(length % splitSize > 0) bucketCount++;
- Bucket[] buckets = new Bucket[bucketCount];
- InputStream is = origData.getInputStream();
- try {
- DataInputStream dis = new DataInputStream(is);
- long remainingLength = length;
- byte[] buf = new byte[splitSize];
- for(int i=0;i<bucketCount;i++) {
- int len = (int) Math.min(splitSize,
remainingLength);
- Bucket bucket = bf.makeBucket(len);
- buckets[i] = bucket;
- dis.readFully(buf, 0, len);
- remainingLength -= len;
- OutputStream os = bucket.getOutputStream();
- try {
- os.write(buf, 0, len);
- } finally {
- os.close();
- }
- }
- } finally {
- is.close();
- }
- return buckets;
- }
-}
Deleted: trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,364 +0,0 @@
-package freenet.support;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.spaceroots.mantissa.random.MersenneTwister;
-
-import freenet.crypt.PCFBMode;
-import freenet.crypt.RandomSource;
-import freenet.crypt.UnsupportedCipherException;
-import freenet.crypt.ciphers.Rijndael;
-import freenet.support.io.CannotCreateFromFieldSetException;
-import freenet.support.io.PersistentFileTracker;
-import freenet.support.io.SerializableToFieldSetBucket;
-import freenet.support.io.SerializableToFieldSetBucketUtil;
-
-/**
- * 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,
SerializableToFieldSetBucket {
-
- private final Bucket bucket;
- private final int minPaddedSize;
- private final RandomSource origRandom;
- private final Rijndael aes;
- /** The decryption key. May be null. */
- private final byte[] key;
- private long dataLength;
- private boolean readOnly;
- private int lastOutputStream;
-
- /**
- * Create a padded encrypted proxy bucket.
- * @param bucket The bucket which we are proxying to. Must be empty.
- * @param pcfb The encryption mode with which to encipher/decipher the
data.
- * @param minSize The minimum padded size of the file (after it has
been closed).
- * @param origRandom Hard random number generator from which to obtain
a seed for padding.
- * @throws UnsupportedCipherException
- */
- public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize,
RandomSource origRandom, boolean forgetKey) {
- this.origRandom = origRandom;
- this.bucket = bucket;
- if(bucket.size() != 0) throw new
IllegalArgumentException("Bucket must be empty");
- try {
- aes = new Rijndael(256, 256);
- } catch (UnsupportedCipherException e) {
- throw new Error(e);
- }
- byte[] tempKey = new byte[32];
- origRandom.nextBytes(tempKey);
- aes.initialize(tempKey);
- if(forgetKey) {
- // Might as well blank it
- for(int i=0;i<tempKey.length;i++) tempKey[i] = 0;
- this.key = null;
- } else {
- this.key = tempKey;
- }
- this.minPaddedSize = minSize;
- readOnly = false;
- lastOutputStream = 0;
- }
-
- /**
- * Load an existing PaddedEphemerallyEncryptedBucket, with a key.
- * The bucket can and should already exist.
- * @param bucket
- * @param minSize
- * @param knownSize The size of the data. This cannot be deduced from
the bucket
- * alone and must be specified. If the bucket is smaller than this, we
throw.
- * @param key
- * @param origRandom
- * @throws IOException
- */
- public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize,
long knownSize, byte[] key, RandomSource origRandom) throws IOException {
- if(bucket.size() < knownSize)
- throw new IOException("Bucket is too small on disk -
knownSize="+knownSize+" but bucket.size="+bucket.size()+" for "+bucket);
- this.dataLength = knownSize;
- this.origRandom = origRandom;
- this.bucket = bucket;
- try {
- aes = new Rijndael(256, 256);
- } catch (UnsupportedCipherException e) {
- throw new Error(e);
- }
- aes.initialize(key);
- this.key = key;
- this.minPaddedSize = minSize;
- readOnly = false;
- lastOutputStream = 0;
- }
-
- public PaddedEphemerallyEncryptedBucket(SimpleFieldSet fs, RandomSource
origRandom, PersistentFileTracker f) throws CannotCreateFromFieldSetException {
- this.origRandom = origRandom;
- String tmp = fs.get("DataLength");
- if(tmp == null)
- throw new CannotCreateFromFieldSetException("No
DataLength");
- try {
- dataLength = Long.parseLong(tmp);
- } catch (NumberFormatException e) {
- throw new CannotCreateFromFieldSetException("Corrupt
dataLength: "+tmp, e);
- }
- SimpleFieldSet underlying = fs.subset("Underlying");
- if(underlying == null)
- throw new CannotCreateFromFieldSetException("No
underlying bucket");
- bucket = SerializableToFieldSetBucketUtil.create(underlying,
origRandom, f);
- tmp = fs.get("DecryptKey");
- if(tmp == null)
- throw new CannotCreateFromFieldSetException("No key");
- key = HexUtil.hexToBytes(tmp);
- try {
- aes = new Rijndael(256, 256);
- } catch (UnsupportedCipherException e) {
- throw new Error(e);
- }
- aes.initialize(key);
- tmp = fs.get("MinPaddedSize");
- if(tmp == null)
- minPaddedSize = 1024; // FIXME throw! back
compatibility hack
- else {
- try {
- minPaddedSize = Integer.parseInt(tmp);
- } catch (NumberFormatException e) {
- throw new
CannotCreateFromFieldSetException("Corrupt dataLength: "+tmp, e);
- }
- }
- if(dataLength > bucket.size())
- throw new CannotCreateFromFieldSetException("Underlying
bucket is too small: should be "+dataLength+" actually "+bucket.size());
- }
-
- public OutputStream getOutputStream() throws IOException {
- if(readOnly) throw new IOException("Read only");
- OutputStream os = bucket.getOutputStream();
- synchronized(this) {
- dataLength = 0;
- }
- return new PaddedEphemerallyEncryptedOutputStream(os,
++lastOutputStream);
- }
-
- private class PaddedEphemerallyEncryptedOutputStream extends
OutputStream {
-
- final PCFBMode pcfb;
- final OutputStream out;
- final int streamNumber;
- private boolean closed;
-
- public PaddedEphemerallyEncryptedOutputStream(OutputStream out,
int streamNumber) {
- this.out = out;
- dataLength = 0;
- this.streamNumber = streamNumber;
- pcfb = new PCFBMode(aes);
- }
-
- public void write(int b) throws IOException {
- if(closed) throw new IOException("Already closed!");
- if(streamNumber != lastOutputStream)
- throw new IllegalStateException("Writing to old
stream in "+getName());
- if((b < 0) || (b > 255))
- throw new IllegalArgumentException();
- int toWrite = pcfb.encipher(b);
- synchronized(PaddedEphemerallyEncryptedBucket.this) {
- out.write(toWrite);
- dataLength++;
- }
- }
-
- public void write(byte[] buf, int offset, int length) throws
IOException {
- if(closed) throw new IOException("Already closed!");
- if(streamNumber != lastOutputStream)
- throw new IllegalStateException("Writing to old
stream in "+getName());
- byte[] enc = new byte[length];
- System.arraycopy(buf, offset, enc, 0, length);
- pcfb.blockEncipher(enc, 0, enc.length);
- synchronized(PaddedEphemerallyEncryptedBucket.this) {
- out.write(enc, 0, enc.length);
- dataLength += enc.length;
- }
- }
-
- // Override this or FOS will use write(int)
- public void write(byte[] buf) throws IOException {
- if(closed) throw new IOException("Already closed!");
- if(streamNumber != lastOutputStream)
- throw new IllegalStateException("Writing to old
stream in "+getName());
- write(buf, 0, buf.length);
- }
-
- public void close() throws IOException {
- if(closed) return;
- try {
- if(streamNumber != lastOutputStream) {
- Logger.normal(this, "Not padding out to
length because have been superceded: "+getName());
- return;
- }
-
synchronized(PaddedEphemerallyEncryptedBucket.this) {
- MersenneTwister paddingSource = new
MersenneTwister(origRandom.nextLong());
- long finalLength = paddedLength();
- long padding = finalLength - dataLength;
- byte[] buf = new byte[4096];
- long writtenPadding = 0;
- while(writtenPadding < padding) {
- int left = Math.min((int)
(padding - writtenPadding), buf.length);
- paddingSource.nextBytes(buf);
- out.write(buf, 0, left);
- writtenPadding += left;
- }
- }
- } finally {
- closed = true;
- out.close();
- }
- }
- }
-
- public InputStream getInputStream() throws IOException {
- return new
PaddedEphemerallyEncryptedInputStream(bucket.getInputStream());
- }
-
- private class PaddedEphemerallyEncryptedInputStream extends InputStream
{
-
- final InputStream in;
- final PCFBMode pcfb;
- long ptr;
-
- public PaddedEphemerallyEncryptedInputStream(InputStream in) {
- this.in = in;
- pcfb = new PCFBMode(aes);
- ptr = 0;
- }
-
- public int read() throws IOException {
- if(ptr > dataLength) return -1;
- int x = in.read();
- if(x == -1) return x;
- ptr++;
- return pcfb.decipher(x);
- }
-
- public final int available() {
- int x = (int)(dataLength - ptr);
- return (x < 0) ? 0 : x;
- }
-
- public int read(byte[] buf, int offset, int length) throws
IOException {
- // FIXME remove debugging
- if((length+offset > buf.length) || (offset < 0) ||
(length < 0))
- throw new
ArrayIndexOutOfBoundsException("a="+offset+", b="+length+", length
"+buf.length);
- int x = available();
- if(x <= 0) return -1;
- length = Math.min(length, x);
- int readBytes = in.read(buf, offset, length);
- if(readBytes <= 0) return readBytes;
- ptr += readBytes;
- pcfb.blockDecipher(buf, offset, readBytes);
- return readBytes;
- }
-
- public int read(byte[] buf) throws IOException {
- return read(buf, 0, buf.length);
- }
-
- public long skip(long bytes) throws IOException {
- byte[] buf = new byte[(int)Math.min(4096, bytes)];
- long skipped = 0;
- while(skipped < bytes) {
- int x = read(buf, 0,
(int)Math.min(bytes-skipped, buf.length));
- if(x <= 0) return skipped;
- skipped += x;
- }
- return skipped;
- }
-
- public void close() throws IOException {
- in.close();
- }
- }
-
- /**
- * Return the length of the data in the proxied bucket, after padding.
- */
- public synchronized long paddedLength() {
- long size = dataLength;
- if(size < minPaddedSize) size = minPaddedSize;
- if(size == minPaddedSize) return size;
- long min = minPaddedSize;
- long max = minPaddedSize << 1;
- while(true) {
- if(max < 0)
- throw new Error("Impossible size: "+size+" -
min="+min+", max="+max);
- if(size < min)
- throw new IllegalStateException("???");
- if((size >= min) && (size <= max)) {
- Logger.minor(this, "Padded: "+max+" was:
"+dataLength+" for "+getName());
- return max;
- }
- min = max;
- max = max << 1;
- }
- }
-
- public String getName() {
- return "Encrypted:"+bucket.getName();
- }
-
- public String toString() {
- return super.toString()+":"+bucket.toString();
- }
-
- public synchronized long size() {
- return dataLength;
- }
-
- public boolean isReadOnly() {
- return readOnly;
- }
-
- public void setReadOnly() {
- readOnly = true;
- }
-
- /**
- * @return The underlying Bucket.
- */
- public Bucket getUnderlying() {
- return bucket;
- }
-
- public void free() {
- bucket.free();
- }
-
- /**
- * Get the decryption key. May have been blanked out.
- */
- public byte[] getKey() {
- return key;
- }
-
- public SimpleFieldSet toFieldSet() {
- SimpleFieldSet fs = new SimpleFieldSet(true);
- fs.put("Type", "PaddedEphemerallyEncryptedBucket");
- synchronized(this) {
- 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;
- }
- fs.put("MinPaddedSize", minPaddedSize);
- return fs;
- }
-
-}
Deleted:
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
===================================================================
---
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
2006-07-25 16:14:02 UTC (rev 9751)
+++
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,31 +0,0 @@
-package freenet.support;
-
-import java.io.IOException;
-
-import freenet.crypt.RandomSource;
-
-/**
- * Factory wrapper for PaddedEphemerallyEncryptedBucket's, which are themselves
- * wrappers.
- */
-public class PaddedEphemerallyEncryptedBucketFactory implements BucketFactory {
-
- final BucketFactory baseFactory;
- final RandomSource random;
- final int minSize;
-
- public PaddedEphemerallyEncryptedBucketFactory(BucketFactory factory,
RandomSource r, int minSize) {
- baseFactory = factory;
- this.minSize = minSize;
- this.random = r;
- }
-
- public Bucket makeBucket(long size) throws IOException {
- return new
PaddedEphemerallyEncryptedBucket(baseFactory.makeBucket(size), minSize, random,
true);
- }
-
- public void freeBucket(Bucket b) throws IOException {
-
baseFactory.freeBucket(((PaddedEphemerallyEncryptedBucket)b).getUnderlying());
- }
-
-}
Deleted: trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,467 +0,0 @@
-// REDFLAG: test and javadoc
-package freenet.support;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.util.Vector;
-
-import freenet.support.io.CannotCreateFromFieldSetException;
-import freenet.support.io.PersistentFileTracker;
-import freenet.support.io.SerializableToFieldSetBucket;
-
-/**
- * Bucket implementation that can efficiently access any arbitrary byte-range
- * of a file.
- *
- **/
-public class RandomAccessFileBucket implements Bucket,
SerializableToFieldSetBucket {
-
- private final File file;
- private final long offset;
- private long localOffset = 0;
- private final long len;
- private boolean readOnly = false;
- private boolean released = false;
- private Vector streams = new Vector();
-
- public RandomAccessFileBucket(File file, long offset, long len, boolean
readOnly)
- throws IOException {
- if (!(file.exists() && file.canRead())) {
- throw new IOException("Can't read file: " +
file.getAbsolutePath());
- }
-
- if ((!file.canWrite()) && (!readOnly)) {
- throw new IOException("Can't write to file: " +
file.getAbsolutePath());
- }
-
- this.file = file;
- this.readOnly = readOnly;
- this.offset = offset;
- this.len = len;
- }
-
- public RandomAccessFileBucket(SimpleFieldSet fs, PersistentFileTracker f)
throws CannotCreateFromFieldSetException {
- String tmp = fs.get("Filename");
- if(tmp == null) throw new CannotCreateFromFieldSetException("No
filename");
- this.file = new File(tmp);
- tmp = fs.get("Length");
- if(tmp == null) throw new CannotCreateFromFieldSetException("No
length");
- try {
- len = Long.parseLong(tmp);
- } catch (NumberFormatException e) {
- throw new CannotCreateFromFieldSetException("Corrupt
length "+tmp, e);
- }
- tmp = fs.get("Offset");
- if(tmp == null) throw new CannotCreateFromFieldSetException("No
offset");
- try {
- offset = Long.parseLong(tmp);
- } catch (NumberFormatException e) {
- throw new CannotCreateFromFieldSetException("Corrupt
offset "+tmp, e);
- }
- }
-
- public static class Range {
- Range(long offset, long len) {
- this.offset = offset;
- this.len = len;
- }
-
- public long offset;
- public long len;
- }
-
- public final synchronized Range getRange() {
- return new Range(offset, len);
- }
-
- // hmmm make protected???
- public final synchronized boolean hasOpenStreams() {
- return streams.size() > 0;
- }
-
- // Wrap non-const members so we can tell
- // when code touches the Bucket after it
- // has been released.
- public synchronized InputStream getInputStream() throws IOException {
- if (isReleased()) {
- throw new IOException("Attempt to use a released
RandomAccessFileBucket: " + getName() );
- }
-
- InputStream newIn = new RAInputStream(file.getAbsolutePath());
- streams.addElement(newIn);
- return newIn;
- }
-
- public synchronized OutputStream getOutputStream() throws IOException {
- if (isReleased()) {
- throw new IOException("Attempt to use a released
RandomAccessBucket: " + getName() );
- }
-
- if (readOnly) {
- throw new IOException("Tried to write a read-only Bucket.");
- }
-
- OutputStream newOut = new RAOutputStream(file.getAbsolutePath());
- streams.addElement(newOut);
- return newOut;
- }
-
- public String getName() {
- return file.getAbsolutePath() + " [" + offset + ", " +
- (offset + len - 1) + "]";
- }
-
- public synchronized void resetWrite() {
- if (isReleased()) {
- throw new RuntimeException("Attempt to use a released
RandomAccessFileBucket: " + getName() );
- }
- // REDFLAG: implicit assumptions
- // 0) Bucket is only written to at a time.
- // 1) The output stream is closed before the
- // next is open. Ouch. This may cause problems...
- localOffset = 0;
- }
-
- public long size() { return len; }
-
- public synchronized boolean release() {
- if (released) {
- return true;
- }
-
- // Force all open streams closed.
- // Windows won't let us delete the file unless we
- // do this.
- for (int i =0; i < streams.size(); i++) {
- try {
- if (streams.elementAt(i) instanceof InputStream) {
- ((InputStream)streams.elementAt(i)).close();
-
- Logger.debug(this, "closed open InputStream !: " +
- file.getAbsolutePath());
- }
- else if (streams.elementAt(i) instanceof OutputStream) {
- ((OutputStream)streams.elementAt(i)).close();
- Logger.debug(this, "closed open OutputStream !: " +
- file.getAbsolutePath());
- }
- }
- catch (IOException ioe) {
- }
- }
- streams.removeAllElements();
- streams.trimToSize();
- // We don't delete anything because we don't own anything.
- released = true;
- return true;
- }
-
- public synchronized final boolean isReleased() { return released; }
-
- public void finalize() throws Throwable {
- synchronized(this) {
- if(released) return;
- }
- release();
- }
-
- // REDFLAG: RETEST
- // set blocks = -1 for until end.
- // last block may have length < blockSize
- public static Bucket[] segment(File file, int blockSize,
- long offset, int blocks, boolean readOnly)
- throws IOException {
-
- if (!(file.exists() && file.canRead())) {
- throw new IOException("Can't read file: " +
file.getAbsolutePath());
- }
-
- if ((!file.canWrite()) && (!readOnly)) {
- throw new IOException("Can't write to file: " +
file.getAbsolutePath());
- }
-
- if ((offset < 0) || (offset >= file.length() - 1)) {
- throw new IllegalArgumentException("offset: " + offset);
- }
-
- long length = file.length() - offset;
- int nBlocks = (int) (length / blockSize);
- if ((length % blockSize) != 0) {
- nBlocks++;
- }
-
- if (blocks == -1) {
- blocks = nBlocks;
- }
- else if ((blocks > nBlocks) || (blocks < 1)) {
- throw new IllegalArgumentException("blocks: " + blocks);
- }
-
- Bucket[] ret = new Bucket[blocks];
-
- for (int i = 0; i < blocks; i++) {
- final long localOffset = i * blockSize + offset;
- int blockLen = blockSize;
- if (i == nBlocks - 1) {
- blockLen = (int) (length - (nBlocks - 1) * blockSize);
- }
- ret[i] = new RandomAccessFileBucket(file, localOffset, blockLen,
readOnly);
- }
-
- return ret;
- }
-
- ////////////////////////////////////////////////////////////
- // InputStream and OutputStream implementations
- //
- private final static boolean vociferous = false;
-
- class RAInputStream extends InputStream {
- public RAInputStream(String prefix) throws IOException {
- raf = new RandomAccessFile(file, "r");
- raf.seek(offset);
- println(" -- Created new InputStream [" + offset +
- ", " + (offset + len -1) + "]" );
- }
-
- ////////////////////////////////////////////////////////////
- // FilterInput implementation
-
- private final int bytesLeft() throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- return (int)(offset + len -
raf.getFilePointer());
- }
- }
-
- public int read() throws java.io.IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".read()");
- checkValid();
- if (bytesLeft() < 1) {
- return -1; // EOF
- }
- return raf.read();
- }
- }
-
- public int read(byte[] bytes) throws java.io.IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".read(byte[])");
- checkValid();
- int nAvailable = bytesLeft();
- if (nAvailable < 1) {
- return -1; // EOF
- }
- if (nAvailable > bytes.length) {
- nAvailable = bytes.length;
- }
- return raf.read(bytes, 0, nAvailable);
- }
- }
-
- public int read(byte[] bytes, int a, int b) throws java.io.IOException
{
- synchronized (RandomAccessFileBucket.this) {
- println(".read(byte[], int, int)");
- checkValid();
- int nAvailable = bytesLeft();
- if (nAvailable < 1) {
- return -1; // EOF
- }
- if (nAvailable > b) {
- nAvailable = b;
- }
- return raf.read(bytes, a, nAvailable);
- }
- }
-
- public long skip(long a) throws java.io.IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".skip(long)");
- checkValid();
- int nAvailable = bytesLeft();
- if (nAvailable < 1) {
- return -1; // EOF
- }
- if (nAvailable > a) {
- nAvailable = (int)a;
- }
-
- return raf.skipBytes(nAvailable);
- }
- }
-
- public int available() throws java.io.IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".available()");
- checkValid();
- return bytesLeft();
- }
- }
-
- public void close() throws java.io.IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".close()");
- checkValid();
- raf.close();
- if (streams.contains(RAInputStream.this)) {
- streams.removeElement(RAInputStream.this);
- }
- streams.trimToSize();
- }
- }
-
- // LATER: support if really needed.
- public void mark(int a) {
- // NOP
- }
-
- public void reset() {
- // NOP
- }
-
- public boolean markSupported() {
- return false;
- }
-
- private final void println(String text) {
- if (vociferous) {
- Logger.debug(this, text);
- }
- }
-
- private final void checkValid() throws IOException {
- synchronized(RandomAccessFileBucket.this) {
- if (released) {
- throw new IOException("Attempt to use a
released RandomAccessFileBucket: " + prefix);
- }
- }
- }
-
- ////////////////////////////////////////////////////////////
- private RandomAccessFile raf = null;
- private String prefix = "";
- }
-
- private class RAOutputStream extends OutputStream {
- public RAOutputStream(String pref) throws IOException {
- raf = new RandomAccessFile(file, "rw");
- raf.seek(offset + localOffset);
- println(" -- Created new OutputStream [" + offset + ", "
- + (offset + len -1) + "]" );
- }
-
- ////////////////////////////////////////////////////////////
- // OutputStream implementation
- public void write(int b) throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".write(b)");
- checkValid();
- int nAvailable = bytesLeft();
- if (nAvailable < 1) {
- throw new IOException("Attempt to write past end of
Bucket.");
- }
- raf.write(b);
- }
- }
-
- public void write(byte[] buf) throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".write(buf)");
- checkValid();
- int nAvailable = bytesLeft();
- if (nAvailable < buf.length) {
- throw new IOException("Attempt to write past end of
Bucket.");
- }
- raf.write(buf);
- }
- }
-
- public void write(byte[] buf, int off, int len) throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".write(buf,off,len)");
- checkValid();
- int nAvailable = bytesLeft();
- if (nAvailable < len) {
- throw new IOException("Attempt to write past end of
Bucket.");
- }
- raf.write(buf, off, len);
- }
- }
-
- public void flush() throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".flush()");
- checkValid();
- // NOP? Bytes written immediately?
- // REDFLAG: double check.
- }
- }
-
- public void close() throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- println(".close()");
- checkValid();
- if (streams.contains(RAOutputStream.this)) {
- streams.removeElement(RAOutputStream.this);
- }
- streams.trimToSize();
- long added = raf.getFilePointer() - offset;
- if (added > 0) {
- // To get proper append behavior.
- localOffset = added;
- }
-
- raf.close();
- }
- }
-
- ////////////////////////////////////////////////////////////
- private void println(String text) {
- if (vociferous) {
- Logger.debug(this, text);
- }
- }
-
- private final void checkValid() throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- if (isReleased()) {
- throw new IOException("Attempt to use a
released RandomAccessFileBucket: " + prefix);
- }
- }
- }
- private final int bytesLeft() throws IOException {
- synchronized (RandomAccessFileBucket.this) {
- return (int)(offset + len -
raf.getFilePointer());
- }
- }
-
- private RandomAccessFile raf = null;
- private String prefix = "";
-
- }
- ////////////////////////////////////////////////////////////
-
- public synchronized boolean isReadOnly() {
- return readOnly;
- }
-
- public synchronized void setReadOnly() {
- readOnly = true;
- }
-
- public void free() {
- release();
- }
-
- public synchronized 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;
- }
-}
Deleted: trunk/freenet/src/freenet/support/ReadOnlyFileSliceBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/ReadOnlyFileSliceBucket.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/ReadOnlyFileSliceBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,119 +0,0 @@
-package freenet.support;
-
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-
-/**
- * FIXME: implement a hash verifying version of this.
- */
-public class ReadOnlyFileSliceBucket implements Bucket {
-
- private final File file;
- private final long startAt;
- private final long length;
-
- public ReadOnlyFileSliceBucket(File f, long startAt, long length) {
- this.file = f;
- this.startAt = startAt;
- this.length = length;
- }
-
- public OutputStream getOutputStream() throws IOException {
- throw new IOException("Bucket is read-only");
- }
-
- public InputStream getInputStream() throws IOException {
- return new MyInputStream();
- }
-
- public String getName() {
- return "ROFS:"+file.getAbsolutePath()+":"+startAt+":"+length;
- }
-
- public long size() {
- return length;
- }
-
- public boolean isReadOnly() {
- return true;
- }
-
- public void setReadOnly() {
- // Do nothing
- }
-
- class MyInputStream extends InputStream {
-
- private RandomAccessFile f;
- private long ptr; // relative to startAt
-
- MyInputStream() throws IOException {
- try {
- this.f = new RandomAccessFile(file,"r");
- f.seek(startAt);
- if(f.length() < (startAt+length))
- throw new
ReadOnlyFileSliceBucketException("File truncated? Length "+f.length()+" but
start at "+startAt+" for "+length+" bytes");
- ptr = 0;
- } catch (FileNotFoundException e) {
- throw new ReadOnlyFileSliceBucketException(e);
- }
- }
-
- public int read() throws IOException {
- if(ptr > length)
- throw new EOFException();
- int x = f.read();
- ptr++;
- return x;
- }
-
- public int read(byte[] buf, int offset, int len) throws
IOException {
- if(ptr > length)
- throw new EOFException();
- len = (int) Math.min(len, length - ptr);
- int x = f.read(buf, offset, len);
- ptr += x;
- return x;
- }
-
- public int read(byte[] buf) throws IOException {
- return read(buf, 0, buf.length);
- }
-
- public void close() throws IOException {
- f.close();
- }
-
- public void finalize() {
- try {
- close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }
-
- public class ReadOnlyFileSliceBucketException extends IOException {
- private static final long serialVersionUID = -1;
-
- public ReadOnlyFileSliceBucketException(FileNotFoundException
e) {
- super("File not found: "+e.getMessage());
- initCause(e);
- }
-
- public ReadOnlyFileSliceBucketException(String string) {
- super(string);
- }
-
- }
-
- public void free() {
- // Do nothing
- }
-
-}
Modified: trunk/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -5,6 +5,8 @@
import java.io.InputStream;
import java.io.OutputStream;
+import freenet.support.io.Bucket;
+
/**
* Simple read-only array bucket. Just an adapter class to save some RAM.
* Not the same as ArrayBucket, which can't take a (byte[], offset, len) in
Modified: trunk/freenet/src/freenet/support/compress/Compressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/Compressor.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/compress/Compressor.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -3,8 +3,8 @@
import java.io.IOException;
import freenet.client.Metadata;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
/**
* A data compressor. Contains methods to get all data compressors.
Modified: trunk/freenet/src/freenet/support/compress/GzipCompressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/GzipCompressor.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/compress/GzipCompressor.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -8,8 +8,8 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
+import freenet.support.io.Bucket;
+import freenet.support.io.BucketFactory;
public class GzipCompressor extends Compressor {
Copied: trunk/freenet/src/freenet/support/io/ArrayBucket.java (from rev 9743,
trunk/freenet/src/freenet/support/ArrayBucket.java)
===================================================================
--- trunk/freenet/src/freenet/support/ArrayBucket.java 2006-07-25 01:25:46 UTC
(rev 9743)
+++ trunk/freenet/src/freenet/support/io/ArrayBucket.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -0,0 +1,187 @@
+package freenet.support.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * A bucket that stores data in the memory.
+ *
+ * FIXME: No synchronization, should there be?
+ *
+ * @author oskar
+ */
+public class ArrayBucket implements Bucket {
+
+ private final ArrayList data;
+ private String name;
+ private boolean readOnly;
+
+ public ArrayBucket() {
+ this("ArrayBucket");
+ }
+
+ public ArrayBucket(byte[] initdata) {
+ this("ArrayBucket");
+ data.add(initdata);
+ }
+
+ public ArrayBucket(String name) {
+ data = new ArrayList();
+ this.name = name;
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ if(readOnly) throw new IOException("Read only");
+ return new ArrayBucketOutputStream();
+ }
+
+ public InputStream getInputStream() {
+ return new ArrayBucketInputStream();
+ }
+
+ public String toString() {
+ StringBuffer s = new StringBuffer(250);
+ for (Iterator i = data.iterator(); i.hasNext();) {
+ byte[] b = (byte[]) i.next();
+ s.append(new String(b));
+ }
+ return s.toString();
+ }
+
+ public void read(InputStream in) throws IOException {
+ OutputStream out = new ArrayBucketOutputStream();
+ int i;
+ byte[] b = new byte[8 * 1024];
+ while ((i = in.read(b)) != -1) {
+ out.write(b, 0, i);
+ }
+ out.close();
+ }
+
+ public long size() {
+ long size = 0;
+ for (Iterator i = data.iterator(); i.hasNext();) {
+ byte[] b = (byte[]) i.next();
+ size += b.length;
+ }
+ return size;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private class ArrayBucketOutputStream extends ByteArrayOutputStream {
+
+ public ArrayBucketOutputStream() {
+ super();
+ }
+
+ public void close() throws IOException {
+ data.add(toByteArray());
+ if(readOnly) throw new IOException("Read only");
+ // FIXME maybe we should throw on write instead? :)
+ }
+ }
+
+ private class ArrayBucketInputStream extends InputStream {
+
+ private Iterator i;
+ private ByteArrayInputStream in;
+
+ public ArrayBucketInputStream() {
+ i = data.iterator();
+ }
+
+ public int read() {
+ return priv_read();
+ }
+
+ private int priv_read() {
+ if (in == null) {
+ if (i.hasNext()) {
+ in = new ByteArrayInputStream((byte[])
i.next());
+ } else {
+ return -1;
+ }
+ }
+ int i = in.read();
+ if (i == -1) {
+ in = null;
+ return priv_read();
+ } else {
+ return i;
+ }
+ }
+
+ public int read(byte[] b) {
+ return priv_read(b, 0, b.length);
+ }
+
+ public int read(byte[] b, int off, int len) {
+ return priv_read(b, off, len);
+ }
+
+ private int priv_read(byte[] b, int off, int len) {
+ if (in == null) {
+ if (i.hasNext()) {
+ in = new ByteArrayInputStream((byte[])
i.next());
+ } else {
+ return -1;
+ }
+ }
+ int i = in.read(b, off, len);
+ if (i == -1) {
+ in = null;
+ return priv_read(b, off, len);
+ } else {
+ return i;
+ }
+ }
+
+ public int available() {
+ if (in == null) {
+ if (i.hasNext()) {
+ in = new ByteArrayInputStream((byte[])
i.next());
+ } else {
+ return 0;
+ }
+ }
+ return in.available();
+ }
+
+ }
+
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ public void setReadOnly() {
+ readOnly = true;
+ }
+
+ public void free() {
+ data.clear();
+ // Not much else we can do.
+ }
+
+ public byte[] toByteArray() {
+ long sz = size();
+ int size = (int)sz;
+ byte[] buf = new byte[size];
+ int index = 0;
+ for(Iterator i=data.iterator();i.hasNext();) {
+ byte[] obuf = (byte[]) i.next();
+ System.arraycopy(obuf, 0, buf, index, obuf.length);
+ index += obuf.length;
+ }
+ if(index != buf.length)
+ throw new IllegalStateException();
+ return buf;
+ }
+}
Copied: trunk/freenet/src/freenet/support/io/ArrayBucketFactory.java (from rev
9743, trunk/freenet/src/freenet/support/ArrayBucketFactory.java)
===================================================================
--- trunk/freenet/src/freenet/support/ArrayBucketFactory.java 2006-07-25
01:25:46 UTC (rev 9743)
+++ trunk/freenet/src/freenet/support/io/ArrayBucketFactory.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -0,0 +1,15 @@
+package freenet.support.io;
+
+import java.io.IOException;
+
+public class ArrayBucketFactory implements BucketFactory {
+
+ public Bucket makeBucket(long size) throws IOException {
+ return new ArrayBucket();
+ }
+
+ public void freeBucket(Bucket b) throws IOException {
+ // Do nothing
+ }
+
+}
Copied: trunk/freenet/src/freenet/support/io/Bucket.java (from rev 9743,
trunk/freenet/src/freenet/support/Bucket.java)
===================================================================
--- trunk/freenet/src/freenet/support/Bucket.java 2006-07-25 01:25:46 UTC
(rev 9743)
+++ trunk/freenet/src/freenet/support/io/Bucket.java 2006-07-25 16:18:57 UTC
(rev 9752)
@@ -0,0 +1,50 @@
+package freenet.support.io;
+import java.io.*;
+/**
+ * A bucket is any arbitrary object can temporarily store data.
+ *
+ * @author oskar
+ */
+public interface Bucket {
+
+ /**
+ * Returns an OutputStream that is used to put data in this Bucket, from
the
+ * beginning. It is not possible to append data to a Bucket! This
simplifies the
+ * code significantly for some classes. If you need to append, just pass
the
+ * OutputStream around.
+ */
+ public OutputStream getOutputStream() throws IOException;
+
+ /**
+ * Returns an InputStream that reads data from this Bucket. If there is
+ * no data in this bucket, null is returned.
+ */
+ public InputStream getInputStream() throws IOException;
+
+ /**
+ * Returns a name for the bucket, may be used to identify them in
+ * certain in certain situations.
+ */
+ public String getName();
+
+ /**
+ * Returns the amount of data currently in this bucket.
+ */
+ public long size();
+
+ /**
+ * Is the bucket read-only?
+ */
+ public boolean isReadOnly();
+
+ /**
+ * Make the bucket read-only. Irreversible.
+ */
+ public void setReadOnly();
+
+ /**
+ * Free the bucket, if supported.
+ */
+ public void free();
+
+}
Copied: trunk/freenet/src/freenet/support/io/BucketFactory.java (from rev 9743,
trunk/freenet/src/freenet/support/BucketFactory.java)
===================================================================
--- trunk/freenet/src/freenet/support/BucketFactory.java 2006-07-25
01:25:46 UTC (rev 9743)
+++ trunk/freenet/src/freenet/support/io/BucketFactory.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -0,0 +1,10 @@
+package freenet.support.io;
+
+import java.io.IOException;
+
+
+public interface BucketFactory {
+ public Bucket makeBucket(long size) throws IOException;
+ public void freeBucket(Bucket b) throws IOException;
+}
+
Copied: trunk/freenet/src/freenet/support/io/BucketTools.java (from rev 9743,
trunk/freenet/src/freenet/support/BucketTools.java)
===================================================================
--- trunk/freenet/src/freenet/support/BucketTools.java 2006-07-25 01:25:46 UTC
(rev 9743)
+++ trunk/freenet/src/freenet/support/io/BucketTools.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -0,0 +1,476 @@
+package freenet.support.io;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+
+import freenet.support.Logger;
+
+/**
+ * Helper functions for working with Buckets.
+ */
+public class BucketTools {
+
+ static final int BLOCK_SIZE = 4096;
+
+ /**
+ * Copy from the input stream of <code>src</code> to the output stream
of
+ * <code>dest</code>.
+ *
+ * @param src
+ * @param dst
+ * @throws IOException
+ */
+ public final static void copy(Bucket src, Bucket dst) throws
IOException {
+ OutputStream out = dst.getOutputStream();
+ InputStream in = src.getInputStream();
+ ReadableByteChannel readChannel = Channels.newChannel(in);
+ WritableByteChannel writeChannel = Channels.newChannel(out);
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(BLOCK_SIZE);
+ while (readChannel.read(buffer) != -1) {
+ buffer.flip();
+ writeChannel.write(buffer);
+ buffer.clear();
+ }
+
+ writeChannel.close();
+ readChannel.close();
+ out.close();
+ in.close();
+ }
+
+ public final static void zeroPad(Bucket b, long size) throws
IOException {
+ OutputStream out = b.getOutputStream();
+
+ // Initialized to zero by default.
+ byte[] buffer = new byte[16384];
+
+ long count = 0;
+ while (count < size) {
+ long nRequired = buffer.length;
+ if (nRequired > size - count) {
+ nRequired = size - count;
+ }
+ out.write(buffer, 0, (int) nRequired);
+ count += nRequired;
+ }
+
+ out.close();
+ }
+
+ public final static void paddedCopy(Bucket from, Bucket to, long nBytes,
+ int blockSize) throws IOException {
+
+ if (nBytes > blockSize) {
+ throw new IllegalArgumentException("nBytes >
blockSize");
+ }
+
+ OutputStream out = null;
+ InputStream in = null;
+
+ try {
+
+ out = to.getOutputStream();
+ byte[] buffer = new byte[16384];
+ in = from.getInputStream();
+
+ long count = 0;
+ while (count != nBytes) {
+ long nRequired = nBytes - count;
+ if (nRequired > buffer.length) {
+ nRequired = buffer.length;
+ }
+ long nRead = in.read(buffer, 0, (int)
nRequired);
+ if (nRead == -1) {
+ throw new IOException("Not enough data
in source bucket.");
+ }
+ out.write(buffer, 0, (int) nRead);
+ count += nRead;
+ }
+
+ if (count < blockSize) {
+ // hmmm... better to just allocate a new buffer
+ // instead of explicitly zeroing the old one?
+ // Zero pad to blockSize
+ long padLength = buffer.length;
+ if (padLength > blockSize - nBytes) {
+ padLength = blockSize - nBytes;
+ }
+ for (int i = 0; i < padLength; i++) {
+ buffer[i] = 0;
+ }
+
+ while (count != blockSize) {
+ long nRequired = blockSize - count;
+ if (blockSize - count > buffer.length) {
+ nRequired = buffer.length;
+ }
+ out.write(buffer, 0, (int) nRequired);
+ count += nRequired;
+ }
+ }
+ } finally {
+ if (in != null)
+ in.close();
+ if (out != null)
+ out.close();
+ }
+ }
+
+ public static class BucketFactoryWrapper implements BucketFactory {
+ public BucketFactoryWrapper(BucketFactory bf) {
+ BucketFactoryWrapper.this.bf = bf;
+ }
+ public Bucket makeBucket(long size) throws IOException {
+ return bf.makeBucket(size);
+ }
+
+ public void freeBucket(Bucket b) throws IOException {
+ if (b instanceof RandomAccessFileBucket) {
+ ((RandomAccessFileBucket) b).release();
+ return;
+ }
+ bf.freeBucket(b);
+ }
+ private BucketFactory bf = null;
+ }
+
+ public static Bucket[] makeBuckets(BucketFactory bf, int count, int
size)
+ throws IOException {
+ Bucket[] ret = new Bucket[count];
+ for (int i = 0; i < count; i++) {
+ ret[i] = bf.makeBucket(size);
+ }
+ return ret;
+ }
+
+ /**
+ * Free buckets. Get yer free buckets here! No charge! All you can carry
+ * free buckets!
+ * <p>
+ * If an exception happens the method will attempt to free the remaining
+ * buckets then retun the first exception. Buckets successfully freed
are
+ * made <code>null</code> in the array.
+ * </p>
+ *
+ * @param bf
+ * @param buckets
+ * @throws IOException
+ * the first exception The <code>buckets</code> array will
+ */
+ public static void freeBuckets(BucketFactory bf, Bucket[] buckets)
+ throws IOException {
+ if (buckets == null) {
+ return;
+ }
+
+ IOException firstIoe = null;
+
+ for (int i = 0; i < buckets.length; i++) {
+ // Make sure we free any temp buckets on exception
+ try {
+ if (buckets[i] != null) {
+ bf.freeBucket(buckets[i]);
+ }
+ buckets[i] = null;
+ } catch (IOException e) {
+ if (firstIoe == null) {
+ firstIoe = e;
+ }
+ }
+ }
+
+ if (firstIoe != null) {
+ throw firstIoe;
+ }
+ }
+
+ // Note: Not all buckets are allocated by the bf.
+ // You must use the BucketFactoryWrapper class above
+ // to free the returned buckets.
+ //
+ // Always returns blocks, blocks, even if it has to create
+ // zero padded ones.
+ public static Bucket[] splitFile(
+ File file,
+ int blockSize,
+ long offset,
+ int blocks,
+ boolean readOnly,
+ BucketFactoryWrapper bf)
+ throws IOException {
+
+ long len = file.length() - offset;
+ if (len > blocks * blockSize) {
+ len = blocks * blockSize;
+ }
+
+ long padBlocks = 0;
+ if ((blocks * blockSize) - len >= blockSize) {
+ padBlocks = ((blocks * blockSize) - len) / blockSize;
+ }
+
+ Bucket[] ret = new Bucket[blocks];
+ Bucket[] rab =
+ RandomAccessFileBucket.segment(
+ file,
+ blockSize,
+ offset,
+ (int) (blocks - padBlocks),
+ true);
+ System.arraycopy(rab, 0, ret, 0, rab.length);
+
+ boolean groovy = false;
+ try {
+ if (len % blockSize != 0) {
+ // Copy and zero pad final partial block
+ Bucket partial = ret[rab.length - 1];
+ ret[rab.length - 1] = bf.makeBucket(blockSize);
+ paddedCopy(
+ partial,
+ ret[rab.length - 1],
+ len % blockSize,
+ blockSize);
+ }
+
+ // Trailing zero padded blocks
+ for (int i = rab.length; i < ret.length; i++) {
+ ret[i] = bf.makeBucket(blockSize);
+ zeroPad(ret[i], blockSize);
+ }
+ groovy = true;
+ } finally {
+ if (!groovy) {
+ freeBuckets(bf, ret);
+ }
+ }
+ return ret;
+ }
+
+ public final static int[] nullIndices(Bucket[] array) {
+ List list = new ArrayList();
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] == null) {
+ list.add(new Integer(i));
+ }
+ }
+
+ int[] ret = new int[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ ret[i] = ((Integer) list.get(i)).intValue();
+ }
+ return ret;
+ }
+
+ public final static int[] nonNullIndices(Bucket[] array) {
+ List list = new ArrayList();
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] != null) {
+ list.add(new Integer(i));
+ }
+ }
+
+ int[] ret = new int[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ ret[i] = ((Integer) list.get(i)).intValue();
+ }
+ return ret;
+ }
+
+ public final static Bucket[] nonNullBuckets(Bucket[] array) {
+ List list = new ArrayList(array.length);
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] != null) {
+ list.add(array[i]);
+ }
+ }
+
+ Bucket[] ret = new Bucket[list.size()];
+ return (Bucket[]) list.toArray(ret);
+ }
+
+ /**
+ * Read the entire bucket in as a byte array.
+ * Not a good idea unless it is very small!
+ * Don't call if concurrent writes may be happening.
+ * @throws IOException If there was an error reading from the bucket.
+ * @throws OutOfMemoryError If it was not possible to allocate enough
+ * memory to contain the entire bucket.
+ */
+ public final static byte[] toByteArray(Bucket bucket) throws
IOException {
+ long size = bucket.size();
+ if(size > Integer.MAX_VALUE) throw new OutOfMemoryError();
+ byte[] data = new byte[(int)size];
+ InputStream is = bucket.getInputStream();
+ try {
+ DataInputStream dis = new DataInputStream(is);
+ dis.readFully(data);
+ } finally {
+ is.close();
+ }
+ return data;
+ }
+
+ public static int toByteArray(Bucket bucket, byte[] output) throws
IOException {
+ long size = bucket.size();
+ if(size > output.length)
+ throw new IllegalArgumentException("Data does not fit
in provided buffer");
+ InputStream is = bucket.getInputStream();
+ int moved = 0;
+ while(true) {
+ if(moved == size) return moved;
+ int x = is.read(output, moved, (int)(size - moved));
+ if(x == -1) return moved;
+ moved += x;
+ }
+ }
+
+ public static Bucket makeImmutableBucket(BucketFactory bucketFactory,
byte[] data) throws IOException {
+ Bucket bucket = bucketFactory.makeBucket(data.length);
+ OutputStream os = bucket.getOutputStream();
+ os.write(data);
+ os.close();
+ bucket.setReadOnly();
+ return bucket;
+ }
+
+ public static byte[] hash(Bucket data) throws IOException {
+ InputStream is = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ is = data.getInputStream();
+ long bucketLength = data.size();
+ long bytesRead = 0;
+ byte[] buf = new byte[4096];
+ while((bytesRead < bucketLength) || (bucketLength ==
-1)) {
+ int readBytes = is.read(buf);
+ if(readBytes < 0) break;
+ bytesRead += readBytes;
+ md.update(buf, 0, readBytes);
+ }
+ if((bytesRead < bucketLength) && (bucketLength > 0))
+ throw new EOFException();
+ if((bytesRead != bucketLength) && (bucketLength > 0))
+ throw new IOException("Read "+bytesRead+" but
bucket length "+bucketLength+"!");
+ return md.digest();
+ } catch (NoSuchAlgorithmException e) {
+ Logger.error(BucketTools.class, "No such digest:
SHA-256 !!");
+ throw new Error("No such digest: SHA-256 !!");
+ } finally {
+ if(is != null) is.close();
+ }
+ }
+
+ /** Copy the given quantity of data from the given bucket to the given
OutputStream.
+ * @throws IOException If there was an error reading from the bucket or
writing to the stream. */
+ public static void copyTo(Bucket decodedData, OutputStream os, long
truncateLength) throws IOException {
+ if(truncateLength == 0) return;
+ if(truncateLength < 0) truncateLength = Long.MAX_VALUE;
+ InputStream is = decodedData.getInputStream();
+ try {
+ byte[] buf = new byte[4096];
+ long moved = 0;
+ while(moved < truncateLength) {
+ // DO NOT move the (int) inside the Math.min()!
big numbers truncate to negative numbers.
+ int bytes = (int) Math.min(buf.length,
truncateLength - moved);
+ if(bytes <= 0)
+ throw new
IllegalStateException("bytes="+bytes+", truncateLength="+truncateLength+",
moved="+moved);
+ bytes = is.read(buf, 0, bytes);
+ if(bytes <= 0) {
+ if(truncateLength == Long.MAX_VALUE)
+ break;
+ throw new IOException("Could not move
required quantity of data: "+bytes+" (moved "+moved+" of "+truncateLength+")");
+ }
+ os.write(buf, 0, bytes);
+ moved += bytes;
+ }
+ } finally {
+ is.close();
+ }
+ }
+
+ /** Copy data from an InputStream into a Bucket. */
+ public static void copyFrom(Bucket bucket, InputStream is, long
truncateLength) throws IOException {
+ OutputStream os = bucket.getOutputStream();
+ byte[] buf = new byte[4096];
+ if(truncateLength < 0) truncateLength = Long.MAX_VALUE;
+ try {
+ long moved = 0;
+ while(moved < truncateLength) {
+ // DO NOT move the (int) inside the Math.min()!
big numbers truncate to negative numbers.
+ int bytes = (int) Math.min(buf.length,
truncateLength - moved);
+ if(bytes <= 0)
+ throw new
IllegalStateException("bytes="+bytes+", truncateLength="+truncateLength+",
moved="+moved);
+ bytes = is.read(buf, 0, bytes);
+ if(bytes <= 0) {
+ if(truncateLength == Long.MAX_VALUE)
+ break;
+ throw new IOException("Could not move
required quantity of data: "+bytes+" (moved "+moved+" of "+truncateLength+")");
+ }
+ os.write(buf, 0, bytes);
+ moved += bytes;
+ }
+ } finally {
+ os.close();
+ }
+ }
+
+ /**
+ * Split the data into a series of read-only Bucket's.
+ * @param origData The original data Bucket.
+ * @param splitSize The number of bytes to put into each bucket.
+ *
+ * FIXME This could be made many orders of magnitude more efficient on
+ * time and space if the underlying Bucket happens to be a passed-in
+ * plaintext file!
+ *
+ * Note that this method will allocate a buffer of size splitSize.
+ * @throws IOException If there is an error creating buckets, reading
from
+ * the provided bucket, or writing to created buckets.
+ */
+ public static Bucket[] split(Bucket origData, int splitSize,
BucketFactory bf) throws IOException {
+ if(origData instanceof FileBucket) {
+ return ((FileBucket)origData).split(splitSize);
+ }
+ long length = origData.size();
+ if(length > ((long)Integer.MAX_VALUE) * splitSize)
+ throw new IllegalArgumentException("Way too big!:
"+length+" for "+splitSize);
+ int bucketCount = (int) (length / splitSize);
+ if(length % splitSize > 0) bucketCount++;
+ Bucket[] buckets = new Bucket[bucketCount];
+ InputStream is = origData.getInputStream();
+ try {
+ DataInputStream dis = new DataInputStream(is);
+ long remainingLength = length;
+ byte[] buf = new byte[splitSize];
+ for(int i=0;i<bucketCount;i++) {
+ int len = (int) Math.min(splitSize,
remainingLength);
+ Bucket bucket = bf.makeBucket(len);
+ buckets[i] = bucket;
+ dis.readFully(buf, 0, len);
+ remainingLength -= len;
+ OutputStream os = bucket.getOutputStream();
+ try {
+ os.write(buf, 0, len);
+ } finally {
+ os.close();
+ }
+ }
+ } finally {
+ is.close();
+ }
+ return buckets;
+ }
+}
Modified: trunk/freenet/src/freenet/support/io/FileBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/FileBucket.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/FileBucket.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -9,9 +9,7 @@
import java.io.OutputStream;
import freenet.crypt.RandomSource;
-import freenet.support.Bucket;
import freenet.support.Logger;
-import freenet.support.ReadOnlyFileSliceBucket;
import freenet.support.SimpleFieldSet;
/**
Modified: trunk/freenet/src/freenet/support/io/FileBucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/io/FileBucketFactory.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/FileBucketFactory.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -4,8 +4,6 @@
import java.io.IOException;
import java.util.Vector;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
public class FileBucketFactory implements BucketFactory {
Modified: trunk/freenet/src/freenet/support/io/NullBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/NullBucket.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/NullBucket.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -2,7 +2,6 @@
import java.io.InputStream;
import java.io.OutputStream;
-import freenet.support.Bucket;
import freenet.support.SimpleFieldSet;
public class NullBucket implements Bucket, SerializableToFieldSetBucket {
Copied:
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
(from rev 9743,
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java)
===================================================================
--- trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucket.java
2006-07-25 01:25:46 UTC (rev 9743)
+++ trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -0,0 +1,363 @@
+package freenet.support.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spaceroots.mantissa.random.MersenneTwister;
+
+import freenet.crypt.PCFBMode;
+import freenet.crypt.RandomSource;
+import freenet.crypt.UnsupportedCipherException;
+import freenet.crypt.ciphers.Rijndael;
+import freenet.support.HexUtil;
+import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;
+
+/**
+ * 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,
SerializableToFieldSetBucket {
+
+ private final Bucket bucket;
+ private final int minPaddedSize;
+ private final RandomSource origRandom;
+ private final Rijndael aes;
+ /** The decryption key. May be null. */
+ private final byte[] key;
+ private long dataLength;
+ private boolean readOnly;
+ private int lastOutputStream;
+
+ /**
+ * Create a padded encrypted proxy bucket.
+ * @param bucket The bucket which we are proxying to. Must be empty.
+ * @param pcfb The encryption mode with which to encipher/decipher the
data.
+ * @param minSize The minimum padded size of the file (after it has
been closed).
+ * @param origRandom Hard random number generator from which to obtain
a seed for padding.
+ * @throws UnsupportedCipherException
+ */
+ public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize,
RandomSource origRandom, boolean forgetKey) {
+ this.origRandom = origRandom;
+ this.bucket = bucket;
+ if(bucket.size() != 0) throw new
IllegalArgumentException("Bucket must be empty");
+ try {
+ aes = new Rijndael(256, 256);
+ } catch (UnsupportedCipherException e) {
+ throw new Error(e);
+ }
+ byte[] tempKey = new byte[32];
+ origRandom.nextBytes(tempKey);
+ aes.initialize(tempKey);
+ if(forgetKey) {
+ // Might as well blank it
+ for(int i=0;i<tempKey.length;i++) tempKey[i] = 0;
+ this.key = null;
+ } else {
+ this.key = tempKey;
+ }
+ this.minPaddedSize = minSize;
+ readOnly = false;
+ lastOutputStream = 0;
+ }
+
+ /**
+ * Load an existing PaddedEphemerallyEncryptedBucket, with a key.
+ * The bucket can and should already exist.
+ * @param bucket
+ * @param minSize
+ * @param knownSize The size of the data. This cannot be deduced from
the bucket
+ * alone and must be specified. If the bucket is smaller than this, we
throw.
+ * @param key
+ * @param origRandom
+ * @throws IOException
+ */
+ public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize,
long knownSize, byte[] key, RandomSource origRandom) throws IOException {
+ if(bucket.size() < knownSize)
+ throw new IOException("Bucket is too small on disk -
knownSize="+knownSize+" but bucket.size="+bucket.size()+" for "+bucket);
+ this.dataLength = knownSize;
+ this.origRandom = origRandom;
+ this.bucket = bucket;
+ try {
+ aes = new Rijndael(256, 256);
+ } catch (UnsupportedCipherException e) {
+ throw new Error(e);
+ }
+ aes.initialize(key);
+ this.key = key;
+ this.minPaddedSize = minSize;
+ readOnly = false;
+ lastOutputStream = 0;
+ }
+
+ public PaddedEphemerallyEncryptedBucket(SimpleFieldSet fs, RandomSource
origRandom, PersistentFileTracker f) throws CannotCreateFromFieldSetException {
+ this.origRandom = origRandom;
+ String tmp = fs.get("DataLength");
+ if(tmp == null)
+ throw new CannotCreateFromFieldSetException("No
DataLength");
+ try {
+ dataLength = Long.parseLong(tmp);
+ } catch (NumberFormatException e) {
+ throw new CannotCreateFromFieldSetException("Corrupt
dataLength: "+tmp, e);
+ }
+ SimpleFieldSet underlying = fs.subset("Underlying");
+ if(underlying == null)
+ throw new CannotCreateFromFieldSetException("No
underlying bucket");
+ bucket = SerializableToFieldSetBucketUtil.create(underlying,
origRandom, f);
+ tmp = fs.get("DecryptKey");
+ if(tmp == null)
+ throw new CannotCreateFromFieldSetException("No key");
+ key = HexUtil.hexToBytes(tmp);
+ try {
+ aes = new Rijndael(256, 256);
+ } catch (UnsupportedCipherException e) {
+ throw new Error(e);
+ }
+ aes.initialize(key);
+ tmp = fs.get("MinPaddedSize");
+ if(tmp == null)
+ minPaddedSize = 1024; // FIXME throw! back
compatibility hack
+ else {
+ try {
+ minPaddedSize = Integer.parseInt(tmp);
+ } catch (NumberFormatException e) {
+ throw new
CannotCreateFromFieldSetException("Corrupt dataLength: "+tmp, e);
+ }
+ }
+ if(dataLength > bucket.size())
+ throw new CannotCreateFromFieldSetException("Underlying
bucket is too small: should be "+dataLength+" actually "+bucket.size());
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ if(readOnly) throw new IOException("Read only");
+ OutputStream os = bucket.getOutputStream();
+ synchronized(this) {
+ dataLength = 0;
+ }
+ return new PaddedEphemerallyEncryptedOutputStream(os,
++lastOutputStream);
+ }
+
+ private class PaddedEphemerallyEncryptedOutputStream extends
OutputStream {
+
+ final PCFBMode pcfb;
+ final OutputStream out;
+ final int streamNumber;
+ private boolean closed;
+
+ public PaddedEphemerallyEncryptedOutputStream(OutputStream out,
int streamNumber) {
+ this.out = out;
+ dataLength = 0;
+ this.streamNumber = streamNumber;
+ pcfb = new PCFBMode(aes);
+ }
+
+ public void write(int b) throws IOException {
+ if(closed) throw new IOException("Already closed!");
+ if(streamNumber != lastOutputStream)
+ throw new IllegalStateException("Writing to old
stream in "+getName());
+ if((b < 0) || (b > 255))
+ throw new IllegalArgumentException();
+ int toWrite = pcfb.encipher(b);
+ synchronized(PaddedEphemerallyEncryptedBucket.this) {
+ out.write(toWrite);
+ dataLength++;
+ }
+ }
+
+ public void write(byte[] buf, int offset, int length) throws
IOException {
+ if(closed) throw new IOException("Already closed!");
+ if(streamNumber != lastOutputStream)
+ throw new IllegalStateException("Writing to old
stream in "+getName());
+ byte[] enc = new byte[length];
+ System.arraycopy(buf, offset, enc, 0, length);
+ pcfb.blockEncipher(enc, 0, enc.length);
+ synchronized(PaddedEphemerallyEncryptedBucket.this) {
+ out.write(enc, 0, enc.length);
+ dataLength += enc.length;
+ }
+ }
+
+ // Override this or FOS will use write(int)
+ public void write(byte[] buf) throws IOException {
+ if(closed) throw new IOException("Already closed!");
+ if(streamNumber != lastOutputStream)
+ throw new IllegalStateException("Writing to old
stream in "+getName());
+ write(buf, 0, buf.length);
+ }
+
+ public void close() throws IOException {
+ if(closed) return;
+ try {
+ if(streamNumber != lastOutputStream) {
+ Logger.normal(this, "Not padding out to
length because have been superceded: "+getName());
+ return;
+ }
+
synchronized(PaddedEphemerallyEncryptedBucket.this) {
+ MersenneTwister paddingSource = new
MersenneTwister(origRandom.nextLong());
+ long finalLength = paddedLength();
+ long padding = finalLength - dataLength;
+ byte[] buf = new byte[4096];
+ long writtenPadding = 0;
+ while(writtenPadding < padding) {
+ int left = Math.min((int)
(padding - writtenPadding), buf.length);
+ paddingSource.nextBytes(buf);
+ out.write(buf, 0, left);
+ writtenPadding += left;
+ }
+ }
+ } finally {
+ closed = true;
+ out.close();
+ }
+ }
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new
PaddedEphemerallyEncryptedInputStream(bucket.getInputStream());
+ }
+
+ private class PaddedEphemerallyEncryptedInputStream extends InputStream
{
+
+ final InputStream in;
+ final PCFBMode pcfb;
+ long ptr;
+
+ public PaddedEphemerallyEncryptedInputStream(InputStream in) {
+ this.in = in;
+ pcfb = new PCFBMode(aes);
+ ptr = 0;
+ }
+
+ public int read() throws IOException {
+ if(ptr > dataLength) return -1;
+ int x = in.read();
+ if(x == -1) return x;
+ ptr++;
+ return pcfb.decipher(x);
+ }
+
+ public final int available() {
+ int x = (int)(dataLength - ptr);
+ return (x < 0) ? 0 : x;
+ }
+
+ public int read(byte[] buf, int offset, int length) throws
IOException {
+ // FIXME remove debugging
+ if((length+offset > buf.length) || (offset < 0) ||
(length < 0))
+ throw new
ArrayIndexOutOfBoundsException("a="+offset+", b="+length+", length
"+buf.length);
+ int x = available();
+ if(x <= 0) return -1;
+ length = Math.min(length, x);
+ int readBytes = in.read(buf, offset, length);
+ if(readBytes <= 0) return readBytes;
+ ptr += readBytes;
+ pcfb.blockDecipher(buf, offset, readBytes);
+ return readBytes;
+ }
+
+ public int read(byte[] buf) throws IOException {
+ return read(buf, 0, buf.length);
+ }
+
+ public long skip(long bytes) throws IOException {
+ byte[] buf = new byte[(int)Math.min(4096, bytes)];
+ long skipped = 0;
+ while(skipped < bytes) {
+ int x = read(buf, 0,
(int)Math.min(bytes-skipped, buf.length));
+ if(x <= 0) return skipped;
+ skipped += x;
+ }
+ return skipped;
+ }
+
+ public void close() throws IOException {
+ in.close();
+ }
+ }
+
+ /**
+ * Return the length of the data in the proxied bucket, after padding.
+ */
+ public synchronized long paddedLength() {
+ long size = dataLength;
+ if(size < minPaddedSize) size = minPaddedSize;
+ if(size == minPaddedSize) return size;
+ long min = minPaddedSize;
+ long max = minPaddedSize << 1;
+ while(true) {
+ if(max < 0)
+ throw new Error("Impossible size: "+size+" -
min="+min+", max="+max);
+ if(size < min)
+ throw new IllegalStateException("???");
+ if((size >= min) && (size <= max)) {
+ Logger.minor(this, "Padded: "+max+" was:
"+dataLength+" for "+getName());
+ return max;
+ }
+ min = max;
+ max = max << 1;
+ }
+ }
+
+ public String getName() {
+ return "Encrypted:"+bucket.getName();
+ }
+
+ public String toString() {
+ return super.toString()+":"+bucket.toString();
+ }
+
+ public synchronized long size() {
+ return dataLength;
+ }
+
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ public void setReadOnly() {
+ readOnly = true;
+ }
+
+ /**
+ * @return The underlying Bucket.
+ */
+ public Bucket getUnderlying() {
+ return bucket;
+ }
+
+ public void free() {
+ bucket.free();
+ }
+
+ /**
+ * Get the decryption key. May have been blanked out.
+ */
+ public byte[] getKey() {
+ return key;
+ }
+
+ public SimpleFieldSet toFieldSet() {
+ SimpleFieldSet fs = new SimpleFieldSet(true);
+ fs.put("Type", "PaddedEphemerallyEncryptedBucket");
+ synchronized(this) {
+ 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;
+ }
+ fs.put("MinPaddedSize", minPaddedSize);
+ return fs;
+ }
+
+}
Copied:
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
(from rev 9743,
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java)
===================================================================
---
trunk/freenet/src/freenet/support/PaddedEphemerallyEncryptedBucketFactory.java
2006-07-25 01:25:46 UTC (rev 9743)
+++
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -0,0 +1,31 @@
+package freenet.support.io;
+
+import java.io.IOException;
+
+import freenet.crypt.RandomSource;
+
+/**
+ * Factory wrapper for PaddedEphemerallyEncryptedBucket's, which are themselves
+ * wrappers.
+ */
+public class PaddedEphemerallyEncryptedBucketFactory implements BucketFactory {
+
+ final BucketFactory baseFactory;
+ final RandomSource random;
+ final int minSize;
+
+ public PaddedEphemerallyEncryptedBucketFactory(BucketFactory factory,
RandomSource r, int minSize) {
+ baseFactory = factory;
+ this.minSize = minSize;
+ this.random = r;
+ }
+
+ public Bucket makeBucket(long size) throws IOException {
+ return new
PaddedEphemerallyEncryptedBucket(baseFactory.makeBucket(size), minSize, random,
true);
+ }
+
+ public void freeBucket(Bucket b) throws IOException {
+
baseFactory.freeBucket(((PaddedEphemerallyEncryptedBucket)b).getUnderlying());
+ }
+
+}
Modified:
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
===================================================================
---
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
2006-07-25 16:14:02 UTC (rev 9751)
+++
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -2,8 +2,6 @@
import java.io.IOException;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
public class PersistentEncryptedTempBucketFactory implements BucketFactory {
Modified: trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -7,10 +7,7 @@
import java.util.LinkedList;
import freenet.crypt.RandomSource;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
/**
* Handles persistent temp files. These are used for e.g. persistent downloads.
Copied: trunk/freenet/src/freenet/support/io/RandomAccessFileBucket.java (from
rev 9746, trunk/freenet/src/freenet/support/RandomAccessFileBucket.java)
===================================================================
--- trunk/freenet/src/freenet/support/RandomAccessFileBucket.java
2006-07-25 14:10:01 UTC (rev 9746)
+++ trunk/freenet/src/freenet/support/io/RandomAccessFileBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -0,0 +1,466 @@
+// REDFLAG: test and javadoc
+package freenet.support.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.Vector;
+
+import freenet.support.Logger;
+import freenet.support.SimpleFieldSet;
+
+/**
+ * Bucket implementation that can efficiently access any arbitrary byte-range
+ * of a file.
+ *
+ **/
+public class RandomAccessFileBucket implements Bucket,
SerializableToFieldSetBucket {
+
+ private final File file;
+ private final long offset;
+ private long localOffset = 0;
+ private final long len;
+ private boolean readOnly = false;
+ private boolean released = false;
+ private Vector streams = new Vector();
+
+ public RandomAccessFileBucket(File file, long offset, long len, boolean
readOnly)
+ throws IOException {
+ if (!(file.exists() && file.canRead())) {
+ throw new IOException("Can't read file: " +
file.getAbsolutePath());
+ }
+
+ if ((!file.canWrite()) && (!readOnly)) {
+ throw new IOException("Can't write to file: " +
file.getAbsolutePath());
+ }
+
+ this.file = file;
+ this.readOnly = readOnly;
+ this.offset = offset;
+ this.len = len;
+ }
+
+ public RandomAccessFileBucket(SimpleFieldSet fs, PersistentFileTracker f)
throws CannotCreateFromFieldSetException {
+ String tmp = fs.get("Filename");
+ if(tmp == null) throw new CannotCreateFromFieldSetException("No
filename");
+ this.file = new File(tmp);
+ tmp = fs.get("Length");
+ if(tmp == null) throw new CannotCreateFromFieldSetException("No
length");
+ try {
+ len = Long.parseLong(tmp);
+ } catch (NumberFormatException e) {
+ throw new CannotCreateFromFieldSetException("Corrupt
length "+tmp, e);
+ }
+ tmp = fs.get("Offset");
+ if(tmp == null) throw new CannotCreateFromFieldSetException("No
offset");
+ try {
+ offset = Long.parseLong(tmp);
+ } catch (NumberFormatException e) {
+ throw new CannotCreateFromFieldSetException("Corrupt
offset "+tmp, e);
+ }
+ }
+
+ public static class Range {
+ Range(long offset, long len) {
+ this.offset = offset;
+ this.len = len;
+ }
+
+ public long offset;
+ public long len;
+ }
+
+ public final synchronized Range getRange() {
+ return new Range(offset, len);
+ }
+
+ // hmmm make protected???
+ public final synchronized boolean hasOpenStreams() {
+ return streams.size() > 0;
+ }
+
+ // Wrap non-const members so we can tell
+ // when code touches the Bucket after it
+ // has been released.
+ public synchronized InputStream getInputStream() throws IOException {
+ if (isReleased()) {
+ throw new IOException("Attempt to use a released
RandomAccessFileBucket: " + getName() );
+ }
+
+ InputStream newIn = new RAInputStream(file.getAbsolutePath());
+ streams.addElement(newIn);
+ return newIn;
+ }
+
+ public synchronized OutputStream getOutputStream() throws IOException {
+ if (isReleased()) {
+ throw new IOException("Attempt to use a released
RandomAccessBucket: " + getName() );
+ }
+
+ if (readOnly) {
+ throw new IOException("Tried to write a read-only Bucket.");
+ }
+
+ OutputStream newOut = new RAOutputStream(file.getAbsolutePath());
+ streams.addElement(newOut);
+ return newOut;
+ }
+
+ public String getName() {
+ return file.getAbsolutePath() + " [" + offset + ", " +
+ (offset + len - 1) + "]";
+ }
+
+ public synchronized void resetWrite() {
+ if (isReleased()) {
+ throw new RuntimeException("Attempt to use a released
RandomAccessFileBucket: " + getName() );
+ }
+ // REDFLAG: implicit assumptions
+ // 0) Bucket is only written to at a time.
+ // 1) The output stream is closed before the
+ // next is open. Ouch. This may cause problems...
+ localOffset = 0;
+ }
+
+ public long size() { return len; }
+
+ public synchronized boolean release() {
+ if (released) {
+ return true;
+ }
+
+ // Force all open streams closed.
+ // Windows won't let us delete the file unless we
+ // do this.
+ for (int i =0; i < streams.size(); i++) {
+ try {
+ if (streams.elementAt(i) instanceof InputStream) {
+ ((InputStream)streams.elementAt(i)).close();
+
+ Logger.debug(this, "closed open InputStream !: " +
+ file.getAbsolutePath());
+ }
+ else if (streams.elementAt(i) instanceof OutputStream) {
+ ((OutputStream)streams.elementAt(i)).close();
+ Logger.debug(this, "closed open OutputStream !: " +
+ file.getAbsolutePath());
+ }
+ }
+ catch (IOException ioe) {
+ }
+ }
+ streams.removeAllElements();
+ streams.trimToSize();
+ // We don't delete anything because we don't own anything.
+ released = true;
+ return true;
+ }
+
+ public synchronized final boolean isReleased() { return released; }
+
+ public void finalize() throws Throwable {
+ synchronized(this) {
+ if(released) return;
+ }
+ release();
+ }
+
+ // REDFLAG: RETEST
+ // set blocks = -1 for until end.
+ // last block may have length < blockSize
+ public static Bucket[] segment(File file, int blockSize,
+ long offset, int blocks, boolean readOnly)
+ throws IOException {
+
+ if (!(file.exists() && file.canRead())) {
+ throw new IOException("Can't read file: " +
file.getAbsolutePath());
+ }
+
+ if ((!file.canWrite()) && (!readOnly)) {
+ throw new IOException("Can't write to file: " +
file.getAbsolutePath());
+ }
+
+ if ((offset < 0) || (offset >= file.length() - 1)) {
+ throw new IllegalArgumentException("offset: " + offset);
+ }
+
+ long length = file.length() - offset;
+ int nBlocks = (int) (length / blockSize);
+ if ((length % blockSize) != 0) {
+ nBlocks++;
+ }
+
+ if (blocks == -1) {
+ blocks = nBlocks;
+ }
+ else if ((blocks > nBlocks) || (blocks < 1)) {
+ throw new IllegalArgumentException("blocks: " + blocks);
+ }
+
+ Bucket[] ret = new Bucket[blocks];
+
+ for (int i = 0; i < blocks; i++) {
+ final long localOffset = i * blockSize + offset;
+ int blockLen = blockSize;
+ if (i == nBlocks - 1) {
+ blockLen = (int) (length - (nBlocks - 1) * blockSize);
+ }
+ ret[i] = new RandomAccessFileBucket(file, localOffset, blockLen,
readOnly);
+ }
+
+ return ret;
+ }
+
+ ////////////////////////////////////////////////////////////
+ // InputStream and OutputStream implementations
+ //
+ private final static boolean vociferous = false;
+
+ class RAInputStream extends InputStream {
+ public RAInputStream(String prefix) throws IOException {
+ raf = new RandomAccessFile(file, "r");
+ raf.seek(offset);
+ println(" -- Created new InputStream [" + offset +
+ ", " + (offset + len -1) + "]" );
+ }
+
+ ////////////////////////////////////////////////////////////
+ // FilterInput implementation
+
+ private final int bytesLeft() throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ return (int)(offset + len -
raf.getFilePointer());
+ }
+ }
+
+ public int read() throws java.io.IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".read()");
+ checkValid();
+ if (bytesLeft() < 1) {
+ return -1; // EOF
+ }
+ return raf.read();
+ }
+ }
+
+ public int read(byte[] bytes) throws java.io.IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".read(byte[])");
+ checkValid();
+ int nAvailable = bytesLeft();
+ if (nAvailable < 1) {
+ return -1; // EOF
+ }
+ if (nAvailable > bytes.length) {
+ nAvailable = bytes.length;
+ }
+ return raf.read(bytes, 0, nAvailable);
+ }
+ }
+
+ public int read(byte[] bytes, int a, int b) throws java.io.IOException
{
+ synchronized (RandomAccessFileBucket.this) {
+ println(".read(byte[], int, int)");
+ checkValid();
+ int nAvailable = bytesLeft();
+ if (nAvailable < 1) {
+ return -1; // EOF
+ }
+ if (nAvailable > b) {
+ nAvailable = b;
+ }
+ return raf.read(bytes, a, nAvailable);
+ }
+ }
+
+ public long skip(long a) throws java.io.IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".skip(long)");
+ checkValid();
+ int nAvailable = bytesLeft();
+ if (nAvailable < 1) {
+ return -1; // EOF
+ }
+ if (nAvailable > a) {
+ nAvailable = (int)a;
+ }
+
+ return raf.skipBytes(nAvailable);
+ }
+ }
+
+ public int available() throws java.io.IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".available()");
+ checkValid();
+ return bytesLeft();
+ }
+ }
+
+ public void close() throws java.io.IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".close()");
+ checkValid();
+ raf.close();
+ if (streams.contains(RAInputStream.this)) {
+ streams.removeElement(RAInputStream.this);
+ }
+ streams.trimToSize();
+ }
+ }
+
+ // LATER: support if really needed.
+ public void mark(int a) {
+ // NOP
+ }
+
+ public void reset() {
+ // NOP
+ }
+
+ public boolean markSupported() {
+ return false;
+ }
+
+ private final void println(String text) {
+ if (vociferous) {
+ Logger.debug(this, text);
+ }
+ }
+
+ private final void checkValid() throws IOException {
+ synchronized(RandomAccessFileBucket.this) {
+ if (released) {
+ throw new IOException("Attempt to use a
released RandomAccessFileBucket: " + prefix);
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////
+ private RandomAccessFile raf = null;
+ private String prefix = "";
+ }
+
+ private class RAOutputStream extends OutputStream {
+ public RAOutputStream(String pref) throws IOException {
+ raf = new RandomAccessFile(file, "rw");
+ raf.seek(offset + localOffset);
+ println(" -- Created new OutputStream [" + offset + ", "
+ + (offset + len -1) + "]" );
+ }
+
+ ////////////////////////////////////////////////////////////
+ // OutputStream implementation
+ public void write(int b) throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".write(b)");
+ checkValid();
+ int nAvailable = bytesLeft();
+ if (nAvailable < 1) {
+ throw new IOException("Attempt to write past end of
Bucket.");
+ }
+ raf.write(b);
+ }
+ }
+
+ public void write(byte[] buf) throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".write(buf)");
+ checkValid();
+ int nAvailable = bytesLeft();
+ if (nAvailable < buf.length) {
+ throw new IOException("Attempt to write past end of
Bucket.");
+ }
+ raf.write(buf);
+ }
+ }
+
+ public void write(byte[] buf, int off, int len) throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".write(buf,off,len)");
+ checkValid();
+ int nAvailable = bytesLeft();
+ if (nAvailable < len) {
+ throw new IOException("Attempt to write past end of
Bucket.");
+ }
+ raf.write(buf, off, len);
+ }
+ }
+
+ public void flush() throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".flush()");
+ checkValid();
+ // NOP? Bytes written immediately?
+ // REDFLAG: double check.
+ }
+ }
+
+ public void close() throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ println(".close()");
+ checkValid();
+ if (streams.contains(RAOutputStream.this)) {
+ streams.removeElement(RAOutputStream.this);
+ }
+ streams.trimToSize();
+ long added = raf.getFilePointer() - offset;
+ if (added > 0) {
+ // To get proper append behavior.
+ localOffset = added;
+ }
+
+ raf.close();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////
+ private void println(String text) {
+ if (vociferous) {
+ Logger.debug(this, text);
+ }
+ }
+
+ private final void checkValid() throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ if (isReleased()) {
+ throw new IOException("Attempt to use a
released RandomAccessFileBucket: " + prefix);
+ }
+ }
+ }
+ private final int bytesLeft() throws IOException {
+ synchronized (RandomAccessFileBucket.this) {
+ return (int)(offset + len -
raf.getFilePointer());
+ }
+ }
+
+ private RandomAccessFile raf = null;
+ private String prefix = "";
+
+ }
+ ////////////////////////////////////////////////////////////
+
+ public synchronized boolean isReadOnly() {
+ return readOnly;
+ }
+
+ public synchronized void setReadOnly() {
+ readOnly = true;
+ }
+
+ public void free() {
+ release();
+ }
+
+ public synchronized 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;
+ }
+}
Copied: trunk/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java (from
rev 9743, trunk/freenet/src/freenet/support/ReadOnlyFileSliceBucket.java)
===================================================================
--- trunk/freenet/src/freenet/support/ReadOnlyFileSliceBucket.java
2006-07-25 01:25:46 UTC (rev 9743)
+++ trunk/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -0,0 +1,120 @@
+package freenet.support.io;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+
+/**
+ * FIXME: implement a hash verifying version of this.
+ */
+public class ReadOnlyFileSliceBucket implements Bucket {
+
+ private final File file;
+ private final long startAt;
+ private final long length;
+
+ public ReadOnlyFileSliceBucket(File f, long startAt, long length) {
+ this.file = f;
+ this.startAt = startAt;
+ this.length = length;
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ throw new IOException("Bucket is read-only");
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new MyInputStream();
+ }
+
+ public String getName() {
+ return "ROFS:"+file.getAbsolutePath()+":"+startAt+":"+length;
+ }
+
+ public long size() {
+ return length;
+ }
+
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ public void setReadOnly() {
+ // Do nothing
+ }
+
+ class MyInputStream extends InputStream {
+
+ private RandomAccessFile f;
+ private long ptr; // relative to startAt
+
+ MyInputStream() throws IOException {
+ try {
+ this.f = new RandomAccessFile(file,"r");
+ f.seek(startAt);
+ if(f.length() < (startAt+length))
+ throw new
ReadOnlyFileSliceBucketException("File truncated? Length "+f.length()+" but
start at "+startAt+" for "+length+" bytes");
+ ptr = 0;
+ } catch (FileNotFoundException e) {
+ throw new ReadOnlyFileSliceBucketException(e);
+ }
+ }
+
+ public int read() throws IOException {
+ if(ptr > length)
+ throw new EOFException();
+ int x = f.read();
+ ptr++;
+ return x;
+ }
+
+ public int read(byte[] buf, int offset, int len) throws
IOException {
+ if(ptr > length)
+ throw new EOFException();
+ len = (int) Math.min(len, length - ptr);
+ int x = f.read(buf, offset, len);
+ ptr += x;
+ return x;
+ }
+
+ public int read(byte[] buf) throws IOException {
+ return read(buf, 0, buf.length);
+ }
+
+ public void close() throws IOException {
+ f.close();
+ }
+
+ public void finalize() {
+ try {
+ close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
+ public class ReadOnlyFileSliceBucketException extends IOException {
+ private static final long serialVersionUID = -1;
+
+ public ReadOnlyFileSliceBucketException(FileNotFoundException
e) {
+ super("File not found: "+e.getMessage());
+ initCause(e);
+ }
+
+ public ReadOnlyFileSliceBucketException(String string) {
+ super(string);
+ }
+
+ }
+
+ public void free() {
+ // Do nothing
+ }
+
+}
Modified: trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucket.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,6 +1,5 @@
package freenet.support.io;
-import freenet.support.Bucket;
import freenet.support.SimpleFieldSet;
public interface SerializableToFieldSetBucket extends Bucket {
Modified:
trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
===================================================================
--- trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
2006-07-25 16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
2006-07-25 16:18:57 UTC (rev 9752)
@@ -1,9 +1,6 @@
package freenet.support.io;
import freenet.crypt.RandomSource;
-import freenet.support.Bucket;
-import freenet.support.PaddedEphemerallyEncryptedBucket;
-import freenet.support.RandomAccessFileBucket;
import freenet.support.SimpleFieldSet;
public class SerializableToFieldSetBucketUtil {
Modified: trunk/freenet/src/freenet/support/io/TempBucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/io/TempBucketFactory.java 2006-07-25
16:14:02 UTC (rev 9751)
+++ trunk/freenet/src/freenet/support/io/TempBucketFactory.java 2006-07-25
16:18:57 UTC (rev 9752)
@@ -3,8 +3,6 @@
import java.io.File;
import java.io.IOException;
-import freenet.support.Bucket;
-import freenet.support.BucketFactory;
import freenet.support.Logger;
/*