Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package me.rabrg.mercury;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.lang.reflect.Field;
- import java.lang.reflect.Modifier;
- import me.rabrg.mercury.event.Event;
- /**
- * The core class of the Mercury networking API.
- * @author Ryan Greene
- *
- */
- public final class Mercury {
- /**
- * An array containing all registered events.
- */
- private Class<?>[] events;
- /**
- * The current index for registering events.
- */
- private int index;
- /**
- * The input stream used to read events.
- */
- private final DataInputStream input;
- /**
- * The output stream used to write events.
- */
- private final DataOutputStream output;
- /**
- * Constructs a new Mercury instance with the specified input and output streams.
- * @param input The input stream used to read events.
- * @param output The output stream used to write events.
- */
- public Mercury(final InputStream input, final OutputStream output) {
- events = new Class[1];
- index = 0;
- this.input = new DataInputStream(input);
- this.output = new DataOutputStream(output);
- }
- /**
- * Registers the specified event to an opcode.
- * @param event The event being registered.
- */
- public void registerEvent(final Class<?> event) {
- if (index == events.length) {
- final Class<?>[] expanded = new Class[events.length + 1];
- System.arraycopy(events, 0, expanded, 0, events.length);
- events = expanded;
- }
- events[index++] = event;
- }
- /**
- * Writes the specified event to the output stream.
- * @param event The event being written.
- * @throws Exception If an exception is thrown.
- */
- public void writeEvent(final Event event) throws Exception {
- int opcode = -1;
- for (int i = 0; i < events.length; i++) {
- if (events[i] == event.getClass()) {
- opcode = i;
- break;
- }
- }
- if (opcode == -1) {
- throw new IllegalArgumentException("The specified event is not registered: " + event);
- }
- output.writeByte(opcode);
- for (final Field field : event.getClass().getDeclaredFields()) {
- field.setAccessible(true);
- Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
- final Class<?> type = field.getType();
- if (type == byte.class) {
- output.write(field.getByte(event));
- } else if (type == short.class) {
- output.writeShort(field.getShort(event));
- } else if (type == int.class) {
- output.writeInt(field.getInt(event));
- } else if (type == long.class) {
- output.writeLong(field.getLong(event));
- } else if (type == float.class) {
- output.writeFloat(field.getFloat(event));
- } else if (type == double.class) {
- output.writeDouble(field.getDouble(event));
- } else if (type == boolean.class) {
- output.writeBoolean(field.getBoolean(event));
- } else if (type == char.class) {
- output.writeChar(field.getChar(event));
- } else if (type == String.class) {
- output.writeUTF((String) field.get(event));
- } else {
- throw new IllegalStateException("The type " + type + " is not handled");
- }
- }
- output.flush();
- }
- /**
- * Reads an event from the input stream.
- * @return The read event.
- * @throws Exception If an exception is thrown.
- */
- public Event readEvent() throws Exception {
- final int opcode = input.readByte();
- Event event = null;
- try {
- event = (Event) events[opcode].newInstance();
- } catch (final Exception e) {
- throw new IllegalStateException("Read opcode " + opcode + " but no event registered to it", e);
- }
- for (final Field field : event.getClass().getDeclaredFields()) {
- field.setAccessible(true);
- Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
- final Class<?> type = field.getType();
- if (type == byte.class) {
- field.setByte(event, input.readByte());
- } else if (type == short.class) {
- field.setShort(event, input.readShort());
- } else if (type == int.class) {
- field.setInt(event, input.readInt());
- } else if (type == long.class) {
- field.setLong(event, input.readLong());
- } else if (type == float.class) {
- field.setFloat(event, input.readFloat());
- } else if (type == double.class) {
- field.setDouble(event, input.readDouble());
- } else if (type == boolean.class) {
- field.setBoolean(event, input.readBoolean());
- } else if (type == char.class) {
- field.setChar(event, input.readChar());
- } else if (type == String.class) {
- field.set(event, input.readUTF());
- } else {
- throw new IllegalStateException("The type " + type + " is not handled");
- }
- }
- return event;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement