Created
July 15, 2016 10:29
-
-
Save Hadyn/13dd47252f7e8c32e12969df8b919d31 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.evelus.galaxy; | |
import java.nio.ByteBuffer; | |
/** | |
* A message. All implementations of messages must inherit this class and provide functions | |
* to access various variables that are accessible from the buffer provided to the message. | |
* | |
* @author hadyn | |
*/ | |
public class Message { | |
private ByteBuffer buffer; | |
private MessageStructure structure; | |
private OffsetTable offsets; | |
protected Message(ByteBuffer buffer, MessageStructure structure) { | |
this.buffer = buffer; | |
this.structure = structure; | |
offsets = structure.createOffsetTable(buffer); | |
} | |
/** | |
* Gets an integer variable from the message buffer. | |
* | |
* @param id the identifier of the variable to get. | |
* @return the integer variable value. | |
*/ | |
protected int getInt(int id) { | |
if(!structure.isFieldType(id, MessageField.TYPE_INT)) { | |
throw new IllegalStateException("Expected field " + id + " to be an integer."); | |
} | |
buffer.position(offsets.getOffset(id)); | |
return buffer.getInt(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.evelus.galaxy; | |
import java.nio.ByteBuffer; | |
/** | |
* @author hadyn | |
*/ | |
public class MessageField { | |
public static final int TYPE_INT = 0; | |
private int id; | |
private String name; | |
private int type; | |
public MessageField(int id, String name, int type) { | |
this.id = id; | |
this.name = name; | |
this.type = type; | |
} | |
public int getId() { | |
return id; | |
} | |
public int getType() { | |
return type; | |
} | |
/** | |
* Gets the length of a data type in bytes. | |
* | |
* @param type the data type. | |
* @return the length in bytes. | |
*/ | |
public static int getLength(ByteBuffer buffer, int offset, int type) { | |
switch (type) { | |
case TYPE_INT: | |
return 4; | |
default: | |
throw new UnsupportedOperationException("Unhandled data type."); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.evelus.galaxy; | |
import java.nio.ByteBuffer; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.TreeSet; | |
/** | |
* A structure which defines a message. Fields of a structure are parsed from buffers in ascending | |
* order of identifiers. For backwards compatibility updated structures are expected to retain the | |
* same identifiers for fields of previous versions. Fields being removed will break all backwards | |
* compatibility. | |
* | |
* @author hadyn | |
*/ | |
public class MessageStructure { | |
/** | |
* The fields that comprise the structure. | |
*/ | |
private Map<Integer, MessageField> fields = new HashMap<>(); | |
/** | |
* Adds a field to the structure. | |
* | |
* @param field the field to add. | |
* @return the field that was replaced if one already existed for the provided field's identifier. | |
*/ | |
public MessageField addField(MessageField field) { | |
return fields.put(field.getId(), field); | |
} | |
/** | |
* Gets a field. | |
* | |
* @param id the field identifier. | |
* @return the field. | |
*/ | |
public MessageField getField(int id) { | |
return fields.get(id); | |
} | |
/** | |
* Gets if the structure contains a certain field. | |
* | |
* @param id the field identifier. | |
* @return if the structure has a field with the specified id. | |
*/ | |
public boolean hasField(int id) { | |
return fields.containsKey(id); | |
} | |
/** | |
* Checks to see if a field is a certain type. | |
* | |
* @param id the identifier of the field. | |
* @param type the type to check. | |
* @return if the field is of the specified type. | |
*/ | |
public boolean isFieldType(int id, int type) { | |
if (!hasField(id)) { | |
throw new NullPointerException("Field " + id + " does not exist."); | |
} | |
MessageField field = getField(id); | |
return field.getType() == type; | |
} | |
/** | |
* Creates an offset table for the structure. If the structure has variable length fields then the | |
* byte buffer will have to be read to determine the offsets of all of the variables. | |
* | |
* @param buffer the buffer to read from. | |
* @return the created offset table. | |
*/ | |
public OffsetTable createOffsetTable(ByteBuffer buffer) { | |
OffsetTable table = new OffsetTable(); | |
int offset = 0; | |
Set<Integer> ids = new TreeSet<>(fields.keySet()); | |
for(int id : ids) { | |
MessageField field = fields.get(id); | |
table.addOffset(id, offset); | |
offset += MessageField.getLength(buffer, offset, field.getType()); | |
} | |
return table; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.evelus.galaxy; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* @author hadyn | |
*/ | |
public class OffsetTable { | |
private Map<Integer, Integer> offsets = new HashMap<>(); | |
public void addOffset(int id, int offset) { | |
offsets.put(id, offset); | |
} | |
public int getOffset(int id) { | |
if(!offsets.containsKey(id)) { | |
throw new IllegalArgumentException("Offset for variable " + id + " does not exist."); | |
} | |
return offsets.get(id); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.evelus.galaxy; | |
import java.nio.ByteBuffer; | |
/** | |
* @author hadyn | |
*/ | |
public class SilabMessage extends Message { | |
public SilabMessage(ByteBuffer buffer, MessageStructure structure) { | |
super(buffer, structure); | |
} | |
public int getPowerLevel() { | |
return getInt(0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment