package freenet.clients.fcp; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; /** Identifies a request and its client. Stable serialization format - must not change without * version bump, must maintain back compatibility within reason. This is initially used to check * for whether we've already loaded a request, but it will also be used for last-resort restarting * a request when serialization has failed. * @author toad */ public final class RequestIdentifier { enum RequestType { // Ordinals matter! GET, PUT, PUTDIR } static final int MAGIC = 0x25ebd38d; static final short VERSION = 1; final boolean globalQueue; final String clientName; final String identifier; public final RequestType type; public RequestIdentifier(boolean globalQueue, String clientName, String identifier, RequestType type) { this.globalQueue = globalQueue; this.clientName = clientName; this.identifier = identifier; this.type = type; } public RequestIdentifier(DataInput dis) throws IOException { int magic = dis.readInt(); if(magic != MAGIC) throw new IOException("Bad magic"); short version = dis.readShort(); if(version != VERSION) throw new IOException("Bad version"); this.globalQueue = dis.readBoolean(); if(globalQueue) clientName = null; else clientName = dis.readUTF(); identifier = dis.readUTF(); RequestType[] types = RequestType.values(); short typeKey = dis.readShort(); if(typeKey < 0 || typeKey >= types.length) throw new IOException("Bogus type"); type = types[typeKey]; } public void writeTo(DataOutput dos) throws IOException { dos.writeInt(MAGIC); dos.writeShort(VERSION); dos.writeBoolean(globalQueue); if(!globalQueue) dos.writeUTF(clientName); dos.writeUTF(identifier); dos.writeShort(type.ordinal()); } /** Only compare the identifier, not the type. */ public boolean sameIdentifier(RequestIdentifier other) { if(globalQueue != other.globalQueue) return false; if(!globalQueue) { if(!clientName.equals(other.clientName)) return false; } if (globalQueue != other.globalQueue) return false; if(!identifier.equals(other.identifier)) return false; return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((clientName == null) ? 0 : clientName.hashCode()); result = prime * result + (globalQueue ? 1231 : 1237); result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); // Intentionally don't include the type at all. return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if(!(obj instanceof RequestIdentifier)) return false; RequestIdentifier other = (RequestIdentifier) obj; if(globalQueue != other.globalQueue) return false; if(!globalQueue) { if(!clientName.equals(other.clientName)) return false; } if (globalQueue != other.globalQueue) return false; if(!identifier.equals(other.identifier)) return false; if (type != other.type) return false; return true; } }