-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMessage.java
More file actions
88 lines (68 loc) · 2.89 KB
/
Message.java
File metadata and controls
88 lines (68 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.nio.charset.StandardCharsets;
import java.util.BitSet;
public class Message {
private static final int LENGTH = 4;
private static final int TYPE_LENGTH = 1;
public static final int TYPE_CHOKE = 0;
public static final int TYPE_UNCHOKE = 1;
public static final int TYPE_INTERESTED = 2;
public static final int TYPE_NOT_INTERESTED = 3;
public static final int TYPE_HAVE = 4;
public static final int TYPE_BITFIELD = 5;
public static final int TYPE_REQUEST = 6;
public static final int TYPE_PIECE = 7;
private int length;
private int type;
private Payload payload;
private Message(){
//do nothing
}
private Message(int length, int type, Payload payload){
this.length = length;
this.type = type;
this.payload = payload;
}
public byte[] toBytes(){
byte[] payloadBytes = this.payload.toBytes();
byte[] output = new byte[payloadBytes.length + TYPE_LENGTH + LENGTH];
byte[] typeBuffer = new byte[]{(byte)this.type};
byte[] messageLengthBuffer = ApplicationUtil.intToBytes(typeBuffer.length + payloadBytes.length);
System.arraycopy(messageLengthBuffer, 0, output, 0, LENGTH);
System.arraycopy(typeBuffer, 0, output, LENGTH, TYPE_LENGTH);
System.arraycopy(payloadBytes, 0, output, LENGTH + TYPE_LENGTH, payloadBytes.length);
return output;
}
public static Message createMessage(byte[] bytes){
int type = bytes[0];
byte[] payloadBytes = new byte[bytes.length - TYPE_LENGTH];
System.arraycopy(bytes, TYPE_LENGTH, payloadBytes, 0, payloadBytes.length);
switch(type){
case TYPE_CHOKE:
case TYPE_INTERESTED:
case TYPE_NOT_INTERESTED:
case TYPE_UNCHOKE: return new Message(bytes.length, type, new EmptyPayload());
case TYPE_HAVE:
case TYPE_REQUEST: return new Message(bytes.length, type, new PieceIndexPayload(payloadBytes));
case TYPE_BITFIELD: return new Message(bytes.length, type, new BitFieldPayload(payloadBytes));
default: return new Message(bytes.length, type, new PiecePayload(payloadBytes));
}
}
public static Message createMessage(int type){
return new Message(TYPE_LENGTH, type, new EmptyPayload());
}
public static Message createMessage(int type, int pieceIndex){
return new Message(TYPE_LENGTH, type, new PieceIndexPayload(pieceIndex));
}
public static Message createMessage(int type, int pieceIdx, byte[] bytes){
return new Message(TYPE_LENGTH, type, new PiecePayload(pieceIdx, bytes));
}
public static Message createMessage(int type, BitSet bitset){
return new Message(TYPE_LENGTH, type, new BitFieldPayload(bitset));
}
public int getType(){
return this.type;
}
public Payload getPayload(){
return this.payload;
}
}