View Javadoc

1   package org.jscsi.target.scsi.cdb;
2   
3   
4   import java.nio.ByteBuffer;
5   
6   import org.jscsi.target.storage.IStorageModule;
7   
8   
9   /**
10   * This abstract class represents Command Descriptor Blocks for the <code>READ</code> and <code>WRITE</code> SCSI
11   * commands. This grouping makes sense, since, apart from the different values of the OPERATION CODE field, Read and
12   * Write CDBs are identical.
13   * 
14   * @author Andreas Ergenzinger
15   */
16  public abstract class ReadOrWriteCdb extends CommandDescriptorBlock {
17  
18      /**
19       * The logical block address of the first logical block of data, where data shall be read from or written to.
20       * 
21       * @see #transferLength
22       */
23      private final long logicalBlockAddress;
24  
25      /**
26       * The TRANSFER LENGTH field specifies the number of contiguous logical blocks of data that shall be read/written
27       * and transferred to/from the (initiator's) data-in buffer, starting with the logical block specified by the
28       * {@link #logicalBlockAddress} field.
29       */
30      private final int transferLength;
31  
32      public ReadOrWriteCdb (ByteBuffer buffer) {
33          super(buffer);
34          logicalBlockAddress = deserializeLogicalBlockAddress(buffer);
35          transferLength = deserializeTransferLength(buffer);
36      }
37  
38      /**
39       * Deserializes the value of the {@link #logicalBlockAddress} field.
40       * 
41       * @param buffer the {@link ByteBuffer} containing the CDB
42       * @return value of the {@link #logicalBlockAddress} field
43       */
44      protected abstract long deserializeLogicalBlockAddress (final ByteBuffer buffer);
45  
46      /**
47       * Deserializes the value of the {@link #transferLength} field.
48       * 
49       * @param buffer the {@link ByteBuffer} containing the CDB
50       * @return value of the {@link #transferLength} field
51       */
52      protected abstract int deserializeTransferLength (final ByteBuffer buffer);
53  
54      /**
55       * Returns the value of {@link #logicalBlockAddress}.
56       * 
57       * @return the value of {@link #logicalBlockAddress}
58       */
59      public final long getLogicalBlockAddress () {
60          return logicalBlockAddress;
61      }
62  
63      /**
64       * Returns the value of {@link #transferLength}.
65       * 
66       * @return the value of {@link #transferLength}
67       */
68      public final int getTransferLength () {
69          return transferLength;
70      }
71  
72      /**
73       * Returns the index position of the first byte used for encoding the {@link #logicalBlockAddress} field.
74       * 
75       * @return the index position of the first byte used for encoding the {@link #logicalBlockAddress} field
76       */
77      protected abstract int getLogicalBlockAddressFieldIndex ();
78  
79      /**
80       * Returns the index position of the first byte used for encoding the {@link #transferLength} field.
81       * 
82       * @return the index position of the first byte used for encoding the {@link #transferLength} field
83       */
84      protected abstract int getTransferLengthFieldIndex ();
85  
86      /**
87       * This method is used for signaling an illegal value of the {@link #logicalBlockAddress} variable.
88       * <p>
89       * This method must be called if the {@link #logicalBlockAddress} lies outside the bounds of the used medium.
90       * 
91       * @see #getIllegalFieldPointers()
92       * @see IStorageModule#checkBounds(long, int)
93       */
94      public final void addIllegalFieldPointerForLogicalBlockAddress () {
95          addIllegalFieldPointer(getLogicalBlockAddressFieldIndex());
96      }
97  
98      /**
99       * This method is used for signaling an illegal value of the {@link #transferLength} variable.
100      * <p>
101      * This method must be called if the {@link #transferLength} field value would result in accessing of out-of-bounds
102      * blocks of the storage medium.
103      * 
104      * @see #getIllegalFieldPointers()
105      * @see IStorageModule#checkBounds(long, int)
106      */
107     public final void addIllegalFieldPointerForTransferLength () {
108         addIllegalFieldPointer(getTransferLengthFieldIndex());
109     }
110 }