| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| ModePage |
|
| 1.1666666666666667;1.167 |
| 1 | package org.jscsi.target.scsi.modeSense; | |
| 2 | ||
| 3 | ||
| 4 | import java.nio.ByteBuffer; | |
| 5 | ||
| 6 | import org.jscsi.target.scsi.ISerializable; | |
| 7 | import org.jscsi.target.util.BitManip; | |
| 8 | ||
| 9 | ||
| 10 | /** | |
| 11 | * MODE PAGEs are sent in response to successful <code>MODE SENSE</code> SCSI commands. There are two different, | |
| 12 | * command-specific formats for MODE PAGEs - the PAGE_0 FORMAT and the SUB-PAGE FORMAT, represented by the non-abstract | |
| 13 | * children of this class, {@link Page_0FormatModePage} and {@link SubPageFormatModePage}, respectively. | |
| 14 | * | |
| 15 | * @author Andreas Ergenzinger | |
| 16 | */ | |
| 17 | public abstract class ModePage implements ISerializable { | |
| 18 | ||
| 19 | /** | |
| 20 | * This value plus {@link #pageLength} equals the length in bytes of a MODE PAGE using the SUB-PAGE FORMAT. | |
| 21 | */ | |
| 22 | private static final int SUB_PAGE_FORMAT_PAGE_LENGTH_MODIFIER = 4; | |
| 23 | ||
| 24 | /** | |
| 25 | * This value plus {@link #pageLength} equals the length in bytes of a MODE PAGE using the PAGE_0 FORMAT. | |
| 26 | */ | |
| 27 | private static final int PAGE_0_FORMAT_PAGE_LENGTH_MODIFIER = 2; | |
| 28 | ||
| 29 | /** | |
| 30 | * When using the MODE SENSE command, a parameters saveable (PS) bit set to one indicates that the mode page may be | |
| 31 | * saved by the logical unit in a nonvolatile, vendor specific location. A PS bit set to zero indicates that the | |
| 32 | * device server is not able to save the supporte parameters. When using the MODE SELECT command, the PS bit is | |
| 33 | * reserved. | |
| 34 | */ | |
| 35 | private final boolean parametersSaveable; | |
| 36 | ||
| 37 | /** | |
| 38 | * A SubPage Format (SPF) bit set to <code>false</code>/zero indicates that the page_0 mode page format is being | |
| 39 | * used. A SPF bit set to <code>true</code>/one indicates that the sub_page mode page format is being used. | |
| 40 | */ | |
| 41 | private final boolean subPageFormat; | |
| 42 | ||
| 43 | /** | |
| 44 | * Specifies what kind of information is contained in the MODE PAGE. | |
| 45 | */ | |
| 46 | private final int pageCode; | |
| 47 | ||
| 48 | /** | |
| 49 | * The number of bytes following the PAGE LENGTH field. | |
| 50 | */ | |
| 51 | protected final int pageLength; | |
| 52 | ||
| 53 | /** | |
| 54 | * This value plus {@link #pageLength} equals the length in bytes of the MODE PAGE. | |
| 55 | */ | |
| 56 | private final int pageLengthModifier; | |
| 57 | ||
| 58 | /** | |
| 59 | * The abstract constructor. | |
| 60 | * | |
| 61 | * @param parametersSaveable value of the PARAMETERS SAVEABLE bit | |
| 62 | * @param subPageFormat <code>true</code> if and only if the SUB-PAGE FORMAT is to be used | |
| 63 | * @param pageCode specifies the kind of information is contained in the MODE PAGE | |
| 64 | * @param pageLength the value of the PAGE LENGTH field | |
| 65 | */ | |
| 66 | 0 | public ModePage (final boolean parametersSaveable, final boolean subPageFormat, final int pageCode, final int pageLength) { |
| 67 | 0 | this.parametersSaveable = parametersSaveable; |
| 68 | 0 | this.subPageFormat = subPageFormat; |
| 69 | 0 | if (subPageFormat) |
| 70 | 0 | pageLengthModifier = SUB_PAGE_FORMAT_PAGE_LENGTH_MODIFIER; |
| 71 | else | |
| 72 | 0 | pageLengthModifier = PAGE_0_FORMAT_PAGE_LENGTH_MODIFIER; |
| 73 | 0 | this.pageCode = pageCode; |
| 74 | 0 | this.pageLength = pageLength; |
| 75 | 0 | } |
| 76 | ||
| 77 | public final void serialize (final ByteBuffer byteBuffer, final int index) { | |
| 78 | // serialize first byte | |
| 79 | // (for convenience reasons from least significant to most significant | |
| 80 | // field) | |
| 81 | 0 | byte b = (byte) pageCode;// PAGE CODE |
| 82 | 0 | b = BitManip.getByteWithBitSet(b, 6, subPageFormat);// SPF |
| 83 | 0 | b = BitManip.getByteWithBitSet(b, 7, parametersSaveable);// PS |
| 84 | 0 | byteBuffer.position(index); |
| 85 | 0 | byteBuffer.put(b); |
| 86 | // serialize remaining fields | |
| 87 | 0 | serializeSubPageCode(byteBuffer, index); |
| 88 | 0 | serializePageLength(byteBuffer, index); |
| 89 | 0 | serializeModeParameters(byteBuffer, index); |
| 90 | 0 | } |
| 91 | ||
| 92 | /** | |
| 93 | * This method serializes the SUBPAGE CODE field, if the mode page format says this field exists (only for the | |
| 94 | * sub_page mode page format). | |
| 95 | * | |
| 96 | * @param buffer where to insert the serialized object representation | |
| 97 | * @param index the position of the first byte of the serialized object in the {@link ByteBuffer} | |
| 98 | */ | |
| 99 | protected abstract void serializeSubPageCode (final ByteBuffer buffer, final int index); | |
| 100 | ||
| 101 | /** | |
| 102 | * Serializes the PAGE LENGTH field. | |
| 103 | * | |
| 104 | * @param buffer where to insert the serialized object representation | |
| 105 | * @param index the position of the first byte of the serialized object in the {@link ByteBuffer} | |
| 106 | */ | |
| 107 | protected abstract void serializePageLength (final ByteBuffer buffer, final int index); | |
| 108 | ||
| 109 | /** | |
| 110 | * @param buffer where to insert the serialized object representation | |
| 111 | * @param index the position of the first byte of the serialized object in the {@link ByteBuffer} | |
| 112 | */ | |
| 113 | protected abstract void serializeModeParameters (final ByteBuffer buffer, final int index); | |
| 114 | ||
| 115 | public final int size () { | |
| 116 | 0 | return pageLength + pageLengthModifier; |
| 117 | } | |
| 118 | } |