package freenet.client.async;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import freenet.client.InsertContext;
import freenet.client.InsertContext.CompatibilityMode;
import freenet.support.Logger;
import freenet.support.io.StorageFormatException;
public class CompatibilityAnalyser implements Serializable {
private static final long serialVersionUID = 1L;
CompatibilityMode min;
CompatibilityMode max;
byte[] cryptoKey;
boolean dontCompress;
boolean definitive;
public CompatibilityAnalyser() {
this.min = CompatibilityMode.COMPAT_UNKNOWN;
this.max = CompatibilityMode.COMPAT_UNKNOWN;
}
public void merge(CompatibilityMode min, CompatibilityMode max, byte[] cryptoKey, boolean dontCompress, boolean definitive) {
if(this.definitive) {
Logger.warning(this, "merge() after definitive", new Exception("debug"));
return;
}
assert(min != CompatibilityMode.COMPAT_CURRENT);
assert(max != CompatibilityMode.COMPAT_CURRENT);
if(definitive) this.definitive = true;
if(!dontCompress) this.dontCompress = false;
if(min.ordinal() > this.min.ordinal()) this.min = min;
if(max.ordinal() < this.max.ordinal() || this.max == CompatibilityMode.COMPAT_UNKNOWN) this.max = max;
if(this.cryptoKey == null) {
this.cryptoKey = cryptoKey;
} else if(cryptoKey != null && !Arrays.equals(this.cryptoKey, cryptoKey)) {
Logger.error(this, "Two different crypto keys!");
this.cryptoKey = null;
}
}
public CompatibilityMode min() {
return min;
}
public CompatibilityMode max() {
return max;
}
public byte[] getCryptoKey() {
return cryptoKey;
}
public boolean dontCompress() {
return dontCompress;
}
public boolean definitive() {
return definitive;
}
public InsertContext.CompatibilityMode[] getModes() {
return new InsertContext.CompatibilityMode[] { min(), max() };
}
static final int VERSION = 2;
public void writeTo(DataOutputStream dos) throws IOException {
dos.writeInt(VERSION);
dos.writeShort(min.code);
dos.writeShort(max.code);
if(cryptoKey == null) {
dos.writeBoolean(false);
} else {
dos.writeBoolean(true);
assert(cryptoKey.length == 32);
dos.write(cryptoKey);
}
dos.writeBoolean(dontCompress);
dos.writeBoolean(definitive);
}
public CompatibilityAnalyser(DataInputStream dis) throws IOException, StorageFormatException {
int ver = dis.readInt();
if(ver != VERSION) throw new StorageFormatException("Unknown version for CompatibilityAnalyser");
try {
min = CompatibilityMode.byCode(dis.readShort());
max = CompatibilityMode.byCode(dis.readShort());
} catch (IllegalArgumentException e) {
throw new StorageFormatException("Bad min value");
}
if(dis.readBoolean()) {
cryptoKey = new byte[32];
dis.readFully(cryptoKey);
}
dontCompress = dis.readBoolean();
definitive = dis.readBoolean();
}
}