diff app/src/main/java/org/tn5250j/framework/tn5250/DataStreamProducer.java @ 445:8fa8e73e2f5c

update to tn5250j version 0.7.7, svn r1270
author Carl Byington <carl@five-ten-sg.com>
date Mon, 04 Jan 2016 15:52:25 -0800
parents d29cce60f393
children 5ce5235adde6
line wrap: on
line diff
--- a/app/src/main/java/org/tn5250j/framework/tn5250/DataStreamProducer.java	Thu Dec 03 12:33:34 2015 -0800
+++ b/app/src/main/java/org/tn5250j/framework/tn5250/DataStreamProducer.java	Mon Jan 04 15:52:25 2016 -0800
@@ -1,35 +1,29 @@
 package org.tn5250j.framework.tn5250;
 
 import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.SocketException;
 import java.util.concurrent.BlockingQueue;
+
+import static org.tn5250j.framework.tn5250.Stream5250.OPCODE_OFFSET;
+
 import java.util.Timer;
 import java.util.TimerTask;
 
-import org.tn5250j.encoding.ICodePage;
-
 import android.util.Log;
 
 
 public class DataStreamProducer implements Runnable {
+    private static final int MINIMAL_PARTIAL_STREAM_LEN = 2;
     private static final String TAG = "DataStreamProducer";
     private tnvt                vt;
     private BufferedInputStream bin;
     private ByteArrayOutputStream baosin;
-    private Thread me;
     private byte[] saveStream;
     private final BlockingQueue<Object> dsq;
-    private byte[] abyte2;
-    private FileOutputStream fw;
-    private BufferedOutputStream dw;
-    private boolean dumpBytes = false;
-    private ICodePage codePage;
+    private byte[] dataStream;
+    private DataStreamDumper dataStreamDumper = new DataStreamDumper();
 
 
 
@@ -38,18 +32,14 @@
         this.vt     = vt;
         baosin = new ByteArrayOutputStream();
         dsq = queue;
-        abyte2 = init;
-    }
-
-    public void setInputStream(ByteArrayOutputStream is) {
-        baosin = is;
+        dataStream = init;
     }
 
     public final void run() {
         boolean done = false;
-        me = Thread.currentThread();
+        Thread me = Thread.currentThread();
         // load the first response screen
-        loadStream(abyte2, 0);
+        loadStream(dataStream, 0);
 
         while (!done) {
             try {
@@ -81,71 +71,71 @@
             }
             catch (IOException ioe) {
                 Log.w(TAG, ioe.getMessage());
-
-                if (me.isInterrupted())
-                    done = true;
+                if (me.isInterrupted()) done = true;
             }
             catch (Exception ex) {
                 Log.w(TAG, ex.getMessage());
-
-                if (me.isInterrupted())
-                    done = true;
+                if (me.isInterrupted()) done = true;
             }
         }
     }
 
