Coverage Report - org.jscsi.target.util.ReadWrite
 
Classes in this File Line Coverage Branch Coverage Complexity
ReadWrite
0%
0/62
0%
0/10
1.278
 
 1  
 package org.jscsi.target.util;
 2  
 
 3  
 
 4  
 import java.nio.ByteBuffer;
 5  
 
 6  
 
 7  
 /**
 8  
  * This utility class contains static methods for reading/writing integers of various lengths and character strings
 9  
  * from/to {@link ByteBuffer} objects and byte arrays.
 10  
  * 
 11  
  * @author Andreas Ergenzinger
 12  
  */
 13  0
 public final class ReadWrite {
 14  
 
 15  
     /**
 16  
      * Reads a specified byte from a {@link ByteBuffer} and returns its value as an unsigned integer.
 17  
      * 
 18  
      * @param buffer the {@link ByteBuffer} containing the byte
 19  
      * @param start the index position of the byte in the {@link ByteBuffer}
 20  
      * @return the unsigned integer value of the byte
 21  
      */
 22  
     public static final int readOneByteInt (ByteBuffer buffer, int start) {
 23  0
         final byte b = buffer.get(start);
 24  0
         return (b & 255);
 25  
     }
 26  
 
 27  
     /**
 28  
      * Reads a specified byte from a byte array and returns its value as an unsigned integer.
 29  
      * 
 30  
      * @param array the array containing the byte
 31  
      * @param start the index position of the byte in the array
 32  
      * @return the unsigned integer value of the byte
 33  
      */
 34  
     public static final int readOneByteInt (byte[] array, int start) {
 35  0
         return (array[start] & 255);
 36  
     }
 37  
 
 38  
     /**
 39  
      * Reads an unsigned 2-byte integer from two consecutive big-endian-ordered bytes of a {@link ByteBuffer} object and
 40  
      * returns the value.
 41  
      * 
 42  
      * @param buffer the {@link ByteBuffer} containing the bytes
 43  
      * @param start the index position of the most-significant byte
 44  
      * @return the unsigned value of the two-byte integer
 45  
      */
 46  
     public static final int readTwoByteInt (ByteBuffer buffer, int start) {
 47  0
         final byte b1 = buffer.get(start);
 48  0
         final byte b2 = buffer.get(start + 1);
 49  0
         return ((b1 & 255) << 8) | (b2 & 255);
 50  
     }
 51  
 
 52  
     /**
 53  
      * Reads an unsigned 2-byte integer from two consecutive big-endian-ordered bytes of a byte array and returns the
 54  
      * value.
 55  
      * 
 56  
      * @param array the byte array containing the bytes
 57  
      * @param start the index position of the most-significant byte
 58  
      * @return the unsigned value of the two-byte integer
 59  
      */
 60  
     public static final int readTwoByteInt (byte[] array, int start) {
 61  0
         return ((array[start] & 255) << 8) | (array[start + 1] & 255);
 62  
     }
 63  
 
 64  
     /**
 65  
      * Reads an unsigned 3-byte integer from three consecutive big-endian-ordered bytes of a {@link ByteBuffer} object
 66  
      * and returns the value.
 67  
      * 
 68  
      * @param buffer the {@link ByteBuffer} containing the bytes
 69  
      * @param start the index position of the most-significant byte
 70  
      * @return the unsigned value of the three-byte integer
 71  
      */
 72  
     public static final int readThreeByteInt (ByteBuffer buffer, int start) {
 73  0
         final byte b1 = buffer.get(start);
 74  0
         final byte b2 = buffer.get(start + 1);
 75  0
         final byte b3 = buffer.get(start + 2);
 76  0
         return ((b1 & 255) << 16) | ((b2 & 255) << 8) | (b3 & 255);
 77  
     }
 78  
 
 79  
     /**
 80  
      * Reads an unsigned 3-byte integer from three consecutive big-endian-ordered bytes of a byte array and returns the
 81  
      * value.
 82  
      * 
 83  
      * @param array the byte array containing the bytes
 84  
      * @param start the index position of the most-significant byte
 85  
      * @return the unsigned value of the three-byte integer
 86  
      */
 87  
     public static final int readThreeByteInt (byte[] array, int start) {
 88  0
         return ((array[start] & 255) << 16) | ((array[start + 1] & 255) << 8) | (array[start + 2] & 255);
 89  
     }
 90  
 
 91  
     /**
 92  
      * Reads a (signed) 4-byte integer from four consecutive big-endian-ordered bytes of a {@link ByteBuffer} object and
 93  
      * returns the value.
 94  
      * 
 95  
      * @param buffer the {@link ByteBuffer} containing the bytes
 96  
      * @param start the index position of the most-significant byte
 97  
      * @return the value of the four-byte integer
 98  
      */
 99  
     public static final int readFourByteInt (ByteBuffer buffer, int start) {
 100  0
         final byte b1 = buffer.get(start);
 101  0
         final byte b2 = buffer.get(start + 1);
 102  0
         final byte b3 = buffer.get(start + 2);
 103  0
         final byte b4 = buffer.get(start + 3);
 104  0
         return ((b1 & 255) << 24) | ((b2 & 255) << 16) | ((b3 & 255) << 8) | (b4 & 255);
 105  
     }
 106  
 
 107  
     /**
 108  
      * Reads a (signed) 4-byte integer from four consecutive big-endian-ordered bytes of a byte array and returns the
 109  
      * value.
 110  
      * 
 111  
      * @param array the byte array containing the bytes
 112  
      * @param start the index position of the most-significant byte
 113  
      * @return the unsigned value of the four-byte integer
 114  
      */
 115  
     public static final int readFourByteInt (byte[] array, int start) {
 116  0
         return ((array[start] & 255) << 24) | ((array[start + 1] & 255) << 16) | ((array[start + 2] & 255) << 8) | (array[start + 3] & 255);
 117  
     }
 118  
 
 119  
     /**
 120  
      * Puts the characters in the passed String into an array of one or more ByteBuffers and returns it.
 121  
      * <p>
 122  
      * If the String does not end with a null character, one will be appended. If the String's length is larger than the
 123  
      * specified <i>bufferSize</i>, all but the last ByteBuffer will have <i>capacity() = bufferSize</i>, the last one
 124  
      * will contain the remaining String characters.
 125  
      * 
 126  
      * @param string the String to be put into the ByteBuffer
 127  
      * @param bufferSize the maximum size of the returned ByteBuffers
 128  
      * @return an array of ByteBuffers containing the passed String
 129  
      */
 130  
     public static ByteBuffer[] stringToTextDataSegments (String string, int bufferSize) {
 131  
 
 132  0
         int numberOfParts = string.length() / bufferSize + 1;
 133  0
         ByteBuffer[] segments = new ByteBuffer[numberOfParts];
 134  
 
 135  0
         int bytesRemaining = string.length();
 136  0
         for (int i = 0; i < numberOfParts; ++i) {
 137  0
             if (bytesRemaining > bufferSize) {
 138  0
                 segments[i] = stringToByteBuffer(string.substring(i * bufferSize, (i + 1) * bufferSize));
 139  
             } else {
 140  0
                 segments[i] = stringToByteBuffer(string.substring(i * bufferSize));
 141  
             }
 142  
         }
 143  0
         return segments;
 144  
     }
 145  
 
 146  
     /**
 147  
      * Puts the characters in the passed String into a ByteBuffer of equal length and returns it.
 148  
      * 
 149  
      * @param string any String
 150  
      * @return a ByteBuffer containing the characters of the passed String
 151  
      */
 152  
     private static ByteBuffer stringToByteBuffer (final String string) {
 153  0
         final ByteBuffer buffer = ByteBuffer.allocate(string.length());
 154  0
         for (int i = 0; i < string.length(); ++i)
 155  0
             buffer.put((byte) string.charAt(i));
 156  0
         buffer.clear();
 157  0
         return buffer;
 158  
     }
 159  
 
 160  
     /**
 161  
      * Appends the content of a <code>ProtocolDataUnit</code> (text) data segment to a {@link StringBuilder};
 162  
      * 
 163  
      * @param byteBuffer the PDU's data segment
 164  
      * @param stringBuilder the {@link StringBuilder} that will be extended
 165  
      */
 166  
     public static final void appendTextDataSegmentToStringBuffer (final ByteBuffer byteBuffer, final StringBuilder stringBuilder) {
 167  0
         final String s = new String(byteBuffer.array());
 168  0
         stringBuilder.append(s);
 169  0
     }
 170  
 
 171  
     /**
 172  
      * Writes the given <i>value</i> to the <i>buffer</i> in big-endian format, with the index position of the most
 173  
      * significant byte being <i>start</i>.
 174  
      * 
 175  
      * To get the value back from the buffer, use readUnsignedInt.
 176  
      * 
 177  
      * @param value the integer to write to the ByteBuffer
 178  
      * @param buffer where the integer will be stored
 179  
      * @param start index of the most significant byte of the stored <i>value</i>
 180  
      */
 181  
     public static final void writeInt (int value, final ByteBuffer buffer, int start) {
 182  0
         buffer.position(start);
 183  0
         buffer.put((byte) (value >>> 24));
 184  0
         buffer.put((byte) (value >>> 16));
 185  0
         buffer.put((byte) (value >>> 8));
 186  0
         buffer.put((byte) value);
 187  0
     }
 188  
 
 189  
     /**
 190  
      * Returns the bytes in a {@link ByteBuffer} as a UTF-8 encoded {@link String}.
 191  
      * 
 192  
      * @param buffer a {@link ByteBuffer} containing UTF-8 encoded characters.
 193  
      * @return a String representation of the <i>buffer</i>'s content
 194  
      */
 195  
     public static String byteBufferToString (final ByteBuffer buffer) {
 196  0
         buffer.rewind();
 197  0
         return new String(buffer.array());
 198  
     }
 199  
 
 200  
     /**
 201  
      * Splits the passed <i>value</i> into bytes and returns them in an array, in big-endian format.
 202  
      * 
 203  
      * @param value the long to split
 204  
      * @return byte representation of the parameter
 205  
      */
 206  
     public static byte[] longToBytes (final long value) {
 207  0
         final byte[] bytes = new byte[8];
 208  0
         for (int i = 0; i < bytes.length; ++i)
 209  0
             bytes[i] = (byte) (value >> (8 * (bytes.length - 1 - i)));
 210  0
         return bytes;
 211  
     }
 212  
 
 213  
     /**
 214  
      * Writes the given <i>value</i> to the <i>buffer</i> in big-endian format, with the index position of the most
 215  
      * significant byte being <i>index</i>.
 216  
      * 
 217  
      * @param value the integer to write to the ByteBuffer
 218  
      * @param buffer where the integer will be stored
 219  
      * @param index index of the most significant byte of the stored <i>value</i>
 220  
      */
 221  
     public static void writeLong (final ByteBuffer buffer, final long value, final int index) {
 222  0
         final byte[] bytes = longToBytes(value);
 223  0
         buffer.position(index);
 224  0
         for (int i = 0; i < bytes.length; ++i)
 225  0
             buffer.put(bytes[i]);
 226  0
     }
 227  
 
 228  
     /**
 229  
      * Writes the two least-significant big-endian-ordered bytes of an integer the a specified position in a
 230  
      * {@link ByteBuffer}.
 231  
      * 
 232  
      * @param buffer where the bytes will be written
 233  
      * @param value the value to convert and copy
 234  
      * @param index the position of the most significant byte in the {@link ByteBuffer}
 235  
      */
 236  
     public static void writeTwoByteInt (final ByteBuffer buffer, final int value, final int index) {
 237  0
         buffer.position(index);
 238  0
         buffer.put((byte) (value >> 8));// most significant byte
 239  0
         buffer.put((byte) value);// least significant byte
 240  0
     }
 241  
 
 242  
     /**
 243  
      * Writes the three least-significant big-endian-ordered bytes of an integer the a specified position in a
 244  
      * {@link ByteBuffer}.
 245  
      * 
 246  
      * @param buffer where the bytes will be written
 247  
      * @param value the value to convert and copy
 248  
      * @param index the position of the most significant byte in the {@link ByteBuffer}
 249  
      */
 250  
     public static void writeThreeByteInt (final ByteBuffer buffer, final int value, final int index) {
 251  
 
 252  0
         buffer.position(index);
 253  0
         buffer.put((byte) (value >> 16));// most significant byte
 254  0
         buffer.put((byte) (value >> 8));
 255  0
         buffer.put((byte) value);// least significant byte
 256  0
     }
 257  
 
 258  
     /**
 259  
      * Reads an unsigned 4-byte integer from four consecutive big-endian-ordered bytes of a {@link ByteBuffer} object
 260  
      * and returns the value.
 261  
      * 
 262  
      * @param buffer the {@link ByteBuffer} containing the bytes
 263  
      * @param start the index position of the most-significant byte
 264  
      * @return the value of the unsigned four-byte integer
 265  
      */
 266  
     public static long readUnsignedInt (final ByteBuffer buffer, final int start) {
 267  0
         return readFourByteInt(buffer, start) & 0xffffffffL;
 268  
     }
 269  
 
 270  
 }