QueryHitMessage.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
xnap.plugin.gnutella.net |
![]() |
![]() |
XNap 2 |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* 03/30/2001
*
* QueryHitMessage.java
* Copyright (C) 2001 Frederik Zimmer
* tristian@users.sourceforge.net
* http://sourceforge.net/projects/ziga/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package xnap.plugin.gnutella.net;
import xnap.plugin.gnutella.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.HashMap;
import java.io.IOException;
import java.io.EOFException;
import java.util.zip.InflaterInputStream;
public class QueryHitMessage extends Message
{
//--- Data field(s) ---
private static final int PAYLOAD_LENGTH = 67092;
protected static final String VENDORCODE = "XNAP";
protected static final String LIME_VENDORCODE = "LIME";
protected static final int MAX_COMPRESSION_HEADER_LENGTH = 11;
protected static final char COMPRESSION_HEADER_START = '{';
protected static final String NO_COMPRESSION = "{plaintext}";
protected static final String DEFLATE_COMPRESSION = "{deflate}";
protected int hits;
protected int port;
protected byte[] ip;
protected int speed;
protected ResultSet[] results;
protected GUID serventID;
protected String vendorcode = null;
protected boolean haveExtendedDescriptor;
protected byte openDataSize;
protected byte firstOpenDataByte;
protected byte secondOpenDataByte;
protected byte[] privateData;
protected byte[] xmlMetadata;
protected boolean chat;
protected boolean isLimechat;
//--- Constructor(s) ---
public QueryHitMessage(DescriptorHeader header, DataInputStream in)
throws IOException, InvalidMessageException
{
super(header);
if (header.payloadLength > PAYLOAD_LENGTH) {
throw new InvalidMessageException("Payload length too high");
}
read(in);
}
public QueryHitMessage(GUID id, int port, byte[] ip, int speed,
ResultSet[] results, GUID serventID)
{
super(id, DescriptorHeader.QUERY_HIT,
QueryHitMessage.getLength(results, null));
hits = results.length;
if (port <= 0 || port > 0xFFFF) {
throw new IllegalArgumentException("Invalid port " + port);
}
this.port = port;
this.ip = ip;
this.speed = speed;
this.results = results;
this.serventID = serventID;
haveExtendedDescriptor = false;
}
public QueryHitMessage(GUID id, int port, byte[] ip, int speed,
ResultSet[] results, GUID serventID,
boolean uploadSpeedFlag, boolean haveUploadedFlag,
boolean busyFlag, boolean pushFlag, boolean chat,
byte[] xmlMetadata)
{
super(id, DescriptorHeader.QUERY_HIT,
QueryHitMessage.getLength(results, xmlMetadata)+8);
hits = results.length;
if (port <= 0 || port > 0xFFFF) {
throw new IllegalArgumentException("Invalid port " + port);
}
this.port = port;
this.ip = ip;
this.speed = speed;
this.results = results;
this.serventID = serventID;
this.xmlMetadata = xmlMetadata;
haveExtendedDescriptor = true;
openDataSize = (byte) (xmlMetadata == null ? 2 : 4);
firstOpenDataByte = 28;
secondOpenDataByte = 0;
secondOpenDataByte = setBit(secondOpenDataByte, 0);
if (uploadSpeedFlag) {
secondOpenDataByte = setBit(secondOpenDataByte, 4);
}
if (haveUploadedFlag) {
secondOpenDataByte = setBit(secondOpenDataByte, 3);
}
if (busyFlag) {
secondOpenDataByte = setBit(secondOpenDataByte, 2);
}
if (pushFlag) {
firstOpenDataByte += 1;
}
privateData = new byte[1];
privateData[0] = (byte) (chat ? 1 : 0);
this.chat = chat;
}
public void write(DataOutputStream out)
throws IOException
{
super.write(out);
out.write((byte) hits);
out.writeShort((short)port);
out.write(ip);
out.writeInt(speed);
for (int i = 0; i < results.length; i++) {
results[i].write(out);
}
if (haveExtendedDescriptor) {
out.writeBytes(VENDORCODE);
out.write(openDataSize);
out.write(firstOpenDataByte);
out.write(secondOpenDataByte);
if (xmlMetadata != null) {
short xmlMetadataLength = (short) (xmlMetadata.length + 1);
out.writeShort(xmlMetadataLength);
}
if (privateData != null) {
out.write(privateData);
}
if (xmlMetadata != null) {
out.write(xmlMetadata);
out.write(0);
}
}
out.write(serventID.getBytes());
}
public void read(DataInputStream in)
throws IOException, InvalidMessageException
{
byte[] id = new byte[16];
ip = new byte[4];
int dataLength = header.payloadLength - 27;
byte[] data = new byte[dataLength];
int i = 0;
int resultOffset;
int hitsread = 0;
hits = in.readUByte();
if (hits < 1) {
throw new InvalidMessageException("QueryHit has no hits");
}
results = new ResultSet[hits];
port = in.readUShort();
in.readFully(ip);
speed = in.readInt();
in.readFully(data);
while (hitsread < hits) {
resultOffset = i;
i += 8;
for(int k = 0; k != 2; i++) {
if (i >= dataLength) {
throw new EOFException();
}
if (data[i] == 0) {
k++;
}
}
results[hitsread] = ResultSet.read(data, resultOffset,
i - resultOffset - 1);
hitsread++;
}
if (hitsread != hits) {
throw new InvalidMessageException("Number of reported hits "
+ "doesn't match hits read");
}
if (i+5 < dataLength) {
haveExtendedDescriptor = true;
int trailersize = dataLength-i;
vendorcode = new String(data, i, 4);
i += 4;
openDataSize = data[i++];
if (openDataSize < 0) {
throw new InvalidMessageException("Negative opendata size");
}
if (openDataSize >= 2 && i+2 < dataLength) {
firstOpenDataByte = data[i];
secondOpenDataByte = data[i+1];
if (openDataSize >= 4 && i+4 < dataLength) {
short xmlMetadataSize = (short) ((data[i+2] & 0xFF) | ((data[i+3] & 0xFF) << 8));
if (data[dataLength-1] == 0) {
if (xmlMetadataSize > 1) {
xmlMetadata = new byte[xmlMetadataSize-1];
System.arraycopy(data, dataLength-xmlMetadataSize, xmlMetadata, 0, xmlMetadata.length);
}
}
}
}
else {
haveExtendedDescriptor = false;
}
i += openDataSize;
int privateDataSize = xmlMetadata == null ? dataLength-i : dataLength-xmlMetadata.length-1-i;
if (privateDataSize >= 1 && (vendorcode.equals(VENDORCODE) || (isLimechat = vendorcode.equals(LIME_VENDORCODE)))) {
chat = getBit(data[i], 0);
}
if (privateDataSize > 0) {
privateData = new byte[privateDataSize];
System.arraycopy(data, i, privateData, 0, privateData.length);
}
}
else {
haveExtendedDescriptor = false;
}
in.readFully(id);
serventID = new GUID(id);
}
public GUID getServentID() {
return serventID;
}
public String getIP() {
if (ip.length != 4) {
return null;
}
StringBuffer sb = new StringBuffer();
sb.append(ip[0] & 0xFF);
sb.append('.');
sb.append(ip[1] & 0xFF);
sb.append('.');
sb.append(ip[2] & 0xFF);
sb.append('.');
sb.append(ip[3] & 0xFF);
return sb.toString();
}
private static int getLength(ResultSet[] rs, byte[] xmlMetadata) {
int length = 27;
for (int i = 0; i < rs.length; i++) {
length += rs[i].length;
}
if (xmlMetadata != null) {
length += xmlMetadata.length;
length += 3;
}
return length;
}
// public ExtendedResultSet[] getExtendedResultSet() {
// ExtendedResultSet[] ers = new ExtendedResultSet[results.length];
// String ip = getIP();
// boolean uploadSpeedFlag;
// boolean haveUploadedFlag;
// boolean busyFlag;
// boolean pushFlag;
// pushFlag = isPrivateAddress(this.ip);
// if (haveExtendedDescriptor) {
// if (getBit(firstOpenDataByte, 4)) {
// uploadSpeedFlag = getBit(secondOpenDataByte, 4);
// }
// else {
// uploadSpeedFlag = false;
// }
// if (getBit(firstOpenDataByte, 3)) {
// haveUploadedFlag = getBit(secondOpenDataByte, 3);
// }
// else {
// haveUploadedFlag = true;
// }
// if (getBit(firstOpenDataByte, 2)) {
// busyFlag = getBit(secondOpenDataByte, 2);
// }
// else {
// busyFlag = false;
// }
// if (getBit(secondOpenDataByte, 0)) {
// pushFlag |= getBit(firstOpenDataByte, 0);
// }
// }
// else {
// for (int i = 0; i < results.length; i++) {
// ers[i] = new ExtendedResultSet(header.messageID, ip, port,
// speed, serventID, results[i],
// pushFlag);
// }
// }
// return ers;
// }
protected boolean isPrivateAddress(byte[] ip) {
return ((ip[0] == (byte) 192 && ip[1] == (byte) 168)
|| ip[0] == (byte) 10 || ip[0] == (byte) 127
|| (ip[0] == (byte) 172 && ip[1] >= (byte) 16
&& ip[1] <= (byte) 31));
}
private byte setBit(byte b, int nBit) {
return (byte) (b | (1 << nBit));
}
private boolean getBit(int b, int nBit) {
return (b & (1 << nBit)) > 0 ? true : false;
}
public ResultSet[] getResults()
{
return results;
}
public int getPort()
{
return port;
}
}
The table below shows all metrics for QueryHitMessage.java.




