Advertisement
Chiddix

Mercury v1.0.0

Jul 29th, 2014
280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.82 KB | None | 0 0
  1. package me.rabrg.mercury;
  2.  
  3. import java.io.DataInputStream;
  4. import java.io.DataOutputStream;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import java.lang.reflect.Field;
  8. import java.lang.reflect.Modifier;
  9.  
  10. import me.rabrg.mercury.event.Event;
  11.  
  12. /**
  13.  * The core class of the Mercury networking API.
  14.  * @author Ryan Greene
  15.  *
  16.  */
  17. public final class Mercury {
  18.  
  19.     /**
  20.      * An array containing all registered events.
  21.      */
  22.     private Class<?>[] events;
  23.  
  24.     /**
  25.      * The current index for registering events.
  26.      */
  27.     private int index;
  28.  
  29.     /**
  30.      * The input stream used to read events.
  31.      */
  32.     private final DataInputStream input;
  33.  
  34.     /**
  35.      * The output stream used to write events.
  36.      */
  37.     private final DataOutputStream output;
  38.  
  39.     /**
  40.      * Constructs a new Mercury instance with the specified input and output streams.
  41.      * @param input The input stream used to read events.
  42.      * @param output The output stream used to write events.
  43.      */
  44.     public Mercury(final InputStream input, final OutputStream output) {
  45.         events = new Class[1];
  46.         index = 0;
  47.         this.input = new DataInputStream(input);
  48.         this.output = new DataOutputStream(output);
  49.     }
  50.  
  51.     /**
  52.      * Registers the specified event to an opcode.
  53.      * @param event The event being registered.
  54.      */
  55.     public void registerEvent(final Class<?> event) {
  56.         if (index == events.length) {
  57.             final Class<?>[] expanded = new Class[events.length + 1];
  58.             System.arraycopy(events, 0, expanded, 0, events.length);
  59.             events = expanded;
  60.         }
  61.         events[index++] = event;
  62.     }
  63.  
  64.     /**
  65.      * Writes the specified event to the output stream.
  66.      * @param event The event being written.
  67.      * @throws Exception If an exception is thrown.
  68.      */
  69.     public void writeEvent(final Event event) throws Exception {
  70.         int opcode = -1;
  71.         for (int i = 0; i < events.length; i++) {
  72.             if (events[i] == event.getClass()) {
  73.                 opcode = i;
  74.                 break;
  75.             }
  76.         }
  77.         if (opcode == -1) {
  78.             throw new IllegalArgumentException("The specified event is not registered: " + event);
  79.         }
  80.         output.writeByte(opcode);
  81.         for (final Field field : event.getClass().getDeclaredFields()) {
  82.             field.setAccessible(true);
  83.            
  84.             Field modifiersField = Field.class.getDeclaredField("modifiers");
  85.             modifiersField.setAccessible(true);
  86.             modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
  87.            
  88.             final Class<?> type = field.getType();
  89.             if (type == byte.class) {
  90.                 output.write(field.getByte(event));
  91.             } else if (type == short.class) {
  92.                 output.writeShort(field.getShort(event));
  93.             } else if (type == int.class) {
  94.                 output.writeInt(field.getInt(event));
  95.             } else if (type == long.class) {
  96.                 output.writeLong(field.getLong(event));
  97.             } else if (type == float.class) {
  98.                 output.writeFloat(field.getFloat(event));
  99.             } else if (type == double.class) {
  100.                 output.writeDouble(field.getDouble(event));
  101.             } else if (type == boolean.class) {
  102.                 output.writeBoolean(field.getBoolean(event));
  103.             } else if (type == char.class) {
  104.                 output.writeChar(field.getChar(event));
  105.             } else if (type == String.class) {
  106.                 output.writeUTF((String) field.get(event));
  107.             } else {
  108.                 throw new IllegalStateException("The type " + type + " is not handled");
  109.             }
  110.         }
  111.         output.flush();
  112.     }
  113.  
  114.     /**
  115.      * Reads an event from the input stream.
  116.      * @return The read event.
  117.      * @throws Exception If an exception is thrown.
  118.      */
  119.     public Event readEvent() throws Exception {
  120.         final int opcode = input.readByte();
  121.         Event event = null;
  122.         try {
  123.             event = (Event) events[opcode].newInstance();
  124.         } catch (final Exception e) {
  125.             throw new IllegalStateException("Read opcode " + opcode + " but no event registered to it", e);
  126.         }
  127.         for (final Field field : event.getClass().getDeclaredFields()) {
  128.             field.setAccessible(true);
  129.            
  130.             Field modifiersField = Field.class.getDeclaredField("modifiers");
  131.             modifiersField.setAccessible(true);
  132.             modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
  133.            
  134.             final Class<?> type = field.getType();
  135.             if (type == byte.class) {
  136.                 field.setByte(event, input.readByte());
  137.             } else if (type == short.class) {
  138.                 field.setShort(event, input.readShort());
  139.             } else if (type == int.class) {
  140.                 field.setInt(event, input.readInt());
  141.             } else if (type == long.class) {
  142.                 field.setLong(event, input.readLong());
  143.             } else if (type == float.class) {
  144.                 field.setFloat(event, input.readFloat());
  145.             } else if (type == double.class) {
  146.                 field.setDouble(event, input.readDouble());
  147.             } else if (type == boolean.class) {
  148.                 field.setBoolean(event, input.readBoolean());
  149.             } else if (type == char.class) {
  150.                 field.setChar(event, input.readChar());
  151.             } else if (type == String.class) {
  152.                 field.set(event, input.readUTF());
  153.             } else {
  154.                 throw new IllegalStateException("The type " + type + " is not handled");
  155.             }
  156.         }
  157.         return event;
  158.     }
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement