/* * Dijjer - A Peer to Peer HTTP Cache * Copyright (C) 2004,2005 Change.Tv, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package freenet.support; import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import freenet.io.WritableToDataOutputStream; /** * Byte array which is limited to 32KiB. */ public class ShortBuffer implements WritableToDataOutputStream { public static final String VERSION = "$Id: ShortBuffer.java,v 1.2 2005/08/25 17:28:19 amphibian Exp $"; private final byte[] _data; private final int _start; private final short _length; /** * Create a Buffer by reading a DataInputStream * * @param dis to read bytes from * @throws IllegalArgumentException If the length integer is negative. * @throws IOException error reading from dis */ public ShortBuffer(DataInput dis) throws IOException { _length = dis.readShort(); if(_length < 0) throw new IllegalArgumentException("Negative Length: "+_length); _data = new byte[_length]; _start = 0; dis.readFully(_data); } /** * Create an empty Buffer */ public ShortBuffer() { _data = new byte[0]; _start = 0; _length = 0; } /** * Create a Buffer from a byte array * * @param data */ public ShortBuffer(byte[] data) { if(data.length > Short.MAX_VALUE) throw new IllegalArgumentException("Too big: "+data.length); _start = 0; _length = (short)data.length; _data = data; } public ShortBuffer(byte[] data, int start, int length) { if(length > Short.MAX_VALUE || length < 0 || start < 0 || start + length > data.length) throw new IllegalArgumentException("Invalid Length: start=" + start + ", length=" + length); _start = start; _data = data; _length = (short)length; } /** * Retrieve a byte array containing the data in this buffer. * May be copied, so don't rely on it being the internal * buffer. * * @return The byte array */ public byte[] getData() { if ((_start == 0) && (_length == _data.length)) { return _data; } else { return Arrays.copyOfRange(_data, _start, _start+_length); } } /** * Copy the data to a byte array * * @param array * @param position */ public void copyTo(byte[] array, int position) { System.arraycopy(_data, _start, array, position, _length); } public byte byteAt(int pos) { if (pos >= _length) { throw new ArrayIndexOutOfBoundsException(); } return _data[pos + _start]; } @Override public void writeToDataOutputStream(DataOutputStream stream) throws IOException { stream.writeShort(_length); stream.write(_data, _start, _length); } @Override public String toString() { if (this._length > 50) { return "Buffer {"+this._length+ '}'; } else { StringBuilder b = new StringBuilder(this._length*3); b.append('{').append(this._length).append(':'); for (int x=0; x<this._length; x++) { b.append(byteAt(x)); b.append(' '); } return b.toString(); } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof ShortBuffer)) { return false; } final ShortBuffer buffer = (ShortBuffer) o; if (_length != buffer._length) { return false; } if (_start != buffer._start) { return false; } if (!Arrays.equals(_data, buffer._data)) { return false; } return true; } @Override public int hashCode() { return Fields.hashCode(_data) ^ _start ^ (_length << 16); } public int getLength() { return _length; } }