package com.limegroup.gnutella.messages.vendor; import java.io.IOException; import java.io.OutputStream; import com.limegroup.gnutella.ByteOrder; import com.limegroup.gnutella.GUID; import com.limegroup.gnutella.messages.BadPacketException; import com.limegroup.gnutella.statistics.SentMessageStatHandler; /** In Vendor Message parlance, the "message type" of this VMP is "BEAR/12". * This message contains 2 unsigned bytes that tells you how many * results the sending host has for the guid of a query (the guid of this * message is the same as the original query). */ public final class QueryStatusResponse extends VendorMessage { public static final int VERSION = 1; /** * Constructs a new QueryStatusResponse with data from the network. */ QueryStatusResponse(byte[] guid, byte ttl, byte hops, int version, byte[] payload) throws BadPacketException { super(guid, ttl, hops, F_BEAR_VENDOR_ID, F_REPLY_NUMBER, version, payload); if (getVersion() > VERSION) throw new BadPacketException("UNSUPPORTED VERSION"); if (getPayload().length != 2) throw new BadPacketException("UNSUPPORTED PAYLOAD LENGTH: " + getPayload().length); } /** * Constructs a new QueryStatus response to be sent out. * @param numResults The number of results (1-65535) that you have * for this query. If you have more than 65535 just send 65535. * @param replyGUID The guid of the original query/reply that you want to * send reply info for. */ public QueryStatusResponse(GUID replyGUID, int numResults) { super(F_BEAR_VENDOR_ID, F_REPLY_NUMBER, VERSION, derivePayload(numResults)); setGUID(replyGUID); } /** @return an int (1-65535) representing the amount of results that a host * for a given query (as specified by the guid of this message). */ public int getNumResults() { return ByteOrder.ushort2int(ByteOrder.leb2short(getPayload(), 0)); } /** The query guid that this response refers to. */ public GUID getQueryGUID() { return new GUID(getGUID()); } /** * Constructs the payload from the desired number of results. */ private static byte[] derivePayload(int numResults) { if ((numResults < 0) || (numResults > 65535)) throw new IllegalArgumentException("Number of results too big: " + numResults); byte[] payload = new byte[2]; ByteOrder.short2leb((short) numResults, payload, 0); return payload; } /** Overridden purely for stats handling. */ protected void writePayload(OutputStream out) throws IOException { super.writePayload(out); SentMessageStatHandler.UDP_REPLY_NUMBER.addMessage(this); } /** Overridden purely for stats handling. */ public void recordDrop() { super.recordDrop(); } }