You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/11/24 19:16:02 UTC

svn commit: r1413228 - /tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java

Author: markt
Date: Sat Nov 24 18:16:01 2012
New Revision: 1413228

URL: http://svn.apache.org/viewvc?rev=1413228&view=rev
Log:
First pass at re-factoring based on UpgradeServletInputStream

Added:
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java

Added: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java?rev=1413228&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java Sat Nov 24 18:16:01 2012
@@ -0,0 +1,119 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote.http11.upgrade;
+
+import java.io.IOException;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.WriteListener;
+
+public abstract class UpgradeServletOutputStream extends ServletOutputStream {
+
+    // Start in blocking-mode
+    private volatile Boolean writeable = null;
+    private volatile WriteListener listener = null;
+    private byte[] buffer;
+
+    @Override
+    public boolean canWrite() {
+     // If we already know the current state, return it.
+        if (writeable != null) {
+            return writeable.booleanValue();
+        }
+
+        try {
+            writeable = Boolean.valueOf(doCanWrite());
+        } catch (IOException e) {
+            listener.onError(e);
+        }
+        return writeable.booleanValue();
+    }
+
+    @Override
+    public void setWriteListener(WriteListener listener) {
+        if (listener == null) {
+            // TODO i18n
+            throw new IllegalArgumentException();
+        }
+        this.listener = listener;
+        // Switching to non-blocking. Don't know if data is available.
+        writeable = null;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        preWriteChecks();
+
+        writeInternal(new byte[] { (byte) b }, 0, 1);
+    }
+
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        preWriteChecks();
+
+        writeInternal(b, off, len);
+    }
+
+
+    private void preWriteChecks() {
+        if (writeable == null || !writeable.booleanValue()) {
+            // TODO i18n
+            throw new IllegalStateException();
+        }
+        // No longer know if data is available
+        writeable = null;
+    }
+
+
+    private void writeInternal(byte[] b, int off, int len) throws IOException {
+        if (listener == null) {
+            // Simple case - blocking IO
+            doWrite(true, b, off, len);
+        } else {
+            // Non-blocking IO
+            int written = doWrite(false, b, off, len);
+            if (written < len) {
+                // TODO: - Reuse the buffer
+                //       - Only reallocate if it gets too big (>8k?)
+                buffer = new byte[len - written];
+                System.arraycopy(b, off + written, buffer, 0, len - written);
+            } else {
+                buffer = null;
+            }
+        }
+    }
+
+
+    protected void onWritePossible() {
+        try {
+            writeInternal(buffer, 0, buffer.length);
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+        if (buffer == null) {
+            writeable = Boolean.TRUE;
+            listener.onWritePossible();
+        }
+    }
+
+
+    protected abstract int doWrite(boolean block, byte[] b, int off, int len)
+            throws IOException;
+
+    protected abstract boolean doCanWrite() throws IOException;
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org