Fix all errors and all warnings

This commit is contained in:
Louis Royer 2020-01-23 15:54:27 +01:00
parent 5eb7e0deab
commit 2afb87303f
13 changed files with 149 additions and 64 deletions

View File

@ -13,6 +13,8 @@ All messages begins with `P2P-JAVA-PROJECT VERSION 1.0\n` (this version of the p
# P2P-JAVA-PROJECT version 1.1 (Binary protocol for step 1)
All strings in the datagram are utf-8 encoded.
```Datagram format
1 byte: [0-7: VERSION(0x11, first quartet is major version, second is minor)]
@ -58,7 +60,8 @@ Payload contains
```
8 bytes: [64-127: OFFSET OF FILE CONTENT IN BYTES]
8 bytes: [128-191: TOTAL FILESIZE]
y bytes: [<FILENAME>\n]
4 bytes: [192-223: FILENAME SIZE] (cannot be > to PAYLOAD_SIZE - 20 or be zero)
y bytes: [<FILENAME>]
z bytes: [FILE CONTENT]
```

View File

@ -1,2 +1,4 @@
package exception;
public class InternalError extends Exception {}
public class InternalError extends Exception {
private static final long serialVersionUID = 11L;
}

View File

@ -1,2 +1,4 @@
package exception;
public class NotFound extends Exception {}
public class NotFound extends Exception {
private static final long serialVersionUID = 11L;
}

View File

@ -1,2 +1,4 @@
package exception;
public class ProtocolError extends Exception {}
public class ProtocolError extends Exception {
private static final long serialVersionUID = 11L;
}

View File

@ -1,3 +1,5 @@
package exception;
/** Used on reception side when size as set in datagram is too big, and we cant store this in a int/long as usual. */
public class SizeError extends Exception {}
public class SizeError extends Exception {
private static final long serialVersionUID = 11L;
}

View File

@ -1,2 +1,4 @@
package exception;
public class TransmissionError extends Exception {}
public class TransmissionError extends Exception {
private static final long serialVersionUID = 11L;
}

View File

@ -1,2 +1,4 @@
package exception;
public class VersionError extends Exceptions {}
public class VersionError extends Exception {
private static final long serialVersionUID = 11L;
}

View File

@ -13,7 +13,6 @@ import exception.SizeError;
* @version 1.0
*/
public class FileList extends Payload {
private final static RequestResponseCode requestResponseCode = RequestResponseCode.LIST_RESPONSE;
private ArrayList<String> content;
/** Constructor (typically used by the server) with an ArrayList parameter containing
@ -22,10 +21,11 @@ public class FileList extends Payload {
* @throws InternalError
*/
public FileList(ArrayList<String> content) throws InternalError {
super(RequestResponseCode.LIST_RESPONSE);
/* assert to help debugging */
assert !content.isEmpty() : "Payload size of FileList must not be empty, use EmptyDirectory from Payload instead";
if (content.isEmpty()) {
throws new InternalError();
throw new InternalError();
}
this.content = content;
}
@ -34,24 +34,27 @@ public class FileList extends Payload {
* @param datagram the full datagram received
* @throws SizeError
* @throws InternalError
* @throws ProtocolError
*/
protected FileList(byte[] datagram) throws SizeError, InternalError {
//TODO
protected FileList(byte[] datagram) throws SizeError, ProtocolError, InternalError {
super(datagram);
/* assert to help debugging */
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";
assert requestResponseCode == RequestResponseCode.LIST_RESPONSE : "FileList subclass is incompatible with this datagram, request/response code must be checked before using this constructor";
/* InternalErrorException */
if (RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LIST_RESPONSE) {
if (requestResponseCode!= RequestResponseCode.LIST_RESPONSE) {
throw new InternalError();
}
int size = getPayloadSize(datagram);
//TODO
}
/** Returns a byte[] containing datagram with padding.
* This datagram is still incomplete and should not be send directly.
* ProtocolP2PDatagram will use this method to generate the complete datagram.
* @return datagram with padding
* @throws InternalError
*/
protected byte[] toDatagram() {
/*protected byte[] toDatagram() throws InternalError {
//TODO compute size
int size = 8 + ;
byte[] datagram = new byte[size]; // java initialize all to zero
@ -61,5 +64,5 @@ public class FileList extends Payload {
// bits 16-31 are reserved for future use
datagram = setPayloadSize(size, datagram);
//TODO Write content
}
}*/
}

View File

@ -5,6 +5,8 @@ import exception.ProtocolError;
import exception.InternalError;
import exception.SizeError;
import tools.BytesArrayTools;
import java.util.Arrays;
import java.io.UnsupportedEncodingException;
/** Representation of payload for load response.
* @author Louis Royer
@ -13,7 +15,6 @@ import tools.BytesArrayTools;
* @version 1.0
*/
public class FilePart extends Payload {
private static final RequestResponseCode requestResponseCode = RequestResponseCode.LOAD_RESPONSE;
private String filename;
private long totalSize;
private long offset;
@ -27,10 +28,15 @@ public class FilePart extends Payload {
* @throws InternalError
*/
public FilePart(String filename, long totalSize, long offset, byte[] partialContent) throws InternalError {
super(RequestResponseCode.LOAD_RESPONSE);
/* asserts to help debugging */
assert totalSize >= 0 : "totalSize cannot be negative";
assert partialContent.length != 0 : "partialContent.length cannot be zero";
assert totalSize >= partialContent.length : "totalSize must be greater than partialContent.length";
assert offset >= 0 : "offset cannot be negative";
if (totalSize < 0 || offset < 0) {
assert filename != null : "filename is required";
if (totalSize < 0 || partialContent.length == 0 || totalSize < partialContent.length
|| offset < 0 || filename == null) {
throw new InternalError();
}
this.filename = filename;
@ -45,64 +51,113 @@ public class FilePart extends Payload {
* @throws InternalError
*/
protected FilePart(byte[] datagram) throws SizeError, ProtocolError, InternalError {
super(datagram);
/* assert to help debugging */
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";
assert requestResponseCode == RequestResponseCode.LOAD_RESPONSE : "FilePart subclass is incompatible with this datagram, request/response code must be checked before using this constructor";
/* InternalErrorException */
if (RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LOAD_RESPONSE) {
if (requestResponseCode != RequestResponseCode.LOAD_RESPONSE) {
throw new InternalError();
}
setOffset(datagram); // this can throw SizeError
setTotalFileSize(datagram); // this can throw SizeError
int size = getPayloadSize(datagram); // this can throw SizeError
int partialContentStart = setFilename(datagram, size) + 1; // this can throw ProtocolError
setPartialContent(datagram, partialContentStart, size);
setTotalSize(datagram); // this can throw SizeError
setFilename(datagram); // this can throw ProtocolError, SizeError
setPartialContent(datagram); // this can throw SizeError
}
/** Returns a byte[] containing datagram with padding.
* This datagram is still incomplete and should not be send directly.
* ProtocolP2PDatagram will use this method to generate the complete datagram.
* @return datagram with padding
* @throws InternalError
*/
protected byte[] toDatagram() {
protected byte[] toDatagram() throws InternalError {
//TODO : calculate payload size
int size = 24 + filename.length + 1;
int size = 24 + filename.length() + 1;
byte[] datagram = new byte[size]; // 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
datagram = setPayloadSize(size, datagram);
//TODO : write offset to datagram
//TODO : write totalFileSize to datagram
//TODO : write filename\n to datagram
setPayloadSize(size, datagram);
// write offset to datagram (Byte 8)
BytesArrayTools.write(datagram, 8, offset);
// write totalSize to datagram (Byte 16)
BytesArrayTools.write(datagram, 16, totalSize);
// write filenames size to datagram
BytesArrayTools.write(datagram, 24, filename.length());
//TODO : write filename to datagram
try {
byte[] bFilename = filename.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
//TODO : write partialContent to datagram
return datagram;
}
/** Write from bytes 8 to 15 of datagram into offset.
* @param datagram received datagram
* @throws SizeError
*/
private setOffset(byte[] datagram) throws SizeError {
private void setOffset(byte[] datagram) throws SizeError {
offset = BytesArrayTools.readLong(datagram, 8);
}
/** Write from bytes 16 to 23 of datagram into totalSize.
* @param datagram received datagram
* @throws SizeError
*/
private setTotalFileSize(byte[] datagram) throw SizeError {
private void setTotalSize(byte[] datagram) throws SizeError {
totalSize = BytesArrayTools.readLong(datagram, 16);
}
private int setFilename(byte[] datagram, int payloadSize) throws ProtocolError {
// TODO: copy datagram from byte 24 to the first \n (excluded)
// into filename unless we excess size
// (in this case the wrong size has been
// set by the emitter, it is a protocolerror)
// return position of the \n
/** Read filenames size from bytes 24 to 28 of datagram.
* @param datagram received datagram
* @throws ProtocolError
* @throws SizeError
* @return filenames size
*/
private int getFilenameSize(byte[] datagram) throws SizeError, ProtocolError {
int size = BytesArrayTools.readInt(datagram, 24); // this can throw SizeError
// filename size cannot be zero
if (size == 0) {
throw new ProtocolError();
}
// offset (8B) + totalSize (8B) + filenameSize (4B) = 20B
if ((20 + size) > getPayloadSize(datagram)) {
throw new ProtocolError();
}
return size;
}
private setPartialContent(byte[] datagram, int start, int payloadSize) {
// TODO: copy datagram from start to size into partialContent
/** Write filename from byte 24 to byte (24 + (filenameSize - 1)) of datagram.
* @param datagram received datagram
* @throws ProtocolError
* @throws SizeError
* @throws InternalError
*/
private void setFilename(byte[] datagram) throws ProtocolError, SizeError, InternalError {
int filenameSize = getFilenameSize(datagram); // this can throw ProtocolError or SizeError
try {
filename = new String(datagram, 24, filenameSize, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
}
/** Write partialContent from byte (24 + filenameSize) to byte (8 + payloadSize) of datagram.
* @param datagram received datagram
* @throws SizeError
* @throws ProtocolError
*/
private void setPartialContent(byte[] datagram) throws ProtocolError, SizeError {
int start = 24 + getFilenameSize(datagram); // this can throw SizeError or ProtocolError
int end = 8 + getPayloadSize(datagram); // this can throw SizeError
try {
partialContent = Arrays.copyOfRange(datagram, start, end+1);
} catch (ArrayIndexOutOfBoundsException e) {
throw new ProtocolError();
}
}
}

View File

@ -13,8 +13,8 @@ import tools.BytesArrayTools;
* @version 1.0
*/
public class Payload {
private RequestResponseCode requestResponseCode;
protected final static int PAYLOAD_SIZE_POSITON = 4;
protected RequestResponseCode requestResponseCode;
protected final static int PAYLOAD_SIZE_POSITION = 4;
protected final static int PAYLOAD_START_POSITION = 8;
/** Consructor used to create Payload with a payload size of zero using a RRCode.
@ -23,8 +23,8 @@ public class Payload {
*/
public Payload(RequestResponseCode requestResponseCode) throws InternalError {
/* asserts to help debugging */
assert requestResponseCode != requestResponseCode.LIST_RESPONSE : "LIST_RESPONSE must use FilePart class";
assert requestResponseCode != requestResponseCode.LOAD_RESPONSE : "LOAD_RESPONSE must use FileList class";
assert requestResponseCode != RequestResponseCode.LIST_RESPONSE || (this instanceof FileList) : "LIST_RESPONSE must use FilePart class";
assert requestResponseCode != RequestResponseCode.LOAD_RESPONSE || (this instanceof FilePart) : "LOAD_RESPONSE must use FileList class";
this.requestResponseCode = requestResponseCode;
checkRequestResponseCode(); // this can throw InternalError
}
@ -37,8 +37,8 @@ public class Payload {
*/
protected Payload(byte[] datagram) throws ProtocolError, InternalError {
/* asserts to help debugging */
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";
assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LIST_RESPONSE || (this instanceof FileList) : "LIST_RESPONSE must use FilePart class";
assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LOAD_RESPONSE || (this instanceof FilePart) : "LOAD_RESPONSE must use FileList class";
requestResponseCode = RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]);
checkRequestResponseCode(); // this can throw InternalError
}
@ -48,7 +48,8 @@ public class Payload {
*/
private void checkRequestResponseCode() throws InternalError {
/* Incorrect use cases (use subclasses instead) */
if (requestResponseCode == RequestResponseCode.LIST_RESPONSE || requestResponseCode == RequestResponseCode.LOAD_RESPONSE) {
if ((requestResponseCode == RequestResponseCode.LIST_RESPONSE && !(this instanceof FileList))
|| (requestResponseCode == RequestResponseCode.LOAD_RESPONSE && !(this instanceof FilePart))) {
throw new InternalError();
}
}
@ -57,14 +58,17 @@ public class Payload {
* This datagram is still incomplete and should not be send directly.
* ProtocolP2PDatagram will use this method to generate the complete datagram.
* @return datagram with padding
* @throws InternalError
*/
protected byte[] toDatagram() {
protected byte[] toDatagram() throws InternalError {
// InternalError is impossible in this method on Payload class but still on subclasses
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)
return datagram;
}
/** Set payloads size in a datagram.
@ -72,7 +76,7 @@ public class Payload {
* @param datagram datagram to be completed
* @throws InternalError
*/
protected static setPayloadSize(int size, byte[] datagram) throws InternalError {
protected static void setPayloadSize(int size, byte[] datagram) throws InternalError {
/* assert to help debugging */
assert size >= 0: "Payload size cannot be negative";
if (size < 0) {
@ -80,7 +84,7 @@ public class Payload {
// because this is only for reception side
throw new InternalError();
}
BytesArrayTools.write(datagram, PAYLOAD_SIZE_POSITON, size);
BytesArrayTools.write(datagram, PAYLOAD_SIZE_POSITION, size);
}
/** Get payloads size from a datagram.
@ -89,6 +93,6 @@ public class Payload {
* @throws SizeError
*/
protected static int getPayloadSize(byte[] datagram) throws SizeError {
return BytesArrayTools.readInt(datagram, PAYLOAD_SIZE_POSITON];
return BytesArrayTools.readInt(datagram, PAYLOAD_SIZE_POSITION);
}
}

View File

@ -1,6 +1,8 @@
package protocolP2P;
import exception.ProtocolError;
import exception.VersionError;
import exception.SizeError;
import exception.InternalError;
import protocolP2P.Payload;
import protocolP2P.RequestResponseCode;
import java.util.ArrayList;
@ -30,8 +32,9 @@ public class ProtocolP2PDatagram {
/** Send datagram on socket
* @param socket DatagramSocket used to send datagram
* @throws InternalError
*/
public void send(DatagramSocket socket) {
public void send(DatagramSocket socket) throws InternalError {
//TODO
byte[] datagram = toDatagram();
// generate DatagramPacket
@ -43,31 +46,34 @@ public class ProtocolP2PDatagram {
* @return payload of the datagram
* @throws ProtocolError
* @throws VersionError
* @throws InternalError
* @throws SizeError
*/
public static Payload receive(DatagramSocket socket) throws ProtocolError, VersionError {
public static Payload receive(DatagramSocket socket) throws ProtocolError, VersionError, InternalError, SizeError {
//TODO
// reception
//datagram =
byte[] datagram = new byte[5];
// contruction
ProtocolP2PDatagram p = new ProtocolP2PDatagram(datagram);
return p.getPayload();
}
/** Private constructor with datagram as byte[] parameter (typically used when receiving datagram).
* @param datagram the full datagram received
* @throws ProtocolError
* @throws VersionError
* @throws InternalError
* @throws SizeError
*/
private ProtocolP2PDatagram(byte[] datagram) throws ProtocolError, VersionError, SizeError {
private ProtocolP2PDatagram(byte[] datagram) throws ProtocolError, VersionError, InternalError, SizeError {
// unwrap version
version = datagram[VERSION_POSITON];
checkProtocolVersion(); // this can throw VersionError
RequestResponseCode r = RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]); // this can throw ProtocolError
switch (r) {
case RequestResponseCode.LIST_RESPONSE:
case LIST_RESPONSE:
payload = (Payload) new FileList(datagram);
break;
case RequestResponseCode.LOAD_RESPONSE:
case LOAD_RESPONSE:
payload = (Payload) new FilePart(datagram);
break;
default:
@ -79,11 +85,13 @@ public class ProtocolP2PDatagram {
/** Returns a byte[] containing full datagram (typically used when sending datagram).
* This datagram is still complete and ready to be send.
* @return the full datagram to send
* @throws InternalError
*/
private byte[] toDatagram() {
private byte[] toDatagram() throws InternalError {
byte[] datagram = payload.toDatagram();
datagram[VERSION_POSITON] = version;
return datagram;
}
/** Returns Payload associated with the datagram.

View File

@ -51,11 +51,11 @@ public enum RequestResponseCode {
* @return enum element
*/
public static RequestResponseCode fromCode(byte code) throws ProtocolError {
byte code = BY_CODE.get(Byte.valueOf(code));
if (code == null) {
RequestResponseCode r= BY_CODE.get(Byte.valueOf(code));
if (r == null) {
throw new ProtocolError();
}
return code;
return r;
}

View File

@ -14,7 +14,7 @@ public class BytesArrayTools {
*/
public static void write(byte[] array, int start, int value) {
for(int i=0;i<4;i++) {
array[start + i] = (byte) ((size >> (8 * (3 - i))) & 0xFF);
array[start + i] = (byte) ((value >> (8 * (3 - i))) & 0xFF);
}
}
/** Write long in a bytearray
@ -24,7 +24,7 @@ public class BytesArrayTools {
*/
public static void write(byte[] array, int start, long value) {
for(int i=0;i<4;i++) {
array[start + i] = (byte) ((size >> (8 * (4 - i))) & 0xFF);
array[start + i] = (byte) ((value >> (8 * (4 - i))) & 0xFF);
}
}