Mercurial Hosting > luan
diff src/org/eclipse/jetty/io/AbstractBuffer.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children | 8e9db0bbf4f9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/eclipse/jetty/io/AbstractBuffer.java Wed Sep 07 21:15:48 2016 -0600 @@ -0,0 +1,728 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.io; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; + +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +/** + * + * + */ +public abstract class AbstractBuffer implements Buffer +{ + private static final Logger LOG = Log.getLogger(AbstractBuffer.class); + + private final static boolean __boundsChecking = Boolean.getBoolean("org.eclipse.jetty.io.AbstractBuffer.boundsChecking"); + + protected final static String + __IMMUTABLE = "IMMUTABLE", + __READONLY = "READONLY", + __READWRITE = "READWRITE", + __VOLATILE = "VOLATILE"; + + protected int _access; + protected boolean _volatile; + + protected int _get; + protected int _put; + protected int _hash; + protected int _hashGet; + protected int _hashPut; + protected int _mark; + protected String _string; + protected View _view; + + /** + * Constructor for BufferView + * + * @param access 0==IMMUTABLE, 1==READONLY, 2==READWRITE + */ + public AbstractBuffer(int access, boolean isVolatile) + { + if (access == IMMUTABLE && isVolatile) + throw new IllegalArgumentException("IMMUTABLE && VOLATILE"); + setMarkIndex(-1); + _access = access; + _volatile = isVolatile; + } + + /* + * @see org.eclipse.io.Buffer#toArray() + */ + public byte[] asArray() + { + byte[] bytes = new byte[length()]; + byte[] array = array(); + if (array != null) + System.arraycopy(array, getIndex(), bytes, 0, bytes.length); + else + peek(getIndex(), bytes, 0, length()); + return bytes; + } + + public ByteArrayBuffer duplicate(int access) + { + Buffer b=this.buffer(); + if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve) + return new ByteArrayBuffer.CaseInsensitive(asArray(), 0, length(),access); + else + 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; + return duplicate(IMMUTABLE); + } + + /* + * @see org.eclipse.util.Buffer#asReadOnlyBuffer() + */ + public Buffer asReadOnlyBuffer() + { + if (isReadOnly()) return this; + 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; + } + + public void clear() + { + setMarkIndex(-1); + setGetIndex(0); + setPutIndex(0); + } + + public void compact() + { + if (isReadOnly()) throw new IllegalStateException(__READONLY); + int s = markIndex() >= 0 ? markIndex() : getIndex(); + if (s > 0) + { + byte array[] = array(); + int length = putIndex() - s; + if (length > 0) + { + if (array != null) + System.arraycopy(array(), s, array(), 0, length); + else + poke(0, peek(s, length)); + } + if (markIndex() > 0) setMarkIndex(markIndex() - s); + setGetIndex(getIndex() - s); + setPutIndex(putIndex() - s); + } + } + + @Override + public boolean equals(Object obj) + { + if (obj==this) + return true; + + // reject non buffers; + if (obj == null || !(obj instanceof Buffer)) return false; + Buffer b = (Buffer) obj; + + if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve) + return equalsIgnoreCase(b); + + // 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; + } + + // Nothing for it but to do the hard grind. + int get=getIndex(); + int bi=b.putIndex(); + for (int i = putIndex(); i-->get;) + { + byte b1 = peek(i); + byte b2 = b.peek(--bi); + if (b1 != b2) return false; + } + return true; + } + + public boolean equalsIgnoreCase(Buffer b) + { + if (b==this) + return true; + + // reject different lengths + if (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; + } + + // Nothing for it but to do the hard grind. + int get=getIndex(); + int bi=b.putIndex(); + + byte[] array = array(); + byte[] barray= b.array(); + if (array!=null && barray!=null) + { + for (int i = putIndex(); i-->get;) + { + byte b1 = array[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; + } + } + } + else + { + for (int i = putIndex(); i-->get;) + { + byte b1 = peek(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; + } + } + } + return true; + } + + public byte get() + { + return peek(_get++); + } + + public int get(byte[] b, int offset, int length) + { + int gi = getIndex(); + int l=length(); + if (l==0) + return -1; + + if (length>l) + length=l; + + length = peek(gi, b, offset, length); + if (length>0) + setGetIndex(gi + length); + return length; + } + + public Buffer get(int length) + { + int gi = getIndex(); + Buffer view = peek(gi, length); + setGetIndex(gi + length); + return view; + } + + public final int getIndex() + { + return _get; + } + + public boolean hasContent() + { + return _put > _get; + } + + @Override + public int hashCode() + { + if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) + { + int get=getIndex(); + byte[] array = array(); + if (array==null) + { + for (int i = putIndex(); i-- >get;) + { + byte b = peek(i); + if ('a' <= b && b <= 'z') + b = (byte) (b - 'a' + 'A'); + _hash = 31 * _hash + b; + } + } + else + { + for (int i = putIndex(); i-- >get;) + { + byte b = array[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 boolean isImmutable() + { + return _access <= IMMUTABLE; + } + + public boolean isReadOnly() + { + return _access <= READONLY; + } + + public boolean isVolatile() + { + return _volatile; + } + + public int length() + { + return _put - _get; + } + + public void mark() + { + setMarkIndex(_get - 1); + } + + public void mark(int offset) + { + setMarkIndex(_get + offset); + } + + public int markIndex() + { + return _mark; + } + + public byte peek() + { + return peek(_get); + } + + public Buffer peek(int index, int length) + { + if (_view == null) + { + _view = new View(this, -1, index, index + length, isReadOnly() ? READONLY : READWRITE); + } + else + { + _view.update(this.buffer()); + _view.setMarkIndex(-1); + _view.setGetIndex(0); + _view.setPutIndex(index + length); + _view.setGetIndex(index); + + } + return _view; + } + + 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(); + byte[] dst_array = array(); + if (src_array != null && dst_array != null) + System.arraycopy(src_array, src.getIndex(), dst_array, index, length); + else if (src_array != null) + { + int s=src.getIndex(); + for (int i=0;i<length;i++) + poke(index++,src_array[s++]); + } + else if (dst_array != null) + { + int s=src.getIndex(); + for (int i=0;i<length;i++) + dst_array[index++]=src.peek(s++); + } + else + { + int s=src.getIndex(); + for (int i=0;i<length;i++) + poke(index++,src.peek(s++)); + } + + return length; + } + + + 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()); + */ + } + + byte[] dst_array = array(); + if (dst_array != null) + System.arraycopy(b, offset, dst_array, index, length); + else + { + int s=offset; + for (int i=0;i<length;i++) + poke(index++,b[s++]); + } + return length; + } + + public int put(Buffer src) + { + int pi = putIndex(); + int l=poke(pi, src); + setPutIndex(pi + l); + return l; + } + + public void put(byte b) + { + int pi = putIndex(); + poke(pi, b); + setPutIndex(pi + 1); + } + + public int put(byte[] b, int offset, int length) + { + int pi = putIndex(); + int l = poke(pi, b, offset, length); + setPutIndex(pi + l); + return l; + } + + public int put(byte[] b) + { + int pi = putIndex(); + int l = poke(pi, b, 0, b.length); + setPutIndex(pi + l); + return l; + } + + public final int putIndex() + { + return _put; + } + + public void reset() + { + if (markIndex() >= 0) setGetIndex(markIndex()); + } + + public void rewind() + { + setGetIndex(0); + setMarkIndex(-1); + } + + public void setGetIndex(int getIndex) + { + /* bounds checking + if (isImmutable()) + throw new IllegalStateException(__IMMUTABLE); + if (getIndex < 0) + throw new IllegalArgumentException("getIndex<0: " + getIndex + "<0"); + if (getIndex > putIndex()) + throw new IllegalArgumentException("getIndex>putIndex: " + getIndex + ">" + putIndex()); + */ + _get = getIndex; + _hash=0; + } + + public void setMarkIndex(int index) + { + /* + if (index>=0 && isImmutable()) + throw new IllegalStateException(__IMMUTABLE); + */ + _mark = index; + } + + public void setPutIndex(int putIndex) + { + /* bounds checking + if (isImmutable()) + throw new IllegalStateException(__IMMUTABLE); + if (putIndex > capacity()) + throw new IllegalArgumentException("putIndex>capacity: " + putIndex + ">" + capacity()); + if (getIndex() > putIndex) + throw new IllegalArgumentException("getIndex>putIndex: " + getIndex() + ">" + putIndex); + */ + _put = putIndex; + _hash=0; + } + + public int skip(int n) + { + if (length() < n) n = length(); + setGetIndex(getIndex() + n); + return n; + } + + public Buffer slice() + { + return peek(getIndex(), length()); + } + + public Buffer sliceFromMark() + { + return sliceFromMark(getIndex() - markIndex() - 1); + } + + public Buffer sliceFromMark(int length) + { + if (markIndex() < 0) return null; + Buffer view = peek(markIndex(), length); + setMarkIndex(-1); + return view; + } + + public int space() + { + return capacity() - _put; + } + + public String toDetailString() + { + StringBuilder buf = new StringBuilder(); + buf.append("["); + buf.append(super.hashCode()); + buf.append(","); + buf.append(this.buffer().hashCode()); + buf.append(",m="); + buf.append(markIndex()); + buf.append(",g="); + buf.append(getIndex()); + buf.append(",p="); + buf.append(putIndex()); + buf.append(",c="); + buf.append(capacity()); + buf.append("]={"); + if (markIndex() >= 0) + { + for (int i = markIndex(); i < getIndex(); i++) + { + byte b = peek(i); + TypeUtil.toHex(b,buf); + } + buf.append("}{"); + } + int count = 0; + for (int i = getIndex(); i < putIndex(); i++) + { + byte b = peek(i); + TypeUtil.toHex(b,buf); + if (count++ == 50) + { + if (putIndex() - i > 20) + { + buf.append(" ... "); + i = putIndex() - 20; + } + } + } + buf.append('}'); + return buf.toString(); + } + + /* ------------------------------------------------------------ */ + @Override + public String toString() + { + if (isImmutable()) + { + if (_string == null) + _string = new String(asArray(), 0, length()); + return _string; + } + return new String(asArray(), 0, length()); + } + + /* ------------------------------------------------------------ */ + public String toString(String charset) + { + try + { + byte[] bytes=array(); + if (bytes!=null) + return new String(bytes,getIndex(),length(),charset); + return new String(asArray(), 0, length(),charset); + + } + catch(Exception e) + { + LOG.warn(e); + return new String(asArray(), 0, length()); + } + } + + /* ------------------------------------------------------------ */ + public String toString(Charset charset) + { + try + { + byte[] bytes=array(); + if (bytes!=null) + return new String(bytes,getIndex(),length(),charset); + return new String(asArray(), 0, length(),charset); + } + catch(Exception e) + { + LOG.warn(e); + return new String(asArray(), 0, length()); + } + } + + /* ------------------------------------------------------------ */ + public String toDebugString() + { + return getClass()+"@"+super.hashCode(); + } + + /* ------------------------------------------------------------ */ + 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(); + int s=space(); + if (s>max) + s=max; + + if (array!=null) + { + int l=in.read(array,_put,s); + if (l>0) + _put+=l; + return l; + } + else + { + byte[] buf=new byte[s>1024?1024:s]; + int total=0; + while (s>0) + { + int l=in.read(buf,0,buf.length); + if (l<0) + return total>0?total:-1; + int p=put(buf,0,l); + assert l==p; + s-=l; + } + return total; + } + } +}