org.ajax4jsf.io.ByteBuffer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of richfaces-core Show documentation
Show all versions of richfaces-core Show documentation
The RichFaces core framework.
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.ajax4jsf.io;
import java.io.UnsupportedEncodingException;
/**
* A single link in chain of byte arrays.
*
* @author glory
*/
public class ByteBuffer {
private static final int MAX_WASTE = 16384;
/**
* Stored bytes
*/
private byte[] bytes;
/**
* Length of byte array.
*/
private int cacheSize;
private ByteBuffer next;
private ByteBuffer prev;
/**
* Number of bytes stored in the array.
*/
private int usedSize;
/**
* Creates instance of ByteBuffer already filled by bytes.
*
* @param bytes
*/
public ByteBuffer(byte[] bytes) {
this.bytes = bytes;
usedSize = bytes.length;
cacheSize = usedSize;
}
/**
* Creates instance of ByteBuffer with byte array of required length.
*
* @param cacheSize length of byte array
*/
public ByteBuffer(int cacheSize) {
bytes = new byte[cacheSize];
this.cacheSize = cacheSize;
usedSize = 0;
}
/**
* Appends byte to array if there are unfilled positions in it. Otherwize creates next link in the chain, and appends the
* byte to it.
*
* @param c
* @return instance of ByteBuffer to which byte was appended.
*/
public ByteBuffer append(byte c) {
if (next != null) {
return next.append(c);
}
if (usedSize < cacheSize) {
bytes[usedSize] = c;
usedSize++;
return this;
} else {
next = new ByteBuffer(cacheSize * 2);
next.prev = this;
return next.append(c);
}
}
/**
* Appends segment of a byte array to array if there are unfilled positions in it. Otherwize creates next link in the chain,
* and appends data to it.
*
* @param bs
* @param off
* @param len
* @return instance of ByteBuffer to which byte array was appended.
*/
public ByteBuffer append(byte[] bs, int off, int len) {
if (next != null) {
return next.append(bs, off, len);
}
if (len + usedSize <= cacheSize) {
System.arraycopy(bs, off, bytes, usedSize, len);
usedSize += len;
return this;
}
int av = cacheSize - usedSize;
if (av > 0) {
System.arraycopy(bs, off, bytes, usedSize, av);
usedSize += av;
off += av;
len -= av;
}
next = new ByteBuffer(cacheSize * 2);
next.prev = this;
return next.append(bs, off, len);
}
/**
* Returns stored byte array.
*
* @return stored byte array
*/
public byte[] getBytes() {
return bytes;
}
/**
* Returns byte at index. No check is fulfilled to provide high speed.
*
* @param index
* @return byte at index
*/
public byte getByteAt(int index) {
return bytes[index];
}
/**
* Returns actual number of byte stored in this link.
*
* @return actual number of byte stored in this link
*/
public int getUsedSize() {
return usedSize;
}
/**
* Returns capacity of this link.
*
* @return capacity of this link
*/
public int getCacheSize() {
return cacheSize;
}
/**
* Returns total number of bytes stored in this link and all its predecessors.
*
* @return total number of bytes stored in this link and all its predecessors
*/
public int getTotalSize() {
return (prev == null) ? usedSize : prev.getTotalSize() + usedSize;
}
/**
* Returns the previous link in the chain.
*
* @return the previous link in the chain
*/
public ByteBuffer getPrevious() {
return prev;
}
/**
* Returns the next link in the chain.
*
* @return the next link in the chain
*/
public ByteBuffer getNext() {
return next;
}
/**
* Sets the next link in the chain.
*
* @param b
*/
public void setNext(ByteBuffer b) {
next = b;
if (b != null) {
b.prev = this;
}
}
/**
* Transforms this instance to instance of CharBuffer (a link of chain of char arrays).
*
* @param encoding
* @return link of chain of char arrays
* @throws UnsupportedEncodingException
*/
public CharBuffer toCharBuffer(String encoding) throws UnsupportedEncodingException {
String s;
if (null != encoding) {
s = new String(bytes, 0, usedSize, encoding);
} else {
s = new String(bytes, 0, usedSize);
}
return new CharBuffer(s.toCharArray());
}
/**
* Transforms this instance to instance of CharBuffer (a link of chain of char arrays).
*
* @return link of chain of char arrays
*/
public CharBuffer toCharBuffer() {
String s = new String(bytes, 0, usedSize);
return new CharBuffer(s.toCharArray());
}
/**
* Resets this byte buffer to empty state
*
* @since 3.3.0
*/
public void reset() {
usedSize = 0;
next = null;
prev = null;
}
/**
* @since 4.0
*/
public void compact() {
if (bytes.length - usedSize > MAX_WASTE) {
byte[] bs = new byte[usedSize];
System.arraycopy(bytes, 0, bs, 0, usedSize);
this.bytes = bs;
this.cacheSize = bs.length;
}
if (next != null) {
next.compact();
}
}
public ByteBuffer getLast() {
ByteBuffer result = this;
while (result.next != null) {
result = result.next;
}
return result;
}
}