package org.apache.hadoop.hdfs;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.Text;
public class DataTransferPacket {
// the length of data and checksum in this packet
public int dataLength;
public long offsetInBlock;
public long sequenceNumber;
private byte booleanFields;
public byte[] buffer;
public String errMessage; //just for debug
public DataTransferPacket(int bufferSize) {
buffer = new byte[bufferSize];
reset();
}
public void readHeader(DataInputStream in) throws IOException {
dataLength = in.readInt();
if (dataLength > 0) {
offsetInBlock = in.readLong();
sequenceNumber = in.readLong();
booleanFields = in.readByte();
}
}
public void read(DataInputStream in) throws IOException {
readHeader(in);
if (dataLength > 0) {
try {
IOUtils.readFully(in, buffer, 0, dataLength);
} catch (ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException("buffer.length = "
+ buffer.length + ", dataLength = "
+ dataLength);
}
} else if (dataLength < 0) {
errMessage = Text.readString(in);
}
}
public void writeHeader(DataOutputStream out) throws IOException {
out.writeInt(dataLength);
if (dataLength > 0) {
out.writeLong(offsetInBlock);
out.writeLong(sequenceNumber);
out.writeByte(booleanFields);
}
}
public void write(DataOutputStream out) throws IOException {
writeHeader(out);
if (dataLength > 0)
out.write(buffer, 0, dataLength);
else if (dataLength < 0)
Text.writeString(out, errMessage);
}
public void reset() {
// TODO Auto-generated method stub
dataLength = 0;
offsetInBlock = 0;
sequenceNumber = 0;
booleanFields = 0x00;
Arrays.fill(buffer, (byte)0);
errMessage = null;
}
private static byte lastPacketInBlockMask = 0x01;
private static byte forceSyncMask = 0x02;
final public boolean isLastPacketInBlock() {
return (((booleanFields & lastPacketInBlockMask) == 0) ? false : true);
}
final public void setLastPacketInBlock(boolean value) {
if(value) {
booleanFields |= lastPacketInBlockMask;
} else {
booleanFields &= (~lastPacketInBlockMask);
}
}
final public boolean isForceSync() {
return (((booleanFields & forceSyncMask) == 0) ? false : true);
}
final public void setForceSync(boolean value) {
if(value) {
booleanFields |= forceSyncMask;
} else {
booleanFields &= (~forceSyncMask);
}
}
@Override
public String toString() {
return "DataTransferPacket dataLength=[" + dataLength
+ "], offsetInBlock=[" + offsetInBlock + "], sequenceNumber=["
+ sequenceNumber + "], booleanFields=[" + booleanFields + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + booleanFields;
result = prime * result + dataLength;
result = prime * result
+ (int) (offsetInBlock ^ (offsetInBlock >>> 32));
result = prime * result
+ (int) (sequenceNumber ^ (sequenceNumber >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DataTransferPacket other = (DataTransferPacket) obj;
if (booleanFields != other.booleanFields)
return false;
if (dataLength != other.dataLength)
return false;
if (offsetInBlock != other.offsetInBlock)
return false;
if (sequenceNumber != other.sequenceNumber)
return false;
return true;
}
}