Mercurial Hosting > luan
view src/org/eclipse/jetty/io/ByteArrayBuffer.java @ 1046:a8c92b0a08ed
add JBuffer
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 07 Nov 2016 22:39:39 -0700 |
parents | dd71a59fcf72 |
children |
line wrap: on
line source
// // ======================================================================== // 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.io.UnsupportedEncodingException; import org.eclipse.jetty.util.StringUtil; 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; protected ByteArrayBuffer(int size, int access) { this(new byte[size],0,0,access); } 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, int access) { super(access); _bytes = bytes; setPutIndex(index + length); setGetIndex(index); } public ByteArrayBuffer(int size) { this(new byte[size], 0, 0, READWRITE); setPutIndex(0); } public ByteArrayBuffer(String value) { super(READONLY); _bytes = StringUtil.getBytes(value); setGetIndex(0); setPutIndex(_bytes.length); } @Override public final byte[] array() { return _bytes; } @Override public final int capacity() { return _bytes.length; } @Override public final void compact() { if (isReadOnly()) throw new IllegalStateException(__READONLY); int s = getIndex(); if (s > 0) { int length = putIndex() - s; if (length > 0) { System.arraycopy(_bytes, s,_bytes, 0, length); } setGetIndex(getIndex() - s); setPutIndex(putIndex() - s); } } @Override public final boolean equals(Object obj) { if (obj==this) return true; if (obj == null || !(obj instanceof Buffer)) return false; Buffer b = (Buffer) obj; // reject different lengths if (b.remaining() != remaining()) 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; } @Override public final byte get() { return _bytes[_get++]; } @Override public final 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; } @Override public final byte peek(int index) { return _bytes[index]; } @Override public final 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 final 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 final 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.remaining(); 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 final 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 final 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 final int space() { return _bytes.length - _put; } }