-    private final void loadStream(byte abyte0[], int i) {
-        int j = 0;
-        int size = 0;
+    private void loadStream(byte streamBuffer[], int offset) {
+
+        int partialLen = (streamBuffer[offset] & 0xff) << 8 | streamBuffer[offset + 1] & 0xff;
+        int bufferLen = streamBuffer.length;
+
+        Log.d(TAG, "loadStream() offset=" + offset + " partialLen=" + partialLen + " bufferLen=" + bufferLen);
 
-        if (saveStream == null) {
-            j = (abyte0[i] & 0xff) << 8 | abyte0[i + 1] & 0xff;
-            size = abyte0.length;
-        }
-        else {
-            size = saveStream.length + abyte0.length;
-            byte[] inter = new byte[size];
+        if (saveStream != null) {
+            log.debug("partial stream found");
+            bufferLen = saveStream.length + streamBuffer.length;
+            byte[] inter = new byte[bufferLen];
             System.arraycopy(saveStream, 0, inter, 0, saveStream.length);
-            System.arraycopy(abyte0, 0, inter, saveStream.length, abyte0.length);
-            abyte0 = new byte[size];
-            System.arraycopy(inter, 0, abyte0, 0, size);
+            System.arraycopy(streamBuffer, 0, inter, saveStream.length, streamBuffer.length);
+            streamBuffer = new byte[bufferLen];
+            System.arraycopy(inter, 0, streamBuffer, 0, bufferLen);
             saveStream = null;
-            inter = null;
-            j = (abyte0[i] & 0xff) << 8 | abyte0[i + 1] & 0xff;
-            Log.d(TAG, "partial stream found");
         }
 
-        if (j > size) {
-            saveStream = new byte[abyte0.length];
-            System.arraycopy(abyte0, 0, saveStream, 0, abyte0.length);
-            Log.d(TAG, "partial stream saved");
-        }
-        else {
-            byte abyte1[];
-
+        if (partialLen > bufferLen) {
+          saveStream = new byte[streamBuffer.length];
+          Log.d(TAG, "partial stream saved");
+          System.arraycopy(streamBuffer, 0, saveStream, 0, streamBuffer.length);
+        } else {
+            int buf_len = partialLen + 2;
+            byte[] buf = new byte[buf_len];
+            if (isBufferShifted(partialLen, bufferLen) && isOpcodeShifted(streamBuffer, offset)) {
+                log.debug("Invalid stream buffer detected. Ignoring the inserted byte.");
+                System.arraycopy(streamBuffer, offset, buf, 0, MINIMAL_PARTIAL_STREAM_LEN);
+                System.arraycopy(streamBuffer, offset + MINIMAL_PARTIAL_STREAM_LEN + 1, buf, MINIMAL_PARTIAL_STREAM_LEN, partialLen);
+            } else {
+                System.arraycopy(streamBuffer, offset, buf, 0, buf_len);
+            }
             try {
-                abyte1 = new byte[j + 2];
-                System.arraycopy(abyte0, i, abyte1, 0, j + 2);
-                dsq.put(abyte1);
-
-                if (abyte0.length > abyte1.length + i)
-                    loadStream(abyte0, i + j + 2);
-            }
-            catch (Exception ex) {
-                Log.w(TAG, "load stream error " + ex.getMessage());
-                //        ex.printStackTrace();
-                //        dump(abyte0);
+                dsq.put(buf);
+                if (streamBuffer.length > buf.length + offset + MINIMAL_PARTIAL_STREAM_LEN)
+                    loadStream(streamBuffer, offset + buf_len);
+            } catch (InterruptedException ex) {
+                Log.w(TAG, "load stream error.", ex);
             }
         }
     }
 
-    public final byte[] readIncoming()
-    throws IOException {
+    private boolean isOpcodeShifted(byte[] streamBuffer, int offset) {
+        byte code = streamBuffer[offset + 1 + OPCODE_OFFSET];
+        return (0 <= code && code <= 12);
+    }
+
+    private boolean isBufferShifted(int partialLen, int bufferLen) {
+        return partialLen + MINIMAL_PARTIAL_STREAM_LEN + 1 == bufferLen;
+    }
+
+    public final byte[] readIncoming() throws IOException {
         boolean done = false;
         boolean negotiate = false;
         baosin.reset();
         int j = -1;
-        int i = 0;
         Timer timer = new Timer("data.stream", true);
         TimerTask task = null;
 
@@ -164,7 +154,7 @@
                 timer.schedule(task, 10);   // 10 ms delay
             }
 
-            i = bin.read();
+            int i = bin.read();
 
             if (task != null) {
                 task.cancel();
@@ -235,9 +225,7 @@
         //     Impacts the run method! Added the null check.
         byte[] rBytes = baosin.toByteArray();
 
-        if (dumpBytes) {
-            dump(rBytes);
-        }
+        dataStreamDumper.dump(rBytes);
 
         if (negotiate) {
             if (bin.available() == 0) {
@@ -269,104 +257,7 @@
         return rBytes;
     }
 
-    protected final void toggleDebug(ICodePage cp) {
-        if (codePage == null)
-            codePage = cp;
-
-        dumpBytes = !dumpBytes;
-
-        if (dumpBytes) {
-            try {
-                if (fw == null) {
-                    fw = new FileOutputStream("log.txt");
-                    dw = new BufferedOutputStream(fw);
-                }
-            }
-            catch (FileNotFoundException fnfe) {
-                Log.w(TAG, fnfe.getMessage());
-            }
-        }
-        else {
-            try {
-                if (dw != null)
-                    dw.close();
-
-                if (fw != null)
-                    fw.close();
-
-                dw = null;
-                fw = null;
-                codePage = null;
-            }
-            catch (IOException ioe) {
-                Log.w(TAG, ioe.getMessage());
-            }
-        }
-
-        Log.i(TAG, "Data Stream output is now " + dumpBytes);
+    protected void toggleDebug(ICodePage codePage) {
+        dataStreamDumper.toggleDebug(codePage);
     }
 
-    public void dump(byte[] abyte0) {
-        try {
-            Log.i(TAG, "\n Buffer Dump of data from AS400: ");
-            dw.write("\r\n Buffer Dump of data from AS400: ".getBytes());
-            StringBuffer h = new StringBuffer();
-
-            for (int x = 0; x < abyte0.length; x++) {
-                if (x % 16 == 0) {
-                    System.out.println("  " + h.toString());
-                    dw.write(("  " + h.toString() + "\r\n").getBytes());
-                    h.setLength(0);
-                    h.append("+0000");
-                    h.setLength(5 - Integer.toHexString(x).length());
-                    h.append(Integer.toHexString(x).toUpperCase());
-                    System.out.print(h.toString());
-                    dw.write(h.toString().getBytes());
-                    h.setLength(0);
-                }
-
-                char ac = codePage.ebcdic2uni(abyte0[x]);
-
-                if (ac < ' ')
-                    h.append('.');
-                else
-                    h.append(ac);
-
-                if (x % 4 == 0) {
-                    System.out.print(" ");
-                    dw.write((" ").getBytes());
-                }
-
-                if (Integer.toHexString(abyte0[x] & 0xff).length() == 1) {
-                    System.out.print("0" + Integer.toHexString(abyte0[x] & 0xff).toUpperCase());
-                    dw.write(("0" + Integer.toHexString(abyte0[x] & 0xff).toUpperCase()).getBytes());
-                }
-                else {
-                    System.out.print(Integer.toHexString(abyte0[x] & 0xff).toUpperCase());
-                    dw.write((Integer.toHexString(abyte0[x] & 0xff).toUpperCase()).getBytes());
-                }
-            }
-
-            System.out.println();
-            dw.write("\r\n".getBytes());
-            dw.flush();
-        }
-        catch (EOFException _ex) { }
-        catch (Exception _ex) {
-            Log.w(TAG, "Cannot dump from host\n\r");
-        }
-    }
-
-//      public void dumpBytes() {
-//         byte shit[] = bk.buffer;
-//         for (int i = 0;i < shit.length;i++)
-//            System.out.println(i + ">" + shit[i] + "< - ascii - >" + getASCIIChar(shit[i]) + "<");
-//      }
-//
-//      public void dumpHexBytes(byte[] abyte) {
-//         byte shit[] = abyte;
-//         for (int i = 0;i < shit.length;i++)
-//            System.out.println(i + ">" + shit[i] + "< hex >" + Integer.toHexString((shit[i] & 0xff)));
-//      }
-
-}