package freenet.clients.fcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import freenet.support.SimpleFieldSet;
import freenet.support.api.Bucket;
import freenet.support.api.BucketFactory;
import freenet.support.io.BucketTools;
public abstract class MultipleDataCarryingMessage extends BaseDataCarryingMessage {
//The iteration order matters, hence a LinkedHashMap
protected Map<String, Bucket> buckets = new LinkedHashMap<String, Bucket>();
protected boolean freeOnSent;
void setFreeOnSent() {
freeOnSent = true;
}
//We can't read an arbitrary multiple data carrying message from an InputStream
//This class is only used to send such messages to the client
@Override
public void readFrom(InputStream is, BucketFactory bf, FCPServer server) throws IOException, MessageInvalidException {
throw new UnsupportedOperationException();
}
@Override
protected void writeData(OutputStream os) throws IOException {
for(Map.Entry<String, Bucket> entry : buckets.entrySet()) {
Bucket bucket = entry.getValue();
BucketTools.copyTo(bucket, os, bucket.size());
if(freeOnSent) bucket.free(); // Always transient so no removeFrom() needed.
}
}
@Override
public SimpleFieldSet getFieldSet() {
int dataLength = 0;
SimpleFieldSet fs = new SimpleFieldSet(true);
for(Map.Entry<String, Bucket> entry : buckets.entrySet()) {
String field = entry.getKey();
Bucket bucket = entry.getValue();
fs.put(field + "Length", bucket.size());
dataLength += bucket.size();
}
fs.put("DataLength", dataLength);
return fs;
}
@Override
public long dataLength() {
int dataLength = 0;
for(Bucket bucket : buckets.values())
dataLength += bucket.size();
return dataLength;
}
@Override
String getEndString() {
return "Data";
}
}