package com.limegroup.gnutella.messages.vendor;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.limegroup.gnutella.ErrorService;
import com.limegroup.gnutella.messages.BadGGEPBlockException;
import com.limegroup.gnutella.messages.BadGGEPPropertyException;
import com.limegroup.gnutella.messages.BadPacketException;
import com.limegroup.gnutella.messages.GGEP;
public final class UpdateResponse extends VendorMessage {
private static final int NON_GGEP_VERSION = 1;
public static final int VERSION = 2;
private byte [] update;
/**
* Constructs a new UpdateResponse message from the network.
*/
UpdateResponse(byte[] guid, byte ttl, byte hops, int version, byte[] payload)
throws BadPacketException {
super(guid, ttl, hops, F_LIME_VENDOR_ID, F_UPDATE_RESP, version, payload);
if (version == NON_GGEP_VERSION)
update = payload;
else {
// try to parse a GGEP block
try {
GGEP ggep = new GGEP(payload,0,null);
if (ggep.hasKey(UpdateRequest.UNCOMPRESSED_UPDATE_KEY))
update = ggep.getBytes(UpdateRequest.UNCOMPRESSED_UPDATE_KEY);
else if (ggep.hasKey(UpdateRequest.COMPRESSED_UPDATE_KEY))
update = ggep.getBytes(UpdateRequest.COMPRESSED_UPDATE_KEY);
else throw new BadPacketException("no update in GGEP?");
} catch (BadGGEPPropertyException bad) {
throw new BadPacketException("bad ggep property");
} catch (BadGGEPBlockException notSoBad) {
update = payload;
}
}
}
/**
* Constructs an outgoing message with the payload being the signed parameter body.
*/
private UpdateResponse(byte[] body, int version) {
super(F_LIME_VENDOR_ID, F_UPDATE_RESP, version, body);
}
public static UpdateResponse createUpdateResponse(byte [] update, UpdateRequest request) {
if (!request.hasGGEP())
return new UpdateResponse(update, NON_GGEP_VERSION);
GGEP ggep = new GGEP(true);
if (request.requestsCompressed()) {
ggep.putCompressed(UpdateRequest.COMPRESSED_UPDATE_KEY,update);
} else
ggep.put(UpdateRequest.UNCOMPRESSED_UPDATE_KEY,update);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ggep.write(baos);
} catch (IOException bad) {
ErrorService.error(bad);
}
return new UpdateResponse(baos.toByteArray(),VERSION);
}
public byte[] getUpdate() {
return update;
}
}