package org.jscsi.target.scsi.inquiry; import java.nio.ByteBuffer; /** * The null-terminated, null-padded (see 4.4.2) SCSI NAME STRING field contains * a UTF-8 format string. The number of bytes in the SCSI NAME STRING field * (i.e., the value in the IDENTIFIER LENGTH field) shall be no larger than 256 * and shall be a multiple of four. * * @author Andreas Ergenzinger */ public class ScsiNameStringIdentifier extends Identifier { /** * The maximum {@link #size()} of this {@link Identifier}. */ private static final int MAX_SIZE = 256; /** * The identifying string. */ private final String nameString; /** * The logical unit name extension is a UTF-8 string containing no more than * 16 hexadecimal digits. The logical unit name extension is assigned by the * SCSI target device vendor and shall be assigned so the logical unit name * is worldwide unique. * <p> * This Logical Unit Name Extension has been randomly generated.<br> * (0x493f51ba986f9800 = 5278027150164727808) */ private static final String logicalUnitNameExtension = "493f51ba986f9800"; public ScsiNameStringIdentifier(String targetName) { /* * The SCSI NAME STRING field starts with either:<br> ...<br> c) The * four UTF-8 characters "iqn." concatenated with an iSCSI Name for an * iSCSI-name based identifier (see iSCSI). * * If the ASSOCIATION field is set to 00b (i.e., logical unit) and the * SCSI NAME STRING field starts with the four UTF-8 characters "iqn.", * the SCSI NAME STRING field ends with the five UTF-8 characters * ",L,0x" concatenated with 16 hexadecimal digits for the logical unit * name extension. */ nameString = targetName + ",L,0x" + logicalUnitNameExtension; } public void serialize(ByteBuffer byteBuffer, int index) { byteBuffer.position(index); final int size = size();// this many bytes will be written int stringLength = Math.min(nameString.length(), MAX_SIZE); if (stringLength == MAX_SIZE) --stringLength;// at least one null character as padding // copy string characters for (int i = 0; i < stringLength; ++i) byteBuffer.put((byte)nameString.charAt(i)); // add padding for (int i = 0; i < size - stringLength; ++i) byteBuffer.put((byte)0); } public int size() { return Math.min(nameString.length() + getNullTerminatedPaddingLength(), MAX_SIZE); } /** * Returns the number of null-character padding bytes that have to be * appended to the {@link #nameString} when used in serialized form. * * @return the required number of null-character padding bytes */ private int getNullTerminatedPaddingLength() { return 4 - (nameString.length() % 4); } }