Author: markt Date: Sat Nov 24 17:55:57 2012 New Revision: 1413225 URL: http://svn.apache.org/viewvc?rev=1413225&view=rev Log: Re-factoring - Make sure all read() methods work correctly when using non-blocking - Pull up special handling of single byte read since it is required by multiple protocols and by multiple overridden methods
Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java?rev=1413225&r1=1413224&r2=1413225&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java Sat Nov 24 17:55:57 2012 @@ -65,7 +65,8 @@ public class UpgradeAprServletInputStrea */ @Override - protected int doRead(boolean block) throws IOException { + protected int doRead(boolean block, byte[] b, int off, int len) + throws IOException { // TODO Auto-generated method stub return 0; } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletInputStream.java?rev=1413225&r1=1413224&r2=1413225&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletInputStream.java Sat Nov 24 17:55:57 2012 @@ -32,8 +32,9 @@ public class UpgradeBioServletInputStrea } @Override - protected int doRead(boolean block) throws IOException { - return inputStream.read(); + protected int doRead(boolean block, byte[] b, int off, int len) + throws IOException { + return inputStream.read(b, off, len); } @Override Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletInputStream.java?rev=1413225&r1=1413224&r2=1413225&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletInputStream.java Sat Nov 24 17:55:57 2012 @@ -38,19 +38,6 @@ public class UpgradeNioServletInputStrea } @Override - protected int doRead(boolean block) throws IOException { - byte[] bytes = new byte[1]; - int result = readSocket(block, bytes, 0, 1); - if (result == 0) { - return NO_DATA; - } else if (result == -1) { - return EOF; - } else { - return bytes[0] & 0xFF; - } - } - - @Override protected boolean doIsReady() throws IOException { ByteBuffer readBuffer = channel.getBufHandler().getReadBuffer(); @@ -66,7 +53,8 @@ public class UpgradeNioServletInputStrea return isReady; } - private int readSocket(boolean block, byte[] b, int off, int len) + @Override + protected int doRead(boolean block, byte[] b, int off, int len) throws IOException { ByteBuffer readBuffer = channel.getBufHandler().getReadBuffer(); Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java?rev=1413225&r1=1413224&r2=1413225&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java Sat Nov 24 17:55:57 2012 @@ -23,28 +23,35 @@ import javax.servlet.ServletInputStream; public abstract class UpgradeServletInputStream extends ServletInputStream { - protected static final int EOF = -1; - protected static final int NO_DATA = -2; - private volatile boolean finished = false; - private volatile boolean ready = true; + + // Start in blocking-mode + private volatile Boolean ready = Boolean.TRUE; private volatile ReadListener listener = null; + @Override public final boolean isFinished() { return finished; } + @Override public boolean isReady() { + // If we already know the current state, return it. + if (ready != null) { + return ready.booleanValue(); + } + try { - ready = doIsReady(); + ready = Boolean.valueOf(doIsReady()); } catch (IOException e) { listener.onError(e); } - return ready; + return ready.booleanValue(); } + @Override public void setReadListener(ReadListener listener) { if (listener == null) { @@ -52,36 +59,92 @@ public abstract class UpgradeServletInpu throw new IllegalArgumentException(); } this.listener = listener; - - isReady(); + // Switching to non-blocking. Don't know if data is available. + ready = null; } + @Override public final int read() throws IOException { - if (!ready) { + preReadChecks(); + + return readInternal(); + } + + + @Override + public int readLine(byte[] b, int off, int len) throws IOException { + preReadChecks(); + + if (len == 0) { + return 0; + } + + int r; + int pos = off; + int count = 0; + + while ((r = readInternal()) != -1) { + b[pos++] = (byte) r; + count ++; + if (r == -1 || count == len) { + break; + } + } + + if (r == -1) { + return -1; + } else { + return count; + } + } + + + @Override + public int read(byte[] b, int off, int len) throws IOException { + preReadChecks(); + + return doRead(listener == null, b, off, len); + } + + + private void preReadChecks() { + if (ready == null || !ready.booleanValue()) { // TODO i18n throw new IllegalStateException(); } + // No longer know if data is available + ready = null; + } + + + private int readInternal() throws IOException { + // Handles difference between EOF and NO DATA when reading a single byte ReadListener readListener = this.listener; - int result = doRead(readListener == null); - if (result == EOF) { + byte[] b = new byte[1]; + int result = doRead(readListener == null, b, 0, 1); + if (result == 0) { + return -1; + } else if (result == -1) { finished = true; if (readListener != null) { readListener.onAllDataRead(); } - return EOF; - } else if (result == NO_DATA) { - return EOF; + return -1; + } else { + return b[0] & 0xFF; } - return result; } + protected void onDataAvailable() { - ready = true; + ready = Boolean.TRUE; listener.onDataAvailable(); } - protected abstract int doRead(boolean block) throws IOException; + + protected abstract int doRead(boolean block, byte[] b, int off, int len) + throws IOException; protected abstract boolean doIsReady() throws IOException; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org