@@ -661,7 +661,8 @@ public Bytes not() {
661661 }
662662
663663 /**
664- * Bitwise left shifting of internal byte array.
664+ * Bitwise left shifting of internal byte array (i.e. <code><<</code>). Unlike {@link BigInteger}'s implementation, this one will never
665+ * grow or shrink the underlying array. Either a bit is pushed out of the array or a zero is pushed in.
665666 * <p>
666667 * See the considerations about possible in-place operation in {@link #transform(BytesTransformer)}.
667668 *
@@ -674,7 +675,9 @@ public Bytes leftShift(int shiftCount) {
674675 }
675676
676677 /**
677- * Bitwise unsigned/logical right shifting of internal byte array (i.e. <code>>>></code>).
678+ * Bitwise unsigned/logical right shifting of internal byte array (i.e. <code>>>></code>). Unlike
679+ * {@link BigInteger}'s implementation, this one will never grow or shrink the underlying array. Either a bit is pushed
680+ * out of the array or a zero is pushed in.
678681 * <p>
679682 * See the considerations about possible in-place operation in {@link #transform(BytesTransformer)}.
680683 *
@@ -948,6 +951,21 @@ public int lastIndexOf(byte target) {
948951 return Util .lastIndexOf (internalArray (), target , 0 , length ());
949952 }
950953
954+ /**
955+ * Returns the {@code bit} value as boolean at the specified index. Bit index 0 is the LSB, so for example byte word
956+ * <code>1000 0000</code> has <code>bitAt(0) == false</code> and <code>bitAt(7) == true</code>.
957+ *
958+ * @param bitIndex the index of the {@code bit} value.
959+ * @return true if bit at given index is set, false otherwise
960+ * @throws IndexOutOfBoundsException if the {@code bitIndex} argument is negative or not less than the length of this array in bits.
961+ */
962+ public boolean bitAt (int bitIndex ) {
963+ if (bitIndex < 0 || bitIndex > lengthBit ()) {
964+ throw new IndexOutOfBoundsException ("cannot get bit from index out of bounds: " + bitIndex );
965+ }
966+ return ((byteAt (length () - 1 - (bitIndex / 8 )) >>> bitIndex % 8 ) & 1 ) != 0 ;
967+ }
968+
951969 /**
952970 * Returns the {@code byte} value at the specified index.
953971 * An index ranges from {@code 0} to {@code length() - 1}. The first {@code char} value of the sequence
@@ -965,18 +983,55 @@ public byte byteAt(int index) {
965983 }
966984
967985 /**
968- * Returns the {@code bit } value as boolean at the specified index. Bit index 0 is the LSB, so for example byte word
969- * <code>1000 0000</code> has <code>bitAt(0) == false</code> and <code>bitAt(7) == true</code> .
986+ * Returns the {@code char } value at the specified index.
987+ * Reads the primitive from given index and the following byte and interprets it according to byte order .
970988 *
971- * @param bitIndex the index of the {@code bit } value.
972- * @return true if bit at given index is set, false otherwise
973- * @throws IndexOutOfBoundsException if the {@code bitIndex } argument is negative or not less than the length of this array in bits.
989+ * @param index the index of the {@code char } value.
990+ * @return the {@code char} value at the specified index of the underlying byte array.
991+ * @throws IndexOutOfBoundsException if the {@code index } argument is negative or length is greater than index - 2
974992 */
975- public boolean bitAt (int bitIndex ) {
976- if (bitIndex < 0 || bitIndex > lengthBit ()) {
977- throw new IndexOutOfBoundsException ("cannot get bit from index out of bounds: " + bitIndex );
978- }
979- return ((byteAt (length () - 1 - (bitIndex / 8 )) >>> bitIndex % 8 ) & 1 ) != 0 ;
993+ public char charAt (int index ) {
994+ Util .checkIndexBounds (length (), index , 2 , "char" );
995+ return ((ByteBuffer ) ByteBuffer .wrap (internalArray ()).order (byteOrder ).position (index )).getChar ();
996+ }
997+
998+ /**
999+ * Returns the {@code short} value at the specified index.
1000+ * Reads the primitive from given index and the following byte and interprets it according to byte order.
1001+ *
1002+ * @param index the index of the {@code short} value.
1003+ * @return the {@code short} value at the specified index of the underlying byte array.
1004+ * @throws IndexOutOfBoundsException if the {@code index} argument is negative or length is greater than index - 2
1005+ */
1006+ public short shortAt (int index ) {
1007+ Util .checkIndexBounds (length (), index , 2 , "short" );
1008+ return ((ByteBuffer ) ByteBuffer .wrap (internalArray ()).order (byteOrder ).position (index )).getShort ();
1009+ }
1010+
1011+ /**
1012+ * Returns the {@code int} value at the specified index.
1013+ * Reads the primitive from given index and the following 3 bytes and interprets it according to byte order.
1014+ *
1015+ * @param index the index of the {@code int} value.
1016+ * @return the {@code int} value at the specified index of the underlying byte array.
1017+ * @throws IndexOutOfBoundsException if the {@code int} argument is negative or length is greater than index - 4
1018+ */
1019+ public int intAt (int index ) {
1020+ Util .checkIndexBounds (length (), index , 4 , "int" );
1021+ return ((ByteBuffer ) ByteBuffer .wrap (internalArray ()).order (byteOrder ).position (index )).getInt ();
1022+ }
1023+
1024+ /**
1025+ * Returns the {@code long} value at the specified index.
1026+ * Reads the primitive from given index and the following 7 bytes and interprets it according to byte order.
1027+ *
1028+ * @param index the index of the {@code long} value.
1029+ * @return the {@code long} value at the specified index of the underlying byte array.
1030+ * @throws IndexOutOfBoundsException if the {@code long} argument is negative or length is greater than index - 8
1031+ */
1032+ public long longAt (int index ) {
1033+ Util .checkIndexBounds (length (), index , 8 , "long" );
1034+ return ((ByteBuffer ) ByteBuffer .wrap (internalArray ()).order (byteOrder ).position (index )).getLong ();
9801035 }
9811036
9821037 /**
@@ -1279,107 +1334,103 @@ public BigInteger toBigInteger() {
12791334 }
12801335
12811336 /**
1282- * If the underlying byte array is smaller than or equal to 1 byte / 8 bit returns unsigned two-complement
1337+ * If the underlying byte array is exactly 1 byte / 8 bit long, returns unsigned two-complement
12831338 * representation for a Java byte value.
1339+ * <p>
1340+ * If you just want to get the first element as {@code byte}, see {@link #byteAt(int)}, using index zero.
12841341 *
12851342 * @return the byte representation
1286- * @throws UnsupportedOperationException if byte array is longer than 1 byte
1343+ * @throws IllegalStateException if byte array has length not equal to 1
12871344 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
12881345 */
12891346 public byte toByte () {
1290- if (length () > 1 ) {
1291- throw new UnsupportedOperationException ("cannot convert to byte if length > 1 byte" );
1292- }
1293- return internalBuffer ().get ();
1347+ Util .checkExactLength (length (), 1 , "byte" );
1348+ return internalArray ()[0 ];
12941349 }
12951350
12961351 /**
1297- * If the underlying byte array is smaller than or equal to 2 byte / 16 bit returns unsigned two-complement
1352+ * If the underlying byte array is exactly 2 byte / 16 bit long, return unsigned two-complement
12981353 * representation for a Java char integer value. The output is dependent on the set {@link #byteOrder()}.
1354+ * <p>
1355+ * If you just want to get the first 2 bytes as {@code char}, see {@link #charAt(int)} using index zero.
12991356 *
13001357 * @return the int representation
1301- * @throws UnsupportedOperationException if byte array is longer than 2 byte
1358+ * @throws IllegalStateException if byte array has length not equal to 2
13021359 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
13031360 */
13041361 public char toChar () {
1305- if (length () > 2 ) {
1306- throw new UnsupportedOperationException ("cannot convert to char if length > 2 byte" );
1307- }
1308- return resize (2 ).internalBuffer ().getChar ();
1362+ Util .checkExactLength (length (), 2 , "char" );
1363+ return internalBuffer ().getChar ();
13091364 }
13101365
13111366 /**
1312- * If the underlying byte array is smaller than or equal to 2 byte / 16 bit returns signed two-complement
1367+ * If the underlying byte array is exactly 2 byte / 16 bit long, return signed two-complement
13131368 * representation for a Java short integer value. The output is dependent on the set {@link #byteOrder()}.
1369+ * <p>
1370+ * If you just want to get the first 2 bytes as {@code short}, see {@link #shortAt(int)} using index zero.
13141371 *
13151372 * @return the int representation
1316- * @throws UnsupportedOperationException if byte array is longer than 2 byte
1373+ * @throws IllegalStateException if byte array has length not equal to 2
13171374 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
13181375 */
13191376 public short toShort () {
1320- if (length () > 2 ) {
1321- throw new UnsupportedOperationException ("cannot convert to short if length > 2 byte" );
1322- }
1323- return resize (2 ).internalBuffer ().getShort ();
1377+ Util .checkExactLength (length (), 2 , "short" );
1378+ return internalBuffer ().getShort ();
13241379 }
13251380
13261381 /**
1327- * If the underlying byte array is smaller than or equal to 4 byte / 32 bit returns signed two-complement
1382+ * If the underlying byte array is exactly 4 byte / 32 bit long, return signed two-complement
13281383 * representation for a Java signed integer value. The output is dependent on the set {@link #byteOrder()}.
1384+ * <p>
1385+ * If you just want to get the first 4 bytes as {@code int}, see {@link #intAt(int)} using index zero.
13291386 *
13301387 * @return the int representation
1331- * @throws UnsupportedOperationException if byte array is longer than 4 byte
1388+ * @throws IllegalStateException if byte array has length not equal to 4
13321389 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
13331390 */
13341391 public int toInt () {
1335- if (length () > 4 ) {
1336- throw new UnsupportedOperationException ("cannot convert to int if length > 4 byte" );
1337- }
1338- return resize (4 ).internalBuffer ().getInt ();
1392+ Util .checkExactLength (length (), 4 , "int" );
1393+ return internalBuffer ().getInt ();
13391394 }
13401395
13411396 /**
1342- * If the underlying byte array is smaller than or equal to 8 byte / 64 bit returns signed two-complement
1397+ * If the underlying byte array is exactly 8 byte / 64 bit long, return signed two-complement
13431398 * representation for a Java signed long integer value. The output is dependent on the set {@link #byteOrder()}.
1399+ * <p>
1400+ * If you just want to get the first 4 bytes as {@code long}, see {@link #longAt(int)} using index zero.
13441401 *
13451402 * @return the long representation
1346- * @throws UnsupportedOperationException if byte array is longer than 8 byte
1403+ * @throws IllegalStateException if byte array has length not equal to 8
13471404 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
13481405 */
13491406 public long toLong () {
1350- if (length () > 8 ) {
1351- throw new UnsupportedOperationException ("cannot convert to long if length > 8 byte" );
1352- }
1407+ Util .checkExactLength (length (), 8 , "long" );
13531408 return resize (8 ).internalBuffer ().getLong ();
13541409 }
13551410
13561411 /**
1357- * If the underlying byte array is smaller than or equal to 4 byte / 32 bit returns the
1412+ * If the underlying byte array is exactly 4 byte / 32 bit long, return the
13581413 * representation for a Java float value. The output is dependent on the set {@link #byteOrder()}.
13591414 *
13601415 * @return the float representation
1361- * @throws UnsupportedOperationException if byte array is longer than 4 byte
1416+ * @throws IllegalStateException if byte array has length not equal to 4
13621417 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
13631418 */
13641419 public float toFloat () {
1365- if (length () > 4 ) {
1366- throw new UnsupportedOperationException ("cannot convert to float if length > 4 byte" );
1367- }
1368- return resize (4 ).internalBuffer ().getFloat ();
1420+ Util .checkExactLength (length (), 4 , "float" );
1421+ return internalBuffer ().getFloat ();
13691422 }
13701423
13711424 /**
1372- * If the underlying byte array is smaller than or equal to 8 byte / 64 bit returns the
1425+ * If the underlying byte array is exactly 8 byte / 64 bit long, return the
13731426 * representation for a Java float value. The output is dependent on the set {@link #byteOrder()}.
13741427 *
1375- * @return the float representation
1376- * @throws UnsupportedOperationException if byte array is longer than 8 byte
1428+ * @return the double representation
1429+ * @throws IllegalStateException if byte array has length not equal to 8
13771430 * @see <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">Primitive Types</a>
13781431 */
13791432 public double toDouble () {
1380- if (length () > 8 ) {
1381- throw new UnsupportedOperationException ("cannot convert to float if length > 8 byte" );
1382- }
1433+ Util .checkExactLength (length (), 8 , "double" );
13831434 return resize (8 ).internalBuffer ().getDouble ();
13841435 }
13851436
0 commit comments