package network.message;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.Ints;
import network.Peer;
public class PeersMessage extends Message {
private static final int ADDRESS_LENGTH = 4;
private static final int DATA_LENGTH = 4;
private List<Peer> peers;
public PeersMessage(List<Peer> peers)
{
super(Message.PEERS_TYPE);
this.peers = peers;
}
public List<Peer> getPeers()
{
return this.peers;
}
public static PeersMessage parse(byte[] data) throws Exception
{
//READ LENGTH
byte[] lengthBytes = Arrays.copyOfRange(data, 0, DATA_LENGTH);
int length = Ints.fromByteArray(lengthBytes);
//CHECK IF DATA MATCHES LENGTH
if(data.length != DATA_LENGTH + (length * ADDRESS_LENGTH))
{
throw new Exception("Data does not match length");
}
//CREATE PEER LIST
List<Peer> peers = new ArrayList<Peer>();
for(int i=0; i<length; i++)
{
//CALCULATE POSITION
int position = lengthBytes.length + (i * ADDRESS_LENGTH);
//READ ADDRESS
byte[] addressBytes = Arrays.copyOfRange(data, position, position + ADDRESS_LENGTH);
InetAddress address = InetAddress.getByAddress(addressBytes);
//CREATE PEER
Peer peer = new Peer(address);
//ADD TO LIST
peers.add(peer);
}
return new PeersMessage(peers);
}
@Override
public byte[] toBytes()
{
byte[] data = new byte[0];
//WRITE LENGTH
int length = this.peers.size();
byte[] lengthBytes = Ints.toByteArray(length);
lengthBytes = Bytes.ensureCapacity(lengthBytes, DATA_LENGTH, 0);
data = Bytes.concat(data, lengthBytes);
//WRITE PEERS
for(Peer peer: this.peers)
{
//WRITE ADDRESS
byte[] addressBytes = peer.getAddress().getAddress();
data = Bytes.concat(data, addressBytes);
}
//ADD CHECKSUM
data = Bytes.concat(super.toBytes(), this.generateChecksum(data), data);
return data;
}
@Override
public int getDataLength()
{
return DATA_LENGTH + (this.peers.size() * ADDRESS_LENGTH);
}
}