OSDN Git Service

lejos_NXJ_win32_0_5_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / java / classes / lejos / rcxcomm / RCXAbstractPort.java
diff --git a/nxtOSEK/lejos_nxj/src/java/classes/lejos/rcxcomm/RCXAbstractPort.java b/nxtOSEK/lejos_nxj/src/java/classes/lejos/rcxcomm/RCXAbstractPort.java
new file mode 100644 (file)
index 0000000..df679b6
--- /dev/null
@@ -0,0 +1,200 @@
+package lejos.rcxcomm;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+\r
+/** RCXAbstractPort provides an interface similar to java.net.Socket\r
+ * Adapted from original code created by the LEGO3 Team at DTU-IAU\r
+ * RCXAbstractPort implements input and output stream handling and input\r
+ * buffering. It uses a packet handler for sending and receivng packets.\r
+ * This version is abstract because it has no packet handler defined.\r
+ * Specific versions of RCXAbstractPort override the constructor and\r
+ * set up the packet handler to use a specific protocol stack. \r
+ * @author Brian Bagnall\r
+ * @author Lawrie Griffiths\r
+ */\r
+public abstract class RCXAbstractPort {\r
+\r
+   private boolean portOpen = true;\r
+   private Listener listener;\r
+   private int timeOut = 0;\r
+\r
+   private RCXInputStream rcxin;\r
+   private RCXOutputStream rcxout;\r
+   protected PacketHandler packetHandler;\r
+\r
+   /**\r
+    * Constructor for the RCXAbstractPort.\r
+    * Opens the port, and sets the protocol packet handler.\r
+    * @param handler the packet handler\r
+    */\r
+   public RCXAbstractPort(PacketHandler handler) throws IOException {\r
+      packetHandler = handler;\r
+      rcxin = new RCXInputStream(this);\r
+      rcxout = new RCXOutputStream(packetHandler);\r
+      listener = new Listener();\r
+      listener.setDaemon(true);\r
+      listener.start();\r
+   }\r
+\r
+   /** Returns an input stream for this RCXPort.\r
+    * @return an input stream for reading bytes from this RCXPort.\r
+    */\r
+   public InputStream getInputStream() {\r
+      return (InputStream) rcxin;\r
+   }\r
+\r
+   /** Returns an output stream for this RCXPort.\r
+    * @return an output stream for writing bytes to this RCXPort.\r
+    */\r
+   public OutputStream getOutputStream() {\r
+      return (OutputStream) rcxout;\r
+   }\r
+\r
+   /**\r
+    * Resets sequence numbers for this port \r
+    */\r
+   public void reset() {\r
+     packetHandler.reset();\r
+   }\r
+\r
+   /** Closes this RCXPort, stopping the Listener thread.\r
+    */\r
+   public void close() {\r
+      portOpen = false;\r
+   }\r
+\r
+   /** Getter for property timeOut.\r
+    * @return Value of property timeOut.\r
+    */\r
+   public int getTimeOut() {\r
+      return timeOut;\r
+   }\r
+\r
+   /** Setter for property timeOut.\r
+    * @param timeOut New value of property timeOut.\r
+    */\r
+   public void setTimeOut(int timeOut) {\r
+      this.timeOut = timeOut;\r
+   }\r
+\r
+   private byte [] inPacket = new byte[2];\r
+\r
+   /** Listener class runs a thread that reads and buffers bytes.\r
+    * Allows a maximum of two bytes in a packet.\r
+    */\r
+   private class Listener extends Thread {\r
+      public void run() {\r
+         while (portOpen) {\r
+            if (packetHandler.isPacketAvailable()) {\r
+              int r = packetHandler.receivePacket(inPacket);\r
+              for(int i=0;i<r;i++) rcxin.add(inPacket[i]);\r
+            }\r
+            try {\r
+               Thread.sleep(10);\r
+            } catch (InterruptedException iE) { }\r
+         }\r
+      }\r
+   }\r
+\r
+   /**\r
+    * Hidden inner class extending InputStream. \r
+    */\r
+   private class RCXInputStream extends InputStream {\r
+\r
+      /** The default buffer size for the InputStream\r
+       */\r
+      public static final int bufferSize = 32;\r
+      private byte[] buffer = new byte[bufferSize];\r
+      private int current = 0, last = 0;\r
+      private RCXAbstractPort dataPort;\r
+      private IOException ioe = new IOException();\r
+\r
+      /** Creates new RCXInputStream\r
+      * @param port The RCXAbstractPort which should deliver data for to this InputStream\r
+      */\r
+      public RCXInputStream(RCXAbstractPort port) {\r
+         dataPort = port;\r
+      }\r
+\r
+      /** Checks if there is any data avaliable on the InputStream\r
+      * @throws IOException is never thrown\r
+      * @return The number of bytes avaliable on the InputStream\r
+      */\r
+      public int available() throws IOException {\r
+         if (last < current)\r
+            return bufferSize-(current-last);\r
+         else\r
+            return last-current;\r
+      }\r
+\r
+      /** Read a single byte from the InputStream. Returns value as\r
+      * an int value between 0 and 255.\r
+      * @throws IOException is thrown when the read is timed out\r
+      * @return A data byte from the stream\r
+      */\r
+      public synchronized int read() throws IOException {\r
+         int time1 = (int)System.currentTimeMillis();\r
+         int timeOut = dataPort.getTimeOut();\r
+         while (available() == 0) {\r
+            if (timeOut != 0 && ((int)System.currentTimeMillis()-time1 > timeOut)) {\r
+                  throw ioe;\r
+            }\r
+            try {\r
+               Thread.sleep(10);\r
+            } catch (InterruptedException iE) { }\r
+         }\r
+\r
+         synchronized (buffer) {\r
+            int b = buffer[current++];\r
+            if (current == bufferSize)\r
+               current = 0;\r
+\r
+            if(b < 0) b = b + 256;\r
+            return b;\r
+         }\r
+      }\r
+\r
+      /** Add a data byte to the stream\r
+      * This method should only be called by the RCXPort that\r
+      * created the RCXInputStream\r
+      * @param b The data byte\r
+      */\r
+      void add(byte b) {\r
+         synchronized (buffer) {\r
+            buffer[last++] = b;\r
+            if (last == bufferSize)\r
+               last = 0;\r
+         }\r
+      }\r
+   }\r
+\r
+   /** Hidden inner class extending OutputStream. \r
+    */\r
+   private class RCXOutputStream extends OutputStream {\r
+\r
+      private PacketHandler packetHandler;\r
+      private IOException ioe = new IOException();\r
+\r
+      /** Creates new RCXOutputStream\r
+      * @param handler the packet handler used to send data\r
+      */\r
+      public RCXOutputStream(PacketHandler handler) {\r
+         packetHandler = handler;\r
+      }\r
+\r
+      private byte [] bytePacket = new byte[1];\r
+\r
+      /** Write a byte to the OutputStream.\r
+      * @param b The byte.\r
+      * @throws IOException if the byte could not be written to the stream\r
+      */\r
+      public synchronized void write(int b) throws IOException {\r
+         bytePacket[0] = (byte) b;\r
+         if (!packetHandler.sendPacket(bytePacket,1)) throw ioe;\r
+      }\r
+   }\r
+}\r
+\r
+\r