/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP 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
* of the License, or (at your option) any later version.
*
* UJMP 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 UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.core.util.io;
import java.nio.ByteBuffer;
public abstract class AbstractMemoryByteBufferConcatenation extends AbstractByteBufferConcatenation {
protected ByteBuffer[] byteBuffers;
protected long totalLength;
public AbstractMemoryByteBufferConcatenation(final ByteBuffer... byteBuffers) {
if (byteBuffers.length == 0) {
throw new IllegalArgumentException("byteBuffers is empty");
}
for (ByteBuffer bb : byteBuffers) {
if (bb == null) {
throw new IllegalArgumentException("cannot use ByteBuffer which is null");
} else if (bb.capacity() == 0) {
throw new IllegalArgumentException("cannot use ByteBuffer which has no capacity");
}
}
this.byteBuffers = byteBuffers;
long length = 0;
for (int i = 0; i < byteBuffers.length; i++) {
length += byteBuffers[i].capacity();
}
this.totalLength = length;
}
public final long getLength() {
return totalLength;
}
public final void deleteBytes(final long position, final int count) {
synchronized (this) {
final byte[] copyBuffer = new byte[DEFAULTBUFFERSIZE];
for (long pos = position; pos < totalLength; pos += DEFAULTBUFFERSIZE) {
final int length = (int) Math.min(DEFAULTBUFFERSIZE, totalLength - pos - count);
getBytes(copyBuffer, pos + count, length);
setBytes(copyBuffer, pos, length);
}
shrink(count);
}
}
public final String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < byteBuffers.length; i++) {
sb.append(byteBuffers[i].capacity());
sb.append(",");
}
sb.append(" total: ");
sb.append(totalLength);
return sb.toString();
}
public final byte getByte(final long position) {
int byteBufferId = 0;
long offset = position;
while (offset >= byteBuffers[byteBufferId].capacity()) {
offset -= byteBuffers[byteBufferId++].capacity();
}
return byteBuffers[byteBufferId].get((int) offset);
}
public final void setByte(final byte b, final long position) {
int byteBufferId = 0;
long offset = position;
while (offset >= byteBuffers[byteBufferId].capacity()) {
offset -= byteBuffers[byteBufferId++].capacity();
}
byteBuffers[byteBufferId].put((int) offset, b);
}
public final void getBytes(final byte[] bytes, final long position, final int length) {
if (position + length > totalLength) {
throw new IllegalArgumentException("cannot read beyond buffer size");
}
int byteBufferId = 0;
long offset = position;
while (offset >= byteBuffers[byteBufferId].capacity()) {
offset -= byteBuffers[byteBufferId++].capacity();
}
int remaining = length;
int pos = 0;
while (remaining > 0) {
final int byteCount = Math.min((int) (byteBuffers[byteBufferId].capacity() - offset),
remaining);
synchronized (byteBuffers[byteBufferId]) {
byteBuffers[byteBufferId].position((int) offset);
byteBuffers[byteBufferId].get(bytes, pos, byteCount);
}
remaining -= byteCount;
pos += byteCount;
byteBufferId++;
offset = 0;
}
}
public final void setBytes(final byte[] bytes, final long position, final int length) {
synchronized (this) {
int byteBufferId = 0;
long offset = position;
while (offset >= byteBuffers[byteBufferId].capacity()) {
offset -= byteBuffers[byteBufferId++].capacity();
}
int remaining = length;
int pos = 0;
while (remaining > 0) {
final int byteCount = Math.min(
(int) (byteBuffers[byteBufferId].capacity() - offset), remaining);
synchronized (byteBuffers[byteBufferId]) {
byteBuffers[byteBufferId].position((int) offset);
byteBuffers[byteBufferId].put(bytes, pos, byteCount);
}
remaining -= byteCount;
pos += byteCount;
byteBufferId++;
offset = 0;
}
}
}
}
Ads help maintain this website.