package org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific;
import java.nio.ByteBuffer;
import org.jscsi.target.scsi.sense.SenseData;
import org.jscsi.target.scsi.sense.SenseKey;
import org.jscsi.target.scsi.sense.senseDataDescriptor.CommandSpecificSenseDataDescriptor;
import org.jscsi.target.util.BitManip;
import org.jscsi.target.util.ReadWrite;
/**
* Segment pointer sense-key-specific data is to be used, when the sense key of
* the enclosing {@link SenseData} has the value {@link SenseKey#COPY_ABORTED}.
*
* @author Andreas Ergenzinger
*/
public class SegmentPointerSenseKeySpecificData extends SenseKeySpecificData {
/**
* The segment descriptor (SD) bit indicates whether the field pointer is
* relative to the start of the parameter list or to the start of a segment
* descriptor. An SD bit set to zero indicates that the field pointer is
* relative to the start of the parameter list. An SD bit set to one
* indicates that the field pointer is relative to the start of the segment
* descriptor indicated by the third and fourth bytes of the
* {@link CommandSpecificSenseDataDescriptor#commandSpecificInformation} field.
*/
private final boolean segmentDescriptor;
/**
* A bit pointer valid (BPV) bit set to zero indicates that the value in the {@link #bitPointer} field is
* not valid. A BPV bit set to one indicates
* that the {@link #bitPointer} field specifies which bit of the byte
* designated by the {@link #fieldPointer} field is in error. When a
* multiple-bit field is in error, the {@link #bitPointerValid} field shall
* point to the most-significant (i.e., left-most) bit of the field.
*/
private final boolean bitPointerValid;
/**
* The FIELD POINTER field indicates which byte of the parameter list or
* segment descriptor was in error.
*
* @see #bitPointerValid
*/
private final short fieldPointer;
/**
* Points to the leftmost bit of the field in error.
*
* @see #bitPointerValid
*/
private final int bitPointer;
/**
* The constructor.
* <p>
* All parameters are used to initialize the member variables with the same name.
*
* @param senseKeySpecificDataValid
* @param segmentDescriptor
* @param bitPointerValid
* @param bitPointer
* @param fieldPointer
*/
public SegmentPointerSenseKeySpecificData(final boolean senseKeySpecificDataValid,
final boolean segmentDescriptor, final boolean bitPointerValid, final int bitPointer,
final int fieldPointer) {
super(senseKeySpecificDataValid);
this.segmentDescriptor = segmentDescriptor;
this.bitPointerValid = bitPointerValid;
this.bitPointer = bitPointer;
this.fieldPointer = (short)fieldPointer;
}
@Override
protected void serializeSpecificFields(final ByteBuffer byteBuffer, final int index) {
byte b = byteBuffer.get(index);// SKSV bit has already been set and has
// to be preserved
// segment descriptor
b = BitManip.getByteWithBitSet(b, 5, segmentDescriptor);
// bit pointer valid
b = BitManip.getByteWithBitSet(b, 3, bitPointerValid);
// bit pointer
b &= (bitPointer & 7);
// store first byte
byteBuffer.put(index, b);
// field pointer
ReadWrite.writeTwoByteInt(byteBuffer, fieldPointer, byteBuffer.position());
}
}