DataBlock.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
* tags. See the COPYRIGHT.txt in the distribution for a full listing of
* individual contributors.
*
* All Waarp Project 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 3 of the License, or (at your
* option) any later version.
*
* Waarp 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
* Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.common.file;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.waarp.common.utility.WaarpNettyUtil;
/**
* Main object implementing Data Block whaveter the mode, type, structure used.
*/
public class DataBlock {
private static final int EOR = 128;
private static final int EOF = 64;
private static final int ERROR = 32;
private static final int RESTART = 16;
/**
* Descriptor
*/
private int descriptor;
/**
* Byte Count
*/
private int byteCount = -1;
/**
* Markers
*/
private int[] markers;
/**
* Byte Array
*/
private byte[] block;
private ByteBuf blockBuf;
private int offsetBuf;
/**
* is EOF
*/
private boolean isEOF;
/**
* is EOR
*/
private boolean isEOR;
/**
* is in ERROR (should not be used)
*/
private boolean isERROR;
/**
* is a MARKER RESTART
*/
private boolean isRESTART;
/**
* Create a simple and empty DataBlock
*/
public DataBlock() {
// Empty
}
/**
* @return the block
*
* @deprecated method, prefer getByteBlock()
*/
@Deprecated
public final ByteBuf getBlock() {
if (blockBuf == null) {
blockBuf = Unpooled.wrappedBuffer(block);
offsetBuf = 0;
}
return blockBuf;
}
/**
* @return the block
*/
public final byte[] getByteBlock() {
return block;
}
/**
* @return the offset of the ByteBlock
*/
public final int getOffset() {
return offsetBuf;
}
/**
* Increase the offset position
*
* @param offset
*/
public final void addOffset(final int offset) {
offsetBuf += offset;
}
/**
* Set the block and the byte count according to the block
*
* @param block the block to set
*/
public final void setBlock(final ByteBuf block) {
if (isRESTART) {
this.block = null;
markers = new int[6];
for (int i = 0; i < 6; i++) {
markers[i] = block.readByte();
}
byteCount = 6;
return;
}
byteCount = block.readableBytes();
this.block = new byte[byteCount];
offsetBuf = 0;
if (blockBuf != null) {
WaarpNettyUtil.release(blockBuf);
blockBuf = null;
}
block.readBytes(this.block);
WaarpNettyUtil.release(block);
}
/**
* Set the block and the byte count according to the block
*
* @param block the block to set
*/
public final void setBlock(final byte[] block) {
setBlock(block, block != null? block.length : 0);
}
/**
* Set the block and the byte count
*
* @param block the block to set
* @param size the real size to set
*/
public final void setBlock(final byte[] block, final int size) {
if (isRESTART) {
this.block = null;
markers = new int[6];
if (block == null) {
for (int i = 0; i < 6; i++) {
markers[i] = 0;
}
} else {
for (int i = 0; i < 6; i++) {
markers[i] = block[i];
}
}
byteCount = 6;
return;
}
this.block = block;
if (this.block == null) {
byteCount = 0;
} else {
byteCount = size;
}
if (blockBuf != null) {
WaarpNettyUtil.release(blockBuf);
blockBuf = null;
}
offsetBuf = 0;
}
/**
* @return the byteCount
*/
public final int getByteCount() {
return byteCount - offsetBuf;
}
/**
* @param byteCount the byteCount to set
*/
public final void setByteCount(final int byteCount) {
this.byteCount = byteCount;
}
/**
* @param upper upper byte of the 2 bytes length
* @param lower lower byte of the 2 bytes length
*/
public final void setByteCount(final byte upper, final byte lower) {
byteCount = upper << 8 | (lower & 0xFF);
}
/**
* @return the Upper byte of the byte count
*/
public final byte getByteCountUpper() {
return (byte) (byteCount >> 8 & 0xFF);
}
/**
* @return the Lower byte of the byte count
*/
public final byte getByteCountLower() {
return (byte) (byteCount & 0xFF);
}
/**
* @return the descriptor
*/
public final byte getDescriptor() {
return (byte) (descriptor & 0xFF);
}
/**
* @param descriptor the descriptor to set
*/
public final void setDescriptor(final int descriptor) {
this.descriptor = descriptor & 0xFF;
isEOF = (this.descriptor & EOF) != 0;
isEOR = (this.descriptor & EOR) != 0;
isERROR = (this.descriptor & ERROR) != 0;
isRESTART = (this.descriptor & RESTART) != 0;
}
/**
* @return the isEOF
*/
public final boolean isEOF() {
return isEOF;
}
/**
* @param isEOF the isEOF to set
*/
public final void setEOF(final boolean isEOF) {
this.isEOF = isEOF;
descriptor |= EOF;
}
/**
* @return the isEOR
*/
public final boolean isEOR() {
return isEOR;
}
/**
* @param isEOR the isEOR to set
*/
public final void setEOR(final boolean isEOR) {
this.isEOR = isEOR;
descriptor |= EOR;
}
/**
* @return the isERROR
*/
public final boolean isERROR() {
return isERROR;
}
/**
* @param isERROR the isERROR to set
*/
public final void setERROR(final boolean isERROR) {
this.isERROR = isERROR;
descriptor |= ERROR;
}
/**
* @return the isRESTART
*/
public final boolean isRESTART() {
return isRESTART;
}
/**
* @param isRESTART the isRESTART to set
*/
public final void setRESTART(final boolean isRESTART) {
this.isRESTART = isRESTART;
descriptor |= RESTART;
}
/**
* @return the markers
*/
public final int[] getMarkers() {
return markers;
}
/**
* @return the 6 bytes representation of the markers
*/
public final byte[] getByteMarkers() {
final byte[] bmarkers = new byte[6];
if (markers == null) {
for (int i = 0; i < 6; i++) {
bmarkers[i] = 0;
}
} else {
for (int i = 0; i < 6; i++) {
bmarkers[i] = (byte) (markers[i] & 0xFF);
}
}
return bmarkers;
}
/**
* Set the markers and the byte count
*
* @param markers the markers to set
*/
public final void setMarkers(final int[] markers) {
this.markers = markers;
byteCount = 6;
}
/**
* Clear the object
*/
public final void clear() {
if (blockBuf != null) {
WaarpNettyUtil.release(blockBuf);
blockBuf = null;
}
block = null;
byteCount = -1;
descriptor = 0;
isEOF = false;
isEOR = false;
isERROR = false;
isRESTART = false;
markers = null;
}
/**
* Is this Block cleared
*
* @return True if this Block is cleared
*/
public final boolean isCleared() {
return byteCount == -1;
}
@Override
public String toString() {
return "DataBlock Length:" + byteCount + " isEof:" + isEOF + " isEOR:" +
isEOR + " isERROR:" + isERROR + " isRESTART:" + isRESTART;
}
/**
* Translate the given array of byte into a string in binary format
*
* @param bytes
* @param cutted True if each Byte should be 'blank' separated or
* not
*
* @return the string
*/
public static String toBinaryString(final byte[] bytes,
final boolean cutted) {
final StringBuilder buffer = new StringBuilder();
boolean first = true;
for (final byte b : bytes) {
if (cutted) {
if (first) {
first = false;
} else {
buffer.append(' ');
}
}
String bin = Integer.toBinaryString(b & 0xFF);
bin = bin.substring(0, Math.min(bin.length(), 8));
for (int j = 0; j < 8 - bin.length(); j++) {
buffer.append('0');
}
buffer.append(bin);
}
return buffer.toString();
}
}