2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.io;
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.nio.ByteBuffer;
24 import java.nio.channels.ClosedChannelException;
25 import java.nio.charset.Charset;
26 import java.nio.charset.StandardCharsets;
28 import org.eclipse.jetty.util.BufferUtil;
29 import org.eclipse.jetty.util.log.Log;
30 import org.eclipse.jetty.util.log.Logger;
31 import org.eclipse.jetty.util.thread.Scheduler;
34 /* ------------------------------------------------------------ */
35 /** ByteArrayEndPoint.
38 public class ByteArrayEndPoint extends AbstractEndPoint
40 static final Logger LOG = Log.getLogger(ByteArrayEndPoint.class);
41 public final static InetSocketAddress NOIP=new InetSocketAddress(0);
43 protected volatile ByteBuffer _in;
44 protected volatile ByteBuffer _out;
45 protected volatile boolean _ishut;
46 protected volatile boolean _oshut;
47 protected volatile boolean _closed;
48 protected volatile boolean _growOutput;
51 /* ------------------------------------------------------------ */
55 public ByteArrayEndPoint()
57 this(null,0,null,null);
60 /* ------------------------------------------------------------ */
64 public ByteArrayEndPoint(byte[] input, int outputSize)
66 this(null,0,input!=null?BufferUtil.toBuffer(input):null,BufferUtil.allocate(outputSize));
69 /* ------------------------------------------------------------ */
73 public ByteArrayEndPoint(String input, int outputSize)
75 this(null,0,input!=null?BufferUtil.toBuffer(input):null,BufferUtil.allocate(outputSize));
78 /* ------------------------------------------------------------ */
79 public ByteArrayEndPoint(Scheduler scheduler, long idleTimeoutMs)
81 this(scheduler,idleTimeoutMs,null,null);
84 /* ------------------------------------------------------------ */
85 public ByteArrayEndPoint(Scheduler timer, long idleTimeoutMs, byte[] input, int outputSize)
87 this(timer,idleTimeoutMs,input!=null?BufferUtil.toBuffer(input):null,BufferUtil.allocate(outputSize));
90 /* ------------------------------------------------------------ */
91 public ByteArrayEndPoint(Scheduler timer, long idleTimeoutMs, String input, int outputSize)
93 this(timer,idleTimeoutMs,input!=null?BufferUtil.toBuffer(input):null,BufferUtil.allocate(outputSize));
96 /* ------------------------------------------------------------ */
97 public ByteArrayEndPoint(Scheduler timer, long idleTimeoutMs, ByteBuffer input, ByteBuffer output)
99 super(timer,NOIP,NOIP);
100 _in=input==null?BufferUtil.EMPTY_BUFFER:input;
101 _out=output==null?BufferUtil.allocate(1024):output;
102 setIdleTimeout(idleTimeoutMs);
109 /* ------------------------------------------------------------ */
111 protected void onIncompleteFlush()
113 // Don't need to do anything here as takeOutput does the signalling.
116 /* ------------------------------------------------------------ */
118 protected boolean needsFill() throws IOException
121 throw new ClosedChannelException();
122 return _in == null || BufferUtil.hasContent(_in);
125 /* ------------------------------------------------------------ */
127 * @return Returns the in.
129 public ByteBuffer getIn()
134 /* ------------------------------------------------------------ */
137 public void setInputEOF()
142 /* ------------------------------------------------------------ */
144 * @param in The in to set.
146 public void setInput(ByteBuffer in)
149 if (in == null || BufferUtil.hasContent(in))
150 getFillInterest().fillable();
153 /* ------------------------------------------------------------ */
154 public void setInput(String s)
156 setInput(BufferUtil.toBuffer(s,StandardCharsets.UTF_8));
159 /* ------------------------------------------------------------ */
160 public void setInput(String s,Charset charset)
162 setInput(BufferUtil.toBuffer(s,charset));
165 /* ------------------------------------------------------------ */
167 * @return Returns the out.
169 public ByteBuffer getOutput()
174 /* ------------------------------------------------------------ */
176 * @return Returns the out.
178 public String getOutputString()
180 return getOutputString(StandardCharsets.UTF_8);
183 /* ------------------------------------------------------------ */
185 * @return Returns the out.
187 public String getOutputString(Charset charset)
189 return BufferUtil.toString(_out,charset);
192 /* ------------------------------------------------------------ */
194 * @return Returns the out.
196 public ByteBuffer takeOutput()
199 _out=BufferUtil.allocate(b.capacity());
200 getWriteFlusher().completeWrite();
204 /* ------------------------------------------------------------ */
206 * @return Returns the out.
208 public String takeOutputString()
210 return takeOutputString(StandardCharsets.UTF_8);
213 /* ------------------------------------------------------------ */
215 * @return Returns the out.
217 public String takeOutputString(Charset charset)
219 ByteBuffer buffer=takeOutput();
220 return BufferUtil.toString(buffer,charset);
223 /* ------------------------------------------------------------ */
225 * @param out The out to set.
227 public void setOutput(ByteBuffer out)
230 getWriteFlusher().completeWrite();
233 /* ------------------------------------------------------------ */
235 * @see org.eclipse.io.EndPoint#isOpen()
238 public boolean isOpen()
243 /* ------------------------------------------------------------ */
247 public boolean isInputShutdown()
249 return _ishut||_closed;
252 /* ------------------------------------------------------------ */
256 public boolean isOutputShutdown()
258 return _oshut||_closed;
261 /* ------------------------------------------------------------ */
262 private void shutdownInput()
269 /* ------------------------------------------------------------ */
271 * @see org.eclipse.io.EndPoint#shutdownOutput()
274 public void shutdownOutput()
281 /* ------------------------------------------------------------ */
283 * @see org.eclipse.io.EndPoint#close()
292 /* ------------------------------------------------------------ */
294 * @return <code>true</code> if there are bytes remaining to be read from the encoded input
296 public boolean hasMore()
298 return getOutput().position()>0;
301 /* ------------------------------------------------------------ */
303 * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
306 public int fill(ByteBuffer buffer) throws IOException
309 throw new EofException("CLOSED");
314 int filled=BufferUtil.append(buffer,_in);
320 /* ------------------------------------------------------------ */
322 * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
325 public boolean flush(ByteBuffer... buffers) throws IOException
328 throw new IOException("CLOSED");
330 throw new IOException("OSHUT");
332 boolean flushed=true;
335 for (ByteBuffer b : buffers)
337 if (BufferUtil.hasContent(b))
339 if (_growOutput && b.remaining()>BufferUtil.space(_out))
341 BufferUtil.compact(_out);
342 if (b.remaining()>BufferUtil.space(_out))
344 ByteBuffer n = BufferUtil.allocate(_out.capacity()+b.remaining()*2);
345 BufferUtil.append(n,_out);
350 if (BufferUtil.append(_out,b)>0)
353 if (BufferUtil.hasContent(b))
365 /* ------------------------------------------------------------ */
371 getFillInterest().onClose();
372 getWriteFlusher().onClose();
377 BufferUtil.clear(_out);
380 /* ------------------------------------------------------------ */
382 * @see org.eclipse.io.EndPoint#getConnection()
385 public Object getTransport()
390 /* ------------------------------------------------------------ */
392 * @return the growOutput
394 public boolean isGrowOutput()
399 /* ------------------------------------------------------------ */
401 * @param growOutput the growOutput to set
403 public void setGrowOutput(boolean growOutput)
405 _growOutput=growOutput;