From c75c4deb367536bbc1b85c5af91aa6dd8f5b1306 Mon Sep 17 00:00:00 2001
From: Tommy Olofsson <tommy.olofsson.90@gmail.com>
Date: Thu, 29 Jan 2015 20:59:22 +0100
Subject: [PATCH] Restructured DecoderChannel to be easier to subclass.

---
 lib/java/Makefile                             |  1 +
 .../lth/control/labcomm/DecoderChannel.java   | 55 ++++++++++++-------
 .../labcomm/DynamicDecoderChannel.java        | 36 ++++++++++++
 .../labcomm2006/DynamicDecoderChannel.java    | 12 ++++
 4 files changed, 85 insertions(+), 19 deletions(-)
 create mode 100644 lib/java/se/lth/control/labcomm/DynamicDecoderChannel.java
 create mode 100644 lib/java/se/lth/control/labcomm2006/DynamicDecoderChannel.java

diff --git a/lib/java/Makefile b/lib/java/Makefile
index 060aeeb..b87d2e3 100644
--- a/lib/java/Makefile
+++ b/lib/java/Makefile
@@ -1,6 +1,7 @@
 MODULES=Constant \
 	Decoder \
 	DecoderChannel \
+	DynamicDecoderChannel \
 	DecoderRegistry \
 	Encoder \
 	EncoderChannel \
diff --git a/lib/java/se/lth/control/labcomm/DecoderChannel.java b/lib/java/se/lth/control/labcomm/DecoderChannel.java
index dc25d23..1bac992 100644
--- a/lib/java/se/lth/control/labcomm/DecoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/DecoderChannel.java
@@ -8,9 +8,9 @@ import java.io.EOFException;
 
 public class DecoderChannel implements Decoder {
 
-  private DataInputStream in;
-  private DecoderRegistry def_registry = new DecoderRegistry();
-  private DecoderRegistry ref_registry = new DecoderRegistry();
+  protected DataInputStream in;
+  protected DecoderRegistry def_registry = new DecoderRegistry();
+  protected DecoderRegistry ref_registry = new DecoderRegistry();
 
   public DecoderChannel(InputStream in) throws IOException {
     this.in = new DataInputStream(in);
@@ -55,9 +55,38 @@ public class DecoderChannel implements Decoder {
        }
   }
 
+	protected void processSample(int tag) throws Exception {
+		DecoderRegistry.Entry e = def_registry.get(tag);
+		if (e == null) {
+			throw new IOException("Unhandled tag " + tag);
+		}
+		SampleDispatcher d = e.getDispatcher();
+		if (d == null) {
+			throw new IOException("No dispatcher for '" + e.getName() + "'");
+		}
+		SampleHandler h = e.getHandler();
+		if (h == null) {
+			throw new IOException("No handler for '" + e.getName() +"'");
+		}
+		d.decodeAndHandle(this, h);
+	}
+
   public void runOne() throws Exception {
-    boolean done = false;
-    while (!done) {
+	  runOne(true);
+  }
+
+	/**
+	 * Run the decoder.
+	 *
+	 * @param waitForSample Wether to wait until an actual sample has
+	 *     been decoded or to return after any complete entity has
+	 *     been decoded. Set to <code>true</code> to get the old
+	 *     behaviour.
+	 */
+
+  public void runOne(boolean waitForSample) throws Exception {
+	boolean done = !waitForSample;
+    do {
       int tag = decodePacked32();
       int length = decodePacked32();
       switch (tag) {
@@ -84,23 +113,11 @@ public class DecoderChannel implements Decoder {
           processPragma(length);
 	} break;
 	default: {
-	  DecoderRegistry.Entry e = def_registry.get(tag);
-	  if (e == null) {
-	    throw new IOException("Unhandled tag " + tag);
-	  }
-	  SampleDispatcher d = e.getDispatcher();
-	  if (d == null) {
-	    throw new IOException("No dispatcher for '" + e.getName() + "'");
-	  }
-	  SampleHandler h = e.getHandler();
-	  if (h == null) {
-	    throw new IOException("No handler for '" + e.getName() +"'");
-	  }
-	  d.decodeAndHandle(this, h);
+	  processSample(tag);
 	  done = true;
 	}
       }
-    }
+    } while (!done);
   }
 
   public void run() throws Exception {
diff --git a/lib/java/se/lth/control/labcomm/DynamicDecoderChannel.java b/lib/java/se/lth/control/labcomm/DynamicDecoderChannel.java
new file mode 100644
index 0000000..6ebb70c
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm/DynamicDecoderChannel.java
@@ -0,0 +1,36 @@
+package se.lth.control.labcomm;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+public class DynamicDecoderChannel extends DecoderChannel {
+
+	public DynamicDecoderChannel(InputStream in) throws IOException {
+		super(in);
+	}
+
+	public void runOne() throws Exception {
+		runOne(false);
+	}
+
+	protected void processSample(int tag) throws Exception {
+		DecoderRegistry.Entry e = def_registry.get(tag);
+		if (e == null)
+			throw new IOException("Have not read any registration for " + tag);
+		SampleDispatcher d = e.getDispatcher();
+		if (d != null) {
+			SampleHandler h = e.getHandler();
+			if (h == null)
+				throw new IOException("No handler for '" + e.getName() +"'");
+			d.decodeAndHandle(this, h);
+		} else {
+			dynamicDecode();
+		}
+	}
+
+	private void dynamicDecode() {
+		throw new UnsupportedOperationException("Dynamic decoding not implemented yet.");
+	}
+
+}
diff --git a/lib/java/se/lth/control/labcomm2006/DynamicDecoderChannel.java b/lib/java/se/lth/control/labcomm2006/DynamicDecoderChannel.java
new file mode 100644
index 0000000..2615e40
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2006/DynamicDecoderChannel.java
@@ -0,0 +1,12 @@
+package se.lth.control.labcomm2006;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+public class DynamicDecoderChannel extends DecoderChannel {
+	public DynamicDecoderChannel(InputStream in) throws IOException {
+		super(in);
+		throw new UnsupportedOperationException("Use 2014.");
+	}
+}
-- 
GitLab