Mercurial Hosting > luan
changeset 1010:2712133d5bce
simplify Buffer code
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 23 Oct 2016 22:23:50 -0600 |
parents | c3a04bded909 |
children | 4e7208df7741 |
files | src/org/eclipse/jetty/io/AbstractBuffer.java src/org/eclipse/jetty/io/Buffer.java src/org/eclipse/jetty/io/ByteArrayBuffer.java src/org/eclipse/jetty/io/nio/DirectNIOBuffer.java src/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java src/org/eclipse/jetty/io/nio/NIOBuffer.java src/org/eclipse/jetty/server/AbstractHttpConnection.java |
diffstat | 7 files changed, 902 insertions(+), 1126 deletions(-) [+] |
line wrap: on
line diff
--- a/src/org/eclipse/jetty/io/AbstractBuffer.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/io/AbstractBuffer.java Sun Oct 23 22:23:50 2016 -0600 @@ -92,15 +92,6 @@ return new ByteArrayBuffer(asArray(), 0, length(), access); } - /* - * @see org.eclipse.io.Buffer#asNonVolatile() - */ - public Buffer asNonVolatileBuffer() - { - if (!isVolatile()) return this; - return duplicate(_access); - } - public Buffer asImmutableBuffer() { if (isImmutable()) return this; @@ -116,18 +107,6 @@ return new View(this, markIndex(), getIndex(), putIndex(), READONLY); } - public Buffer asMutableBuffer() - { - if (!isImmutable()) return this; - - Buffer b=this.buffer(); - if (b.isReadOnly()) - { - return duplicate(READWRITE); - } - return new View(b, markIndex(), getIndex(), putIndex(), _access); - } - public Buffer buffer() { return this; @@ -669,32 +648,6 @@ } /* ------------------------------------------------------------ */ - public void writeTo(OutputStream out) - throws IOException - { - byte[] array = array(); - - if (array!=null) - { - out.write(array,getIndex(),length()); - } - else - { - int len = this.length(); - byte[] buf=new byte[len>1024?1024:len]; - int offset=_get; - while (len>0) - { - int l=peek(offset,buf,0,len>buf.length?buf.length:len); - out.write(buf,0,l); - offset+=l; - len-=l; - } - } - clear(); - } - - /* ------------------------------------------------------------ */ public int readFrom(InputStream in,int max) throws IOException { byte[] array = array();
--- a/src/org/eclipse/jetty/io/Buffer.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/io/Buffer.java Sun Oct 23 22:23:50 2016 -0600 @@ -42,339 +42,321 @@ */ public interface Buffer extends Cloneable { - public final static int - IMMUTABLE=0, // neither indexes or contexts can be changed - READONLY=1, // indexes may be changed, but not content - READWRITE=2; // anything can be changed - public final boolean VOLATILE=true; // The buffer may change outside of current scope. - public final boolean NON_VOLATILE=false; + public final static int + IMMUTABLE=0, // neither indexes or contexts can be changed + READONLY=1, // indexes may be changed, but not content + READWRITE=2; // anything can be changed + public final boolean VOLATILE=true; // The buffer may change outside of current scope. + public final boolean NON_VOLATILE=false; - /** - * Get the underlying array, if one exists. - * @return a <code>byte[]</code> backing this buffer or null if none exists. - */ - byte[] array(); - - /** - * - * @return a <code>byte[]</code> value of the bytes from the getIndex to the putIndex. - */ - byte[] asArray(); - - /** - * Get the underlying buffer. If this buffer wraps a backing buffer. - * @return The root backing buffer or this if there is no backing buffer; - */ - Buffer buffer(); - - /** - * - * @return a non volatile version of this <code>Buffer</code> value - */ - Buffer asNonVolatileBuffer(); + /** + * Get the underlying array, if one exists. + * @return a <code>byte[]</code> backing this buffer or null if none exists. + */ + byte[] array(); + + /** + * + * @return a <code>byte[]</code> value of the bytes from the getIndex to the putIndex. + */ + byte[] asArray(); + + /** + * Get the underlying buffer. If this buffer wraps a backing buffer. + * @return The root backing buffer or this if there is no backing buffer; + */ + Buffer buffer(); + + /** + * + * @return a readonly version of this <code>Buffer</code>. + */ + Buffer asReadOnlyBuffer(); - /** - * - * @return a readonly version of this <code>Buffer</code>. - */ - Buffer asReadOnlyBuffer(); - - /** - * - * @return an immutable version of this <code>Buffer</code>. - */ - Buffer asImmutableBuffer(); + /** + * + * @return an immutable version of this <code>Buffer</code>. + */ + Buffer asImmutableBuffer(); - /** - * - * @return an immutable version of this <code>Buffer</code>. - */ - Buffer asMutableBuffer(); - - /** - * - * The capacity of the buffer. This is the maximum putIndex that may be set. - * @return an <code>int</code> value - */ - int capacity(); - - /** - * the space remaining in the buffer. - * @return capacity - putIndex - */ - int space(); - - /** - * Clear the buffer. getIndex=0, putIndex=0. - */ - void clear(); + /** + * + * The capacity of the buffer. This is the maximum putIndex that may be set. + * @return an <code>int</code> value + */ + int capacity(); + + /** + * the space remaining in the buffer. + * @return capacity - putIndex + */ + int space(); + + /** + * Clear the buffer. getIndex=0, putIndex=0. + */ + void clear(); - /** - * Compact the buffer by discarding bytes before the postion (or mark if set). - * Bytes from the getIndex (or mark) to the putIndex are moved to the beginning of - * the buffer and the values adjusted accordingly. - */ - void compact(); - - /** - * Get the byte at the current getIndex and increment it. - * @return The <code>byte</code> value from the current getIndex. - */ - byte get(); - - /** - * Get bytes from the current postion and put them into the passed byte array. - * The getIndex is incremented by the number of bytes copied into the array. - * @param b The byte array to fill. - * @param offset Offset in the array. - * @param length The max number of bytes to read. - * @return The number of bytes actually read. - */ - int get(byte[] b, int offset, int length); + /** + * Compact the buffer by discarding bytes before the postion (or mark if set). + * Bytes from the getIndex (or mark) to the putIndex are moved to the beginning of + * the buffer and the values adjusted accordingly. + */ + void compact(); + + /** + * Get the byte at the current getIndex and increment it. + * @return The <code>byte</code> value from the current getIndex. + */ + byte get(); + + /** + * Get bytes from the current postion and put them into the passed byte array. + * The getIndex is incremented by the number of bytes copied into the array. + * @param b The byte array to fill. + * @param offset Offset in the array. + * @param length The max number of bytes to read. + * @return The number of bytes actually read. + */ + int get(byte[] b, int offset, int length); - /** - * - * @param length an <code>int</code> value - * @return a <code>Buffer</code> value - */ - Buffer get(int length); + /** + * + * @param length an <code>int</code> value + * @return a <code>Buffer</code> value + */ + Buffer get(int length); - /** - * The index within the buffer that will next be read or written. - * @return an <code>int</code> value >=0 <= putIndex() - */ - int getIndex(); - - /** - * @return true of putIndex > getIndex - */ - boolean hasContent(); - - /** - * - * @return a <code>boolean</code> value true if case sensitive comparison on this buffer - */ - boolean equalsIgnoreCase(Buffer buffer); + /** + * The index within the buffer that will next be read or written. + * @return an <code>int</code> value >=0 <= putIndex() + */ + int getIndex(); + + /** + * @return true of putIndex > getIndex + */ + boolean hasContent(); + + /** + * + * @return a <code>boolean</code> value true if case sensitive comparison on this buffer + */ + boolean equalsIgnoreCase(Buffer buffer); - /** - * - * @return a <code>boolean</code> value true if the buffer is immutable and that neither - * the buffer contents nor the indexes may be changed. - */ - boolean isImmutable(); - - /** - * - * @return a <code>boolean</code> value true if the buffer is readonly. The buffer indexes may - * be modified, but the buffer contents may not. For example a View onto an immutable Buffer will be - * read only. - */ - boolean isReadOnly(); - - /** - * - * @return a <code>boolean</code> value true if the buffer contents may change - * via alternate paths than this buffer. If the contents of this buffer are to be used outside of the - * current context, then a copy must be made. - */ - boolean isVolatile(); + /** + * + * @return a <code>boolean</code> value true if the buffer is immutable and that neither + * the buffer contents nor the indexes may be changed. + */ + boolean isImmutable(); + + /** + * + * @return a <code>boolean</code> value true if the buffer is readonly. The buffer indexes may + * be modified, but the buffer contents may not. For example a View onto an immutable Buffer will be + * read only. + */ + boolean isReadOnly(); + + /** + * + * @return a <code>boolean</code> value true if the buffer contents may change + * via alternate paths than this buffer. If the contents of this buffer are to be used outside of the + * current context, then a copy must be made. + */ + boolean isVolatile(); - /** - * The number of bytes from the getIndex to the putIndex - * @return an <code>int</code> == putIndex()-getIndex() - */ - int length(); - - /** - * Set the mark to the current getIndex. - */ - void mark(); - - /** - * Set the mark relative to the current getIndex - * @param offset an <code>int</code> value to add to the current getIndex to obtain the mark value. - */ - void mark(int offset); + /** + * The number of bytes from the getIndex to the putIndex + * @return an <code>int</code> == putIndex()-getIndex() + */ + int length(); + + /** + * Set the mark to the current getIndex. + */ + void mark(); + + /** + * Set the mark relative to the current getIndex + * @param offset an <code>int</code> value to add to the current getIndex to obtain the mark value. + */ + void mark(int offset); - /** - * The current index of the mark. - * @return an <code>int</code> index in the buffer or -1 if the mark is not set. - */ - int markIndex(); + /** + * The current index of the mark. + * @return an <code>int</code> index in the buffer or -1 if the mark is not set. + */ + int markIndex(); - /** - * Get the byte at the current getIndex without incrementing the getIndex. - * @return The <code>byte</code> value from the current getIndex. - */ - byte peek(); + /** + * Get the byte at the current getIndex without incrementing the getIndex. + * @return The <code>byte</code> value from the current getIndex. + */ + byte peek(); - /** - * Get the byte at a specific index in the buffer. - * @param index an <code>int</code> value - * @return a <code>byte</code> value - */ - byte peek(int index); + /** + * Get the byte at a specific index in the buffer. + * @param index an <code>int</code> value + * @return a <code>byte</code> value + */ + byte peek(int index); - /** - * - * @param index an <code>int</code> value - * @param length an <code>int</code> value - * @return The <code>Buffer</code> value from the requested getIndex. - */ - Buffer peek(int index, int length); + /** + * + * @param index an <code>int</code> value + * @param length an <code>int</code> value + * @return The <code>Buffer</code> value from the requested getIndex. + */ + Buffer peek(int index, int length); - /** - * - * @param index an <code>int</code> value - * @param b The byte array to peek into - * @param offset The offset into the array to start peeking - * @param length an <code>int</code> value - * @return The number of bytes actually peeked - */ - int peek(int index, byte[] b, int offset, int length); - - /** - * Put the contents of the buffer at the specific index. - * @param index an <code>int</code> value - * @param src a <code>Buffer</code>. If the source buffer is not modified - - * @return The number of bytes actually poked - */ - int poke(int index, Buffer src); - - /** - * Put a specific byte to a specific getIndex. - * @param index an <code>int</code> value - * @param b a <code>byte</code> value - */ - void poke(int index, byte b); - - /** - * Put a specific byte to a specific getIndex. - * @param index an <code>int</code> value - * @param b a <code>byte array</code> value - * @return The number of bytes actually poked - */ - int poke(int index, byte b[], int offset, int length); - - /** - * Write the bytes from the source buffer to the current getIndex. - * @param src The source <code>Buffer</code> it is not modified. - * @return The number of bytes actually poked - */ - int put(Buffer src); + /** + * + * @param index an <code>int</code> value + * @param b The byte array to peek into + * @param offset The offset into the array to start peeking + * @param length an <code>int</code> value + * @return The number of bytes actually peeked + */ + int peek(int index, byte[] b, int offset, int length); + + /** + * Put the contents of the buffer at the specific index. + * @param index an <code>int</code> value + * @param src a <code>Buffer</code>. If the source buffer is not modified + + * @return The number of bytes actually poked + */ + int poke(int index, Buffer src); + + /** + * Put a specific byte to a specific getIndex. + * @param index an <code>int</code> value + * @param b a <code>byte</code> value + */ + void poke(int index, byte b); + + /** + * Put a specific byte to a specific getIndex. + * @param index an <code>int</code> value + * @param b a <code>byte array</code> value + * @return The number of bytes actually poked + */ + int poke(int index, byte b[], int offset, int length); + + /** + * Write the bytes from the source buffer to the current getIndex. + * @param src The source <code>Buffer</code> it is not modified. + * @return The number of bytes actually poked + */ + int put(Buffer src); - /** - * Put a byte to the current getIndex and increment the getIndex. - * @param b a <code>byte</code> value - */ - void put(byte b); - - /** - * Put a byte to the current getIndex and increment the getIndex. - * @param b a <code>byte</code> value - * @return The number of bytes actually poked - */ - int put(byte[] b,int offset, int length); - - /** - * Put a byte to the current getIndex and increment the getIndex. - * @param b a <code>byte</code> value - * @return The number of bytes actually poked - */ - int put(byte[] b); + /** + * Put a byte to the current getIndex and increment the getIndex. + * @param b a <code>byte</code> value + */ + void put(byte b); + + /** + * Put a byte to the current getIndex and increment the getIndex. + * @param b a <code>byte</code> value + * @return The number of bytes actually poked + */ + int put(byte[] b,int offset, int length); - /** - * The index of the first element that should not be read. - * @return an <code>int</code> value >= getIndex() - */ - int putIndex(); - - /** - * Reset the current getIndex to the mark - */ - void reset(); - - /** - * Set the buffers start getIndex. - * @param newStart an <code>int</code> value - */ - void setGetIndex(int newStart); - - /** - * Set a specific value for the mark. - * @param newMark an <code>int</code> value - */ - void setMarkIndex(int newMark); - - /** - * - * @param newLimit an <code>int</code> value - */ - void setPutIndex(int newLimit); - - /** - * Skip _content. The getIndex is updated by min(remaining(), n) - * @param n The number of bytes to skip - * @return the number of bytes skipped. - */ - int skip(int n); + /** + * Put a byte to the current getIndex and increment the getIndex. + * @param b a <code>byte</code> value + * @return The number of bytes actually poked + */ + int put(byte[] b); - /** - * - * @return a volitile <code>Buffer</code> from the postion to the putIndex. - */ - Buffer slice(); - - /** - * - * - * @return a volitile <code>Buffer</code> value from the mark to the putIndex - */ - Buffer sliceFromMark(); - - /** - * - * - * @param length an <code>int</code> value - * @return a valitile <code>Buffer</code> value from the mark of the length requested. - */ - Buffer sliceFromMark(int length); - - /** - * - * @return a <code>String</code> value describing the state and contents of the buffer. - */ - String toDetailString(); + /** + * The index of the first element that should not be read. + * @return an <code>int</code> value >= getIndex() + */ + int putIndex(); + + /** + * Reset the current getIndex to the mark + */ + void reset(); + + /** + * Set the buffers start getIndex. + * @param newStart an <code>int</code> value + */ + void setGetIndex(int newStart); + + /** + * Set a specific value for the mark. + * @param newMark an <code>int</code> value + */ + void setMarkIndex(int newMark); + + /** + * + * @param newLimit an <code>int</code> value + */ + void setPutIndex(int newLimit); + + /** + * Skip _content. The getIndex is updated by min(remaining(), n) + * @param n The number of bytes to skip + * @return the number of bytes skipped. + */ + int skip(int n); - /* ------------------------------------------------------------ */ - /** Write the buffer's contents to the output stream - * @param out - */ - void writeTo(OutputStream out) throws IOException; - - /* ------------------------------------------------------------ */ - /** Read the buffer's contents from the input stream - * @param in input stream - * @param max maximum number of bytes that may be read - * @return actual number of bytes read or -1 for EOF - */ - int readFrom(InputStream in, int max) throws IOException; - + /** + * + * @return a volitile <code>Buffer</code> from the postion to the putIndex. + */ + Buffer slice(); + + /** + * + * + * @return a volitile <code>Buffer</code> value from the mark to the putIndex + */ + Buffer sliceFromMark(); + + /** + * + * + * @param length an <code>int</code> value + * @return a valitile <code>Buffer</code> value from the mark of the length requested. + */ + Buffer sliceFromMark(int length); + + /** + * + * @return a <code>String</code> value describing the state and contents of the buffer. + */ + String toDetailString(); - /* ------------------------------------------------------------ */ - String toString(String charset); - - /* ------------------------------------------------------------ */ - String toString(Charset charset); + /* ------------------------------------------------------------ */ + /** Read the buffer's contents from the input stream + * @param in input stream + * @param max maximum number of bytes that may be read + * @return actual number of bytes read or -1 for EOF + */ + int readFrom(InputStream in, int max) throws IOException; + - /* - * Buffers implementing this interface should be compared with case insensitive equals - * - */ - public interface CaseInsensitve - {} + /* ------------------------------------------------------------ */ + String toString(String charset); + + /* ------------------------------------------------------------ */ + String toString(Charset charset); - + /* + * Buffers implementing this interface should be compared with case insensitive equals + * + */ + public interface CaseInsensitve + {} + + }
--- a/src/org/eclipse/jetty/io/ByteArrayBuffer.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/io/ByteArrayBuffer.java Sun Oct 23 22:23:50 2016 -0600 @@ -31,409 +31,385 @@ */ public class ByteArrayBuffer extends AbstractBuffer { - // Set a maximum size to a write for the writeTo method, to ensure that very large content is not - // written as a single write (which may fall foul to write timeouts if consumed slowly). - final static int MAX_WRITE=Integer.getInteger("org.eclipse.jetty.io.ByteArrayBuffer.MAX_WRITE",128*1024); - final protected byte[] _bytes; + // Set a maximum size to a write for the writeTo method, to ensure that very large content is not + // written as a single write (which may fall foul to write timeouts if consumed slowly). + final static int MAX_WRITE=Integer.getInteger("org.eclipse.jetty.io.ByteArrayBuffer.MAX_WRITE",128*1024); + final protected byte[] _bytes; - protected ByteArrayBuffer(int size, int access, boolean isVolatile) - { - this(new byte[size],0,0,access, isVolatile); - } - - public ByteArrayBuffer(byte[] bytes) - { - this(bytes, 0, bytes.length, READWRITE); - } + protected ByteArrayBuffer(int size, int access, boolean isVolatile) + { + this(new byte[size],0,0,access, isVolatile); + } + + public ByteArrayBuffer(byte[] bytes) + { + this(bytes, 0, bytes.length, READWRITE); + } - public ByteArrayBuffer(byte[] bytes, int index, int length) - { - this(bytes, index, length, READWRITE); - } + public ByteArrayBuffer(byte[] bytes, int index, int length) + { + this(bytes, index, length, READWRITE); + } - public ByteArrayBuffer(byte[] bytes, int index, int length, int access) - { - super(READWRITE, NON_VOLATILE); - _bytes = bytes; - setPutIndex(index + length); - setGetIndex(index); - _access = access; - } + public ByteArrayBuffer(byte[] bytes, int index, int length, int access) + { + super(READWRITE, NON_VOLATILE); + _bytes = bytes; + setPutIndex(index + length); + setGetIndex(index); + _access = access; + } - public ByteArrayBuffer(byte[] bytes, int index, int length, int access, boolean isVolatile) - { - super(READWRITE, isVolatile); - _bytes = bytes; - setPutIndex(index + length); - setGetIndex(index); - _access = access; - } + public ByteArrayBuffer(byte[] bytes, int index, int length, int access, boolean isVolatile) + { + super(READWRITE, isVolatile); + _bytes = bytes; + setPutIndex(index + length); + setGetIndex(index); + _access = access; + } - public ByteArrayBuffer(int size) - { - this(new byte[size], 0, 0, READWRITE); - setPutIndex(0); - } + public ByteArrayBuffer(int size) + { + this(new byte[size], 0, 0, READWRITE); + setPutIndex(0); + } - public ByteArrayBuffer(String value) - { - super(READWRITE,NON_VOLATILE); - _bytes = StringUtil.getBytes(value); - setGetIndex(0); - setPutIndex(_bytes.length); - _access=IMMUTABLE; - _string = value; - } - - public ByteArrayBuffer(String value,boolean immutable) - { - super(READWRITE,NON_VOLATILE); - _bytes = StringUtil.getBytes(value); - setGetIndex(0); - setPutIndex(_bytes.length); - if (immutable) - { - _access=IMMUTABLE; - _string = value; - } - } + public ByteArrayBuffer(String value) + { + super(READWRITE,NON_VOLATILE); + _bytes = StringUtil.getBytes(value); + setGetIndex(0); + setPutIndex(_bytes.length); + _access=IMMUTABLE; + _string = value; + } + + public ByteArrayBuffer(String value,boolean immutable) + { + super(READWRITE,NON_VOLATILE); + _bytes = StringUtil.getBytes(value); + setGetIndex(0); + setPutIndex(_bytes.length); + if (immutable) + { + _access=IMMUTABLE; + _string = value; + } + } - public ByteArrayBuffer(String value,String encoding) throws UnsupportedEncodingException - { - super(READWRITE,NON_VOLATILE); - _bytes = value.getBytes(encoding); - setGetIndex(0); - setPutIndex(_bytes.length); - _access=IMMUTABLE; - _string = value; - } + public ByteArrayBuffer(String value,String encoding) throws UnsupportedEncodingException + { + super(READWRITE,NON_VOLATILE); + _bytes = value.getBytes(encoding); + setGetIndex(0); + setPutIndex(_bytes.length); + _access=IMMUTABLE; + _string = value; + } - public byte[] array() - { - return _bytes; - } + public byte[] array() + { + return _bytes; + } - public int capacity() - { - return _bytes.length; - } - - @Override - public void compact() - { - if (isReadOnly()) - throw new IllegalStateException(__READONLY); - int s = markIndex() >= 0 ? markIndex() : getIndex(); - if (s > 0) - { - int length = putIndex() - s; - if (length > 0) - { - System.arraycopy(_bytes, s,_bytes, 0, length); - } - if (markIndex() > 0) setMarkIndex(markIndex() - s); - setGetIndex(getIndex() - s); - setPutIndex(putIndex() - s); - } - } + public int capacity() + { + return _bytes.length; + } + + @Override + public void compact() + { + if (isReadOnly()) + throw new IllegalStateException(__READONLY); + int s = markIndex() >= 0 ? markIndex() : getIndex(); + if (s > 0) + { + int length = putIndex() - s; + if (length > 0) + { + System.arraycopy(_bytes, s,_bytes, 0, length); + } + if (markIndex() > 0) setMarkIndex(markIndex() - s); + setGetIndex(getIndex() - s); + setPutIndex(putIndex() - s); + } + } - @Override - public boolean equals(Object obj) - { - if (obj==this) - return true; + @Override + public boolean equals(Object obj) + { + if (obj==this) + return true; - if (obj == null || !(obj instanceof Buffer)) - return false; - - if (obj instanceof Buffer.CaseInsensitve) - return equalsIgnoreCase((Buffer)obj); - + if (obj == null || !(obj instanceof Buffer)) + return false; + + if (obj instanceof Buffer.CaseInsensitve) + return equalsIgnoreCase((Buffer)obj); + - Buffer b = (Buffer) obj; - - // reject different lengths - if (b.length() != length()) - return false; + Buffer b = (Buffer) obj; + + // reject different lengths + if (b.length() != length()) + return false; - // reject AbstractBuffer with different hash value - if (_hash != 0 && obj instanceof AbstractBuffer) - { - AbstractBuffer ab = (AbstractBuffer) obj; - if (ab._hash != 0 && _hash != ab._hash) - return false; - } + // reject AbstractBuffer with different hash value + if (_hash != 0 && obj instanceof AbstractBuffer) + { + AbstractBuffer ab = (AbstractBuffer) obj; + if (ab._hash != 0 && _hash != ab._hash) + return false; + } - // Nothing for it but to do the hard grind. - int get=getIndex(); - int bi=b.putIndex(); - for (int i = putIndex(); i-->get;) - { - byte b1 = _bytes[i]; - byte b2 = b.peek(--bi); - if (b1 != b2) return false; - } - return true; - } + // Nothing for it but to do the hard grind. + int get=getIndex(); + int bi=b.putIndex(); + for (int i = putIndex(); i-->get;) + { + byte b1 = _bytes[i]; + byte b2 = b.peek(--bi); + if (b1 != b2) return false; + } + return true; + } - @Override - public boolean equalsIgnoreCase(Buffer b) - { - if (b==this) - return true; - - // reject different lengths - if (b==null || b.length() != length()) - return false; + @Override + public boolean equalsIgnoreCase(Buffer b) + { + if (b==this) + return true; + + // reject different lengths + if (b==null || b.length() != length()) + return false; - // reject AbstractBuffer with different hash value - if (_hash != 0 && b instanceof AbstractBuffer) - { - AbstractBuffer ab = (AbstractBuffer) b; - if (ab._hash != 0 && _hash != ab._hash) return false; - } + // reject AbstractBuffer with different hash value + if (_hash != 0 && b instanceof AbstractBuffer) + { + AbstractBuffer ab = (AbstractBuffer) b; + if (ab._hash != 0 && _hash != ab._hash) return false; + } - // Nothing for it but to do the hard grind. - int get=getIndex(); - int bi=b.putIndex(); - byte[] barray=b.array(); - if (barray==null) - { - for (int i = putIndex(); i-->get;) - { - byte b1 = _bytes[i]; - byte b2 = b.peek(--bi); - if (b1 != b2) - { - if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); - if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); - if (b1 != b2) return false; - } - } - } - else - { - for (int i = putIndex(); i-->get;) - { - byte b1 = _bytes[i]; - byte b2 = barray[--bi]; - if (b1 != b2) - { - if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); - if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); - if (b1 != b2) return false; - } - } - } - return true; - } + // Nothing for it but to do the hard grind. + int get=getIndex(); + int bi=b.putIndex(); + byte[] barray=b.array(); + if (barray==null) + { + for (int i = putIndex(); i-->get;) + { + byte b1 = _bytes[i]; + byte b2 = b.peek(--bi); + if (b1 != b2) + { + if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); + if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); + if (b1 != b2) return false; + } + } + } + else + { + for (int i = putIndex(); i-->get;) + { + byte b1 = _bytes[i]; + byte b2 = barray[--bi]; + if (b1 != b2) + { + if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); + if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); + if (b1 != b2) return false; + } + } + } + return true; + } - @Override - public byte get() - { - return _bytes[_get++]; - } + @Override + public byte get() + { + return _bytes[_get++]; + } - @Override - public int hashCode() - { - if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) - { - int get=getIndex(); - for (int i = putIndex(); i-- >get;) - { - byte b = _bytes[i]; - if ('a' <= b && b <= 'z') - b = (byte) (b - 'a' + 'A'); - _hash = 31 * _hash + b; - } - if (_hash == 0) - _hash = -1; - _hashGet=_get; - _hashPut=_put; - } - return _hash; - } - - - public byte peek(int index) - { - return _bytes[index]; - } - - public int peek(int index, byte[] b, int offset, int length) - { - int l = length; - if (index + l > capacity()) - { - l = capacity() - index; - if (l==0) - return -1; - } - - if (l < 0) - return -1; - - System.arraycopy(_bytes, index, b, offset, l); - return l; - } + @Override + public int hashCode() + { + if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) + { + int get=getIndex(); + for (int i = putIndex(); i-- >get;) + { + byte b = _bytes[i]; + if ('a' <= b && b <= 'z') + b = (byte) (b - 'a' + 'A'); + _hash = 31 * _hash + b; + } + if (_hash == 0) + _hash = -1; + _hashGet=_get; + _hashPut=_put; + } + return _hash; + } + + + public byte peek(int index) + { + return _bytes[index]; + } + + public int peek(int index, byte[] b, int offset, int length) + { + int l = length; + if (index + l > capacity()) + { + l = capacity() - index; + if (l==0) + return -1; + } + + if (l < 0) + return -1; + + System.arraycopy(_bytes, index, b, offset, l); + return l; + } - public void poke(int index, byte b) - { - /* - if (isReadOnly()) - throw new IllegalStateException(__READONLY); - - if (index < 0) - throw new IllegalArgumentException("index<0: " + index + "<0"); - if (index > capacity()) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - */ - _bytes[index] = b; - } - - @Override - public int poke(int index, Buffer src) - { - _hash=0; - - /* - if (isReadOnly()) - throw new IllegalStateException(__READONLY); - if (index < 0) - throw new IllegalArgumentException("index<0: " + index + "<0"); - */ - - int length=src.length(); - if (index + length > capacity()) - { - length=capacity()-index; - /* - if (length<0) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - */ - } - - byte[] src_array = src.array(); - if (src_array != null) - System.arraycopy(src_array, src.getIndex(), _bytes, index, length); - else - { - int s=src.getIndex(); - for (int i=0;i<length;i++) - _bytes[index++]=src.peek(s++); - } - - return length; - } - + public void poke(int index, byte b) + { + /* + if (isReadOnly()) + throw new IllegalStateException(__READONLY); + + if (index < 0) + throw new IllegalArgumentException("index<0: " + index + "<0"); + if (index > capacity()) + throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); + */ + _bytes[index] = b; + } + + @Override + public int poke(int index, Buffer src) + { + _hash=0; + + /* + if (isReadOnly()) + throw new IllegalStateException(__READONLY); + if (index < 0) + throw new IllegalArgumentException("index<0: " + index + "<0"); + */ + + int length=src.length(); + if (index + length > capacity()) + { + length=capacity()-index; + /* + if (length<0) + throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); + */ + } + + byte[] src_array = src.array(); + if (src_array != null) + System.arraycopy(src_array, src.getIndex(), _bytes, index, length); + else + { + int s=src.getIndex(); + for (int i=0;i<length;i++) + _bytes[index++]=src.peek(s++); + } + + return length; + } + - @Override - public int poke(int index, byte[] b, int offset, int length) - { - _hash=0; - /* - if (isReadOnly()) - throw new IllegalStateException(__READONLY); - if (index < 0) - throw new IllegalArgumentException("index<0: " + index + "<0"); - */ - - if (index + length > capacity()) - { - length=capacity()-index; - /* if (length<0) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - */ - } - - System.arraycopy(b, offset, _bytes, index, length); - - return length; - } - - /* ------------------------------------------------------------ */ - @Override - public void writeTo(OutputStream out) - throws IOException - { - int len=length(); - if (MAX_WRITE>0 && len>MAX_WRITE) - { - int off=getIndex(); - while(len>0) - { - int c=len>MAX_WRITE?MAX_WRITE:len; - out.write(_bytes,off,c); - off+=c; - len-=c; - } - } - else - out.write(_bytes,getIndex(),len); - if (!isImmutable()) - clear(); - } - - /* ------------------------------------------------------------ */ - @Override - public int readFrom(InputStream in,int max) throws IOException - { - if (max<0||max>space()) - max=space(); - int p = putIndex(); - - int len=0, total=0, available=max; - while (total<max) - { - len=in.read(_bytes,p,available); - if (len<0) - break; - else if (len>0) - { - p += len; - total += len; - available -= len; - setPutIndex(p); - } - if (in.available()<=0) - break; - } - if (len<0 && total==0) - return -1; - return total; - } + @Override + public int poke(int index, byte[] b, int offset, int length) + { + _hash=0; + /* + if (isReadOnly()) + throw new IllegalStateException(__READONLY); + if (index < 0) + throw new IllegalArgumentException("index<0: " + index + "<0"); + */ + + if (index + length > capacity()) + { + length=capacity()-index; + /* if (length<0) + throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); + */ + } + + System.arraycopy(b, offset, _bytes, index, length); + + return length; + } + + @Override + public int readFrom(InputStream in,int max) throws IOException + { + if (max<0||max>space()) + max=space(); + int p = putIndex(); + + int len=0, total=0, available=max; + while (total<max) + { + len=in.read(_bytes,p,available); + if (len<0) + break; + else if (len>0) + { + p += len; + total += len; + available -= len; + setPutIndex(p); + } + if (in.available()<=0) + break; + } + if (len<0 && total==0) + return -1; + return total; + } - /* ------------------------------------------------------------ */ - @Override - public int space() - { - return _bytes.length - _put; - } + /* ------------------------------------------------------------ */ + @Override + public int space() + { + return _bytes.length - _put; + } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public static class CaseInsensitive extends ByteArrayBuffer implements Buffer.CaseInsensitve - { - public CaseInsensitive(String s) - { - super(s); - } - - public CaseInsensitive(byte[] b, int o, int l, int rw) - { - super(b,o,l,rw); - } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + public static class CaseInsensitive extends ByteArrayBuffer implements Buffer.CaseInsensitve + { + public CaseInsensitive(String s) + { + super(s); + } + + public CaseInsensitive(byte[] b, int o, int l, int rw) + { + super(b,o,l,rw); + } - @Override - public boolean equals(Object obj) - { - return obj instanceof Buffer && equalsIgnoreCase((Buffer)obj); - } - - } + @Override + public boolean equals(Object obj) + { + return obj instanceof Buffer && equalsIgnoreCase((Buffer)obj); + } + + } }
--- a/src/org/eclipse/jetty/io/nio/DirectNIOBuffer.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/io/nio/DirectNIOBuffer.java Sun Oct 23 22:23:50 2016 -0600 @@ -35,320 +35,229 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/* ------------------------------------------------------------------------------- */ -/** - * - * - */ -public class DirectNIOBuffer extends AbstractBuffer implements NIOBuffer + +public final class DirectNIOBuffer extends AbstractBuffer implements NIOBuffer { - private static final Logger LOG = LoggerFactory.getLogger(DirectNIOBuffer.class); + private static final Logger LOG = LoggerFactory.getLogger(DirectNIOBuffer.class); + + protected final ByteBuffer _buf; + private ReadableByteChannel _in; + private InputStream _inStream; - protected final ByteBuffer _buf; - private ReadableByteChannel _in; - private InputStream _inStream; - private WritableByteChannel _out; - private OutputStream _outStream; + public DirectNIOBuffer(int size) + { + super(READWRITE,NON_VOLATILE); + _buf = ByteBuffer.allocateDirect(size); + _buf.position(0); + _buf.limit(_buf.capacity()); + } + - public DirectNIOBuffer(int size) - { - super(READWRITE,NON_VOLATILE); - _buf = ByteBuffer.allocateDirect(size); - _buf.position(0); - _buf.limit(_buf.capacity()); - } - - public DirectNIOBuffer(ByteBuffer buffer,boolean immutable) - { - super(immutable?IMMUTABLE:READWRITE,NON_VOLATILE); - if (!buffer.isDirect()) - throw new IllegalArgumentException(); - _buf = buffer; - setGetIndex(buffer.position()); - setPutIndex(buffer.limit()); - } + @Override + public boolean isDirect() + { + return true; + } - /** - * @param file - */ - public DirectNIOBuffer(File file) throws IOException - { - super(READONLY,NON_VOLATILE); - FileInputStream fis = null; - FileChannel fc = null; - try - { - fis = new FileInputStream(file); - fc = fis.getChannel(); - _buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - setGetIndex(0); - setPutIndex((int)file.length()); - _access=IMMUTABLE; - } - finally - { - if (fc != null) try {fc.close();} catch (IOException e){LOG.trace("",e);} - IO.close(fis); - } - } + @Override + public byte[] array() + { + return null; + } + + @Override + public int capacity() + { + return _buf.capacity(); + } - /* ------------------------------------------------------------ */ - public boolean isDirect() - { - return true; - } - - /* ------------------------------------------------------------ */ - public byte[] array() - { - return null; - } - - /* ------------------------------------------------------------ */ - public int capacity() - { - return _buf.capacity(); - } - - /* ------------------------------------------------------------ */ - public byte peek(int position) - { - return _buf.get(position); - } + @Override + public byte peek(int position) + { + return _buf.get(position); + } - public int peek(int index, byte[] b, int offset, int length) - { - int l = length; - if (index+l > capacity()) - { - l=capacity()-index; - if (l==0) - return -1; - } - - if (l < 0) - return -1; - try - { - _buf.position(index); - _buf.get(b,offset,l); - } - finally - { - _buf.position(0); - } - - return l; - } + @Override + public int peek(int index, byte[] b, int offset, int length) + { + int l = length; + if (index+l > capacity()) + { + l=capacity()-index; + if (l==0) + return -1; + } + + if (l < 0) + return -1; + try + { + _buf.position(index); + _buf.get(b,offset,l); + } + finally + { + _buf.position(0); + } + + return l; + } - public void poke(int index, byte b) - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); - if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0"); - if (index > capacity()) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - _buf.put(index,b); - } + @Override + public void poke(int index, byte b) + { + if (isReadOnly()) throw new IllegalStateException(__READONLY); + if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0"); + if (index > capacity()) + throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); + _buf.put(index,b); + } - @Override - public int poke(int index, Buffer src) - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); + @Override + public int poke(int index, Buffer src) + { + if (isReadOnly()) throw new IllegalStateException(__READONLY); - byte[] array=src.array(); - if (array!=null) - { - return poke(index,array,src.getIndex(),src.length()); - } - else - { - Buffer src_buf=src.buffer(); - if (src_buf instanceof DirectNIOBuffer) - { - ByteBuffer src_bytebuf = ((DirectNIOBuffer)src_buf)._buf; - if (src_bytebuf==_buf) - src_bytebuf=_buf.duplicate(); - try - { - _buf.position(index); - int space = _buf.remaining(); - - int length=src.length(); - if (length>space) - length=space; - - src_bytebuf.position(src.getIndex()); - src_bytebuf.limit(src.getIndex()+length); - - _buf.put(src_bytebuf); - return length; - } - finally - { - _buf.position(0); - src_bytebuf.limit(src_bytebuf.capacity()); - src_bytebuf.position(0); - } - } - else - return super.poke(index,src); - } - } - - @Override - public int poke(int index, byte[] b, int offset, int length) - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); + byte[] array=src.array(); + if (array!=null) + { + return poke(index,array,src.getIndex(),src.length()); + } + else + { + Buffer src_buf=src.buffer(); + if (src_buf instanceof DirectNIOBuffer) + { + ByteBuffer src_bytebuf = ((DirectNIOBuffer)src_buf)._buf; + if (src_bytebuf==_buf) + src_bytebuf=_buf.duplicate(); + try + { + _buf.position(index); + int space = _buf.remaining(); + + int length=src.length(); + if (length>space) + length=space; + + src_bytebuf.position(src.getIndex()); + src_bytebuf.limit(src.getIndex()+length); + + _buf.put(src_bytebuf); + return length; + } + finally + { + _buf.position(0); + src_bytebuf.limit(src_bytebuf.capacity()); + src_bytebuf.position(0); + } + } + else + return super.poke(index,src); + } + } + + @Override + public int poke(int index, byte[] b, int offset, int length) + { + if (isReadOnly()) throw new IllegalStateException(__READONLY); - if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0"); - - if (index + length > capacity()) - { - length=capacity()-index; - if (length<0) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - } + if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0"); - try - { - _buf.position(index); - - int space=_buf.remaining(); - - if (length>space) - length=space; - if (length>0) - _buf.put(b,offset,length); - return length; - } - finally - { - _buf.position(0); - } - } - - /* ------------------------------------------------------------ */ - public ByteBuffer getByteBuffer() - { - return _buf; - } - - /* ------------------------------------------------------------ */ - @Override - public int readFrom(InputStream in, int max) throws IOException - { - if (_in==null || !_in.isOpen() || in!=_inStream) - { - _in=Channels.newChannel(in); - _inStream=in; - } + if (index + length > capacity()) + { + length=capacity()-index; + if (length<0) + throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); + } - if (max<0 || max>space()) - max=space(); - int p = putIndex(); - - try - { - int len=0, total=0, available=max; - int loop=0; - while (total<max) - { - _buf.position(p); - _buf.limit(p+available); - len=_in.read(_buf); - if (len<0) - { - _in=null; - _inStream=in; - break; - } - else if (len>0) - { - p += len; - total += len; - available -= len; - setPutIndex(p); - loop=0; - } - else if (loop++>1) - break; - if (in.available()<=0) - break; - } - if (len<0 && total==0) - return -1; - return total; - - } - catch(IOException e) - { - _in=null; - _inStream=in; - throw e; - } - finally - { - if (_in!=null && !_in.isOpen()) - { - _in=null; - _inStream=in; - } - _buf.position(0); - _buf.limit(_buf.capacity()); - } - } + try + { + _buf.position(index); + + int space=_buf.remaining(); + + if (length>space) + length=space; + if (length>0) + _buf.put(b,offset,length); + return length; + } + finally + { + _buf.position(0); + } + } + + @Override + public ByteBuffer getByteBuffer() + { + return _buf; + } + + @Override + public int readFrom(InputStream in, int max) throws IOException + { + if (_in==null || !_in.isOpen() || in!=_inStream) + { + _in = Channels.newChannel(in); + _inStream = in; + } - /* ------------------------------------------------------------ */ - @Override - public void writeTo(OutputStream out) throws IOException - { - if (_out==null || !_out.isOpen() || out!=_outStream) - { - _out=Channels.newChannel(out); - _outStream=out; - } + if (max<0 || max>space()) + max=space(); + int p = putIndex(); + + try + { + int len=0, total=0, available=max; + int loop=0; + while (total<max) + { + _buf.position(p); + _buf.limit(p+available); + len = _in.read(_buf); + if (len<0) + { + _in = null; + _inStream = in; + break; + } + else if (len>0) + { + p += len; + total += len; + available -= len; + setPutIndex(p); + loop=0; + } + else if (loop++>1) + break; + if (in.available()<=0) + break; + } + if (len<0 && total==0) + return -1; + return total; + + } + catch(IOException e) + { + _in = null; + _inStream = in; + throw e; + } + finally + { + if (_in!=null && !_in.isOpen()) + { + _in = null; + _inStream = in; + } + _buf.position(0); + _buf.limit(_buf.capacity()); + } + } - synchronized (_buf) - { - try - { - int loop=0; - while(hasContent() && _out.isOpen()) - { - _buf.position(getIndex()); - _buf.limit(putIndex()); - int len=_out.write(_buf); - if (len<0) - break; - else if (len>0) - { - skip(len); - loop=0; - } - else if (loop++>1) - break; - } - - } - catch(IOException e) - { - _out=null; - _outStream=null; - throw e; - } - finally - { - if (_out!=null && !_out.isOpen()) - { - _out=null; - _outStream=null; - } - _buf.position(0); - _buf.limit(_buf.capacity()); - } - } - } - - - }
--- a/src/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java Sun Oct 23 22:23:50 2016 -0600 @@ -22,41 +22,28 @@ import org.eclipse.jetty.io.ByteArrayBuffer; -public class IndirectNIOBuffer extends ByteArrayBuffer implements NIOBuffer + +public final class IndirectNIOBuffer extends ByteArrayBuffer implements NIOBuffer { - protected final ByteBuffer _buf; + private final ByteBuffer _buf; - /* ------------------------------------------------------------ */ - public IndirectNIOBuffer(int size) - { - super(size,READWRITE,NON_VOLATILE); - _buf = ByteBuffer.wrap(_bytes); - _buf.position(0); - _buf.limit(_buf.capacity()); - } + public IndirectNIOBuffer(int size) + { + super(size,READWRITE,NON_VOLATILE); + _buf = ByteBuffer.wrap(_bytes); + _buf.position(0); + _buf.limit(_buf.capacity()); + } - /* ------------------------------------------------------------ */ - public IndirectNIOBuffer(ByteBuffer buffer,boolean immutable) - { - super(buffer.array(),0,0, immutable?IMMUTABLE:READWRITE,NON_VOLATILE); - if (buffer.isDirect()) - throw new IllegalArgumentException(); - _buf = buffer; - _get=buffer.position(); - _put=buffer.limit(); - buffer.position(0); - buffer.limit(buffer.capacity()); - } - - /* ------------------------------------------------------------ */ - public ByteBuffer getByteBuffer() - { - return _buf; - } + @Override + public ByteBuffer getByteBuffer() + { + return _buf; + } - /* ------------------------------------------------------------ */ - public boolean isDirect() - { - return false; - } + @Override + public boolean isDirect() + { + return false; + } }
--- a/src/org/eclipse/jetty/io/nio/NIOBuffer.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/io/nio/NIOBuffer.java Sun Oct 23 22:23:50 2016 -0600 @@ -22,16 +22,10 @@ import org.eclipse.jetty.io.Buffer; -/* ------------------------------------------------------------------------------- */ -/** - * - * - */ + public interface NIOBuffer extends Buffer { - /* ------------------------------------------------------------ */ - public ByteBuffer getByteBuffer(); + public ByteBuffer getByteBuffer(); - /* ------------------------------------------------------------ */ - public boolean isDirect(); + public boolean isDirect(); }
--- a/src/org/eclipse/jetty/server/AbstractHttpConnection.java Sun Oct 23 21:28:56 2016 -0600 +++ b/src/org/eclipse/jetty/server/AbstractHttpConnection.java Sun Oct 23 22:23:50 2016 -0600 @@ -817,62 +817,37 @@ writer.print(s); } - public void sendContent(Object content) throws IOException + public final void sendContent(InputStream in) throws IOException { - Resource resource=null; - if (_closed) throw new IOException("Closed"); if (_generator.isWritten()) throw new IllegalStateException("!empty"); - if (content instanceof Resource) + try { - resource=(Resource)content; - _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified()); - content=resource.getInputStream(); - } - - // Process content. - if (content instanceof Buffer) - { - _generator.addContent((Buffer) content, HttpGenerator.LAST); - commitResponse(HttpGenerator.LAST); - } - else if (content instanceof InputStream) - { - InputStream in = (InputStream)content; + int max = _generator.prepareUncheckedAddContent(); + Buffer buffer = _generator.getUncheckedBuffer(); - try - { - int max = _generator.prepareUncheckedAddContent(); - Buffer buffer = _generator.getUncheckedBuffer(); - - int len=buffer.readFrom(in,max); + int len = buffer.readFrom(in,max); - while (len>=0) - { - _generator.completeUncheckedAddContent(); - _out.flush(); - - max = _generator.prepareUncheckedAddContent(); - buffer = _generator.getUncheckedBuffer(); - len=buffer.readFrom(in,max); - } + while (len>=0) + { _generator.completeUncheckedAddContent(); _out.flush(); + + max = _generator.prepareUncheckedAddContent(); + buffer = _generator.getUncheckedBuffer(); + len=buffer.readFrom(in,max); } - finally - { - if (resource!=null) - resource.release(); - else - in.close(); - } + _generator.completeUncheckedAddContent(); + _out.flush(); } - else - throw new IllegalArgumentException("unknown content type?"); + finally + { + in.close(); + } } }