Début de l’implémentation du protocole binaire
Reste des TODO dans FileList.java et dans FilePart.java + la documentation à faire. Ça ne compile pas encore, et c’est normal (à cause des TODOs).pull/1/head
parent
f4e318dfe5
commit
026008473a
@ -0,0 +1,5 @@
|
|||||||
|
package protocolP2P;
|
||||||
|
public enum CodeType {
|
||||||
|
REQUEST,
|
||||||
|
RESPONSE
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package protocolP2P;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import protocolP2P.Payload;
|
||||||
|
import protocolP2P.RequestResponseCode;
|
||||||
|
import exception.ProtocolError;
|
||||||
|
|
||||||
|
public class FileList extends Payload {
|
||||||
|
private final static RequestResponseCode requestResponseCode = RequestResponseCode.LIST_RESPONSE;
|
||||||
|
private ArrayList<String> content;
|
||||||
|
|
||||||
|
public FileList(ArrayList<String> content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileList(byte[] datagram) throws ProtocolError {
|
||||||
|
//TODO
|
||||||
|
assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) == RequestResponseCode.LIST_RESPONSE : "FileList subclass is incompatible with this datagram, request/response code must be checked before using this constructor";
|
||||||
|
int size = (datagram[PAYLOAD_SIZE_POSITON] << (8*3)) | (datagram[PAYLOAD_SIZE_POSITON+1] << (8*2)) | (datagram[PAYLOAD_SIZE_POSITON+2] << 8) | datagram[PAYLOAD_SIZE_POSITON+3];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** To datagram with padding */
|
||||||
|
public byte[] toDatagram() {
|
||||||
|
byte[] datagram; // java initialize all to zero
|
||||||
|
// size is keep blank (ProtocolP2PDatagram will handle it)
|
||||||
|
// set request/response code
|
||||||
|
datagram[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||||
|
// bits 16-31 are reserved for future use
|
||||||
|
//TODO size
|
||||||
|
int size = ;
|
||||||
|
for(i=0;i<4;i++) {
|
||||||
|
datagram[Payload.PAYLOAD_SIZE_POSITON + i] = (byte) (size >> (8 * (3 - i)) & 0xFF);
|
||||||
|
}
|
||||||
|
//TODO content
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package protocolP2P;
|
||||||
|
import protocolP2P.Payload;
|
||||||
|
import protocolP2P.RequestResponseCode;
|
||||||
|
import exception.ProtocolError;
|
||||||
|
|
||||||
|
public class FilePart extends Payload {
|
||||||
|
private static final RequestResponseCode requestResponseCode = RequestResponseCode.LOAD_RESPONSE;
|
||||||
|
private String filename;
|
||||||
|
private int totalSize;
|
||||||
|
private int offset;
|
||||||
|
private byte[] partialContent;
|
||||||
|
|
||||||
|
public FilePart(String filename, int totalSize, int offset, byte[] partialContent) {
|
||||||
|
this.filename = filename;
|
||||||
|
this.totalSize = totalSize;
|
||||||
|
this.offset = offset;
|
||||||
|
this.partialContent = partialContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilePart(byte[] datagram) throws ProtocolError {
|
||||||
|
//TODO
|
||||||
|
assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) == RequestResponseCode.LOAD_RESPONSE : "FilePart subclass is incompatible with this datagram, request/response code must be checked before using this constructor";
|
||||||
|
int size = (datagram[PAYLOAD_SIZE_POSITON] << (8*3)) | (datagram[PAYLOAD_SIZE_POSITON+1] << (8*2)) | (datagram[PAYLOAD_SIZE_POSITON+2] << 8) | datagram[PAYLOAD_SIZE_POSITON+3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** To datagram with padding */
|
||||||
|
public byte[] toDatagram() {
|
||||||
|
byte[] datagram; // java initialize all to zero
|
||||||
|
// size is keep blank (ProtocolP2PDatagram will handle it)
|
||||||
|
// set request/response code
|
||||||
|
datagram[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||||
|
// bits 16-31 are reserved for future use
|
||||||
|
//TODO size
|
||||||
|
int size = ;
|
||||||
|
for(i=0;i<4;i++) {
|
||||||
|
datagram[Payload.PAYLOAD_SIZE_POSITON + i] = (byte) (size >> (8 * (3 - i)) & 0xFF);
|
||||||
|
}
|
||||||
|
//TODO content
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package protocolP2P;
|
||||||
|
import protocolP2P.RequestResponseCode;
|
||||||
|
import protocolP2P.FilePart;
|
||||||
|
import protocolP2P.FileList;
|
||||||
|
import exception.ProtocolError;
|
||||||
|
|
||||||
|
public class Payload {
|
||||||
|
private RequestResponseCode requestResponseCode;
|
||||||
|
protected final static int PAYLOAD_SIZE_POSITON = 4;
|
||||||
|
protected final static int PAYLOAD_START_POSITION = 8;
|
||||||
|
|
||||||
|
/** To create request/response with a payload size of zero */
|
||||||
|
public Payload(RequestResponseCode requestResponseCode) {
|
||||||
|
assert requestResponseCode != requestResponseCode.LIST_RESPONSE : "LIST_RESPONSE must use FilePart class";
|
||||||
|
assert requestResponseCode != requestResponseCode.LOAD_RESPONSE : "LOAD_RESPONSE must use FileList class";
|
||||||
|
this.requestResponseCode = requestResponseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Payload(byte[] datagram) throws ProtocolError {
|
||||||
|
assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LIST_RESPONSE : "LIST_RESPONSE must use FilePart class";
|
||||||
|
assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LOAD_RESPONSE : "LOAD_RESPONSE must use FileList class";
|
||||||
|
requestResponseCode = RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Payload with padding */
|
||||||
|
public byte[] toDatagram() {
|
||||||
|
byte [] datagram = new byte[8]; // java initialize all to zero
|
||||||
|
// size is keep blank (ProtocolP2PDatagram will handle it)
|
||||||
|
// set request/response code
|
||||||
|
datagram[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||||
|
// bits 16-31 are reserved for future use
|
||||||
|
// payload size is 0 (this is what java have initialized datagram)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package protocolP2P;
|
||||||
|
import exception.ProtocolError;
|
||||||
|
import protocolP2P.Payload;
|
||||||
|
import protocolP2P.RequestResponseCode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.lang.Byte;
|
||||||
|
|
||||||
|
public class ProtocolP2PDatagram {
|
||||||
|
private final static byte PROTOCOL_VERSION = 0x11;
|
||||||
|
private final static int VERSION_POSITON = 0;
|
||||||
|
private byte version;
|
||||||
|
private Payload payload;
|
||||||
|
|
||||||
|
public ProtocolP2PDatagram(Payload payload) {
|
||||||
|
version = PROTOCOL_VERSION;
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtocolP2PDatagram(byte[] datagram) throws ProtocolError {
|
||||||
|
// unwrap version
|
||||||
|
version = datagram[VERSION_POSITON];
|
||||||
|
checkProtocolVersion(); // this can throw ProtocolError
|
||||||
|
RequestResponseCode r = RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]); // this can throw ProtocolError
|
||||||
|
switch (r) {
|
||||||
|
case RequestResponseCode.LIST_RESPONSE:
|
||||||
|
payload = (Payload) new FileList(datagram);
|
||||||
|
break;
|
||||||
|
case RequestResponseCode.LOAD_RESPONSE:
|
||||||
|
payload = (Payload) new FilePart(datagram);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
payload = new Payload(datagram);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toDatagram() {
|
||||||
|
byte[] datagram = payload.toDatagram();
|
||||||
|
datagram[VERSION_POSITON] = version;
|
||||||
|
return datagram;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Payload getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkProtocolVersion() throws ProtocolError {
|
||||||
|
if (PROTOCOL_VERSION != version) {
|
||||||
|
throw new ProtocolError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
package protocolP2P;
|
||||||
|
import protocolP2P.CodeType;
|
||||||
|
import exception.ProtocolError;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.lang.Byte;
|
||||||
|
|
||||||
|
/** Request/Response code enum.
|
||||||
|
* @author Louis Royer
|
||||||
|
* @author Flavien Haas
|
||||||
|
* @author JS Auge
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public enum RequestResponseCode {
|
||||||
|
LIST_REQUEST(CodeType.REQUEST, (byte)0x00),
|
||||||
|
LOAD_REQUEST(CodeType.REQUEST, (byte)0x01),
|
||||||
|
LIST_RESPONSE(CodeType.RESPONSE, (byte)0x80),
|
||||||
|
LOAD_RESPONSE(CodeType.RESPONSE, (byte)0x81),
|
||||||
|
NOT_FOUND(CodeType.RESPONSE, (byte)0x82),
|
||||||
|
PROTOCOL_ERROR(CodeType.RESPONSE, (byte)0x83),
|
||||||
|
INTERNAL_ERROR(CodeType.RESPONSE, (byte)0x84);
|
||||||
|
|
||||||
|
public final CodeType codeType;
|
||||||
|
public final byte codeValue;
|
||||||
|
protected final static int RRCODE_POSITION = 1;
|
||||||
|
|
||||||
|
/* To be able to convert code to enum */
|
||||||
|
private static final Map<Byte, RequestResponseCode> BY_CODE = new HashMap<>();
|
||||||
|
/* Initialization of HashMap */
|
||||||
|
static {
|
||||||
|
for (RequestResponseCode r: values()) {
|
||||||
|
assert !BY_CODE.containsKey(Byte.valueOf(r.codeValue)) : "Duplicate in " + RequestResponseCode.class.getCanonicalName();
|
||||||
|
BY_CODE.put(Byte.valueOf(r.codeValue), r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Private constructor
|
||||||
|
* @param codeType type of code (request or response)
|
||||||
|
* @param codeValue value of the element in datagram
|
||||||
|
* @return enum element
|
||||||
|
*/
|
||||||
|
private RequestResponseCode(CodeType codeType, byte codeValue) {
|
||||||
|
this.codeType = codeType;
|
||||||
|
this.codeValue = codeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gives enum from datagram code.
|
||||||
|
* @param code value of the element in datagram
|
||||||
|
* @return enum element
|
||||||
|
*/
|
||||||
|
public static RequestResponseCode fromCode(byte code) throws ProtocolError {
|
||||||
|
byte code = BY_CODE.get(Byte.valueOf(code));
|
||||||
|
if (code == null) {
|
||||||
|
throw new ProtocolError();
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue