Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package io.undertow.servlet.spec;
  
  import org.xnio.IoUtils;
  
 
 import static org.xnio.Bits.anyAreClear;
 import static org.xnio.Bits.anyAreSet;

Output stream used for upgraded requests. This is different to ServletOutputStreamImpl as it does no buffering, and it not tied to an exchange.

Author(s):
Stuart Douglas
 
 
     private final StreamSinkChannel channel;
 
     private WriteListener listener;
     private final Executor ioExecutor;

    
If this stream is ready for a write
 
     private static final int FLAG_READY = 1;
     private static final int FLAG_CLOSED = 1 << 1;
     private static final int FLAG_DELEGATE_SHUTDOWN = 1 << 2;
 
     private int state;

    
The buffer that is in the process of being written out
 
     private ByteBuffer buffer;
 
     protected UpgradeServletOutputStream(final StreamSinkChannel channelExecutor ioExecutor) {
         this. = channel;
         this. = ioExecutor;
     }
 
     @Override
     public void write(final byte[] bthrows IOException {
         write(b, 0, b.length);
     }
 
     @Override
     public void write(final byte[] bfinal int offfinal int lenthrows IOException {
         if (anyAreSet()) {
             throw ..streamIsClosed();
         }
         if ( == null) {
             Channels.writeBlocking(, ByteBuffer.wrap(bofflen));
         } else {
             if (anyAreClear()) {
                 throw ..streamNotReady();
             }
             int res;
             ByteBuffer buffer = ByteBuffer.wrap(b);
             do {
                 res = .write(buffer);
                 if (res == 0) {
 
                     ByteBuffer copy = ByteBuffer.allocate(buffer.remaining());
                     copy.put(buffer);
                     copy.flip();
                     this. = copy;
                      =  & ~;
                     if (Thread.currentThread() == .getIoThread()) {
                         .resumeWrites();
                     } else {
                         .execute(new Runnable() {
                             @Override
                             public void run() {
                                 .resumeWrites();
                             }
                         });
                     }
                     return;
                 }
             } while (buffer.hasRemaining());
         }
     }
 
     @Override
     public void write(final int bthrows IOException {
         write(new byte[]{(byteb}, 0, 1);
     }
 
     @Override
     public void flush() throws IOException {
        if (anyAreSet()) {
            throw ..streamIsClosed();
        }
        if ( == null) {
            Channels.flushBlocking();
        }
    }
    @Override
    public void close() throws IOException {
         |= ;
         &= ~;
        if ( == null) {
            .shutdownWrites();
             |= ;
            Channels.flushBlocking();
        } else {
            if ( == null) {
                .shutdownWrites();
                 |= ;
                if (!.flush()) {
                    if (Thread.currentThread() == .getIoThread()) {
                        .resumeWrites();
                    } else {
                        .execute(new Runnable() {
                            @Override
                            public void run() {
                                .resumeWrites();
                            }
                        });
                    }
                }
            }
        }
    }
    void closeBlocking() throws IOException {
         |= ;
        try {
            if ( != null) {
                Channels.writeBlocking();
            }
            .shutdownWrites();
            Channels.flushBlocking();
        } finally {
            .close();
        }
    }
    @Override
    public boolean isReady() {
        if ( == null) {
            //TODO: is this the correct behaviour?
            throw ..streamNotInAsyncMode();
        }
        return anyAreSet();
    }
    @Override
    public void setWriteListener(final WriteListener writeListener) {
        if (writeListener == null) {
            throw ..paramCannotBeNull("writeListener");
        }
        if ( != null) {
            throw ..listenerAlreadySet();
        }
         = writeListener;
         |= ;
        .execute(new Runnable() {
            @Override
            public void run() {
                .resumeWrites();
            }
        });
    }
    private class WriteChannelListener implements ChannelListener<StreamSinkChannel> {
        @Override
        public void handleEvent(final StreamSinkChannel channel) {
            //flush the channel if it is closed
            if (anyAreSet()) {
                try {
                    //either it will work, and the channel is closed
                    //or it won't, and we continue with writes resumed
                    channel.flush();
                    return;
                } catch (IOException e) {
                    handleError(channele);
                }
            }
            //if there is data still to write
            if ( != null) {
                int res;
                do {
                    try {
                        res = channel.write();
                        if (res == 0) {
                            return;
                        }
                    } catch (IOException e) {
                        handleError(channele);
                    }
                } while (.hasRemaining());
                 = null;
            }
            if (anyAreSet()) {
                try {
                    channel.shutdownWrites();
                     |= ;
                    channel.flush(); //if this does not succeed we are already resumed anyway
                } catch (IOException e) {
                    handleError(channele);
                }
            } else {
                 |= ;
                channel.suspendWrites();
                try {
                    .onWritePossible();
                } catch (IOException e) {
                    .onError(e);
                }
            }
        }
        private void handleError(final StreamSinkChannel channelfinal IOException e) {
            try {
                .onError(e);
            } finally {
                IoUtils.safeClose(channel);
            }
        }
    }
New to GrepCode? Check out our FAQ X