@@ -436,6 +436,15 @@ private Converter() {
436436 * collection.toArray()}. Calling this method is as thread-safe as calling
437437 * that method.
438438 *
439+ * <p>
440+ * <strong>Analysis</strong>
441+ * <ul>
442+ * <li>Time Complexity: <code>O(n)</code></li>
443+ * <li>Space Complexity: <code>O(n)</code></li>
444+ * <li>Alters Parameters: <code>false</code></li>
445+ * </ul>
446+ * </p>
447+ *
439448 * @param collection a collection of {@code Byte} objects
440449 * @return an array containing the same values as {@code collection}, in the
441450 * same order, converted to primitives
@@ -457,6 +466,15 @@ static byte[] toArray(Collection<java.lang.Byte> collection) {
457466 * Converts this primitive array to an boxed object array.
458467 * Will create a new array and not reuse the array reference.
459468 *
469+ * <p>
470+ * <strong>Analysis</strong>
471+ * <ul>
472+ * <li>Time Complexity: <code>O(n)</code></li>
473+ * <li>Space Complexity: <code>O(n)</code></li>
474+ * <li>Alters Parameters: <code>false</code></li>
475+ * </ul>
476+ * </p>
477+ *
460478 * @param array to convert
461479 * @return new array
462480 */
@@ -472,6 +490,15 @@ static java.lang.Byte[] toBoxedArray(byte[] array) {
472490 * Converts given array to list of boxed bytes. Will create a new list
473491 * and not reuse the array reference.
474492 *
493+ * <p>
494+ * <strong>Analysis</strong>
495+ * <ul>
496+ * <li>Time Complexity: <code>O(n)</code></li>
497+ * <li>Space Complexity: <code>O(n)</code></li>
498+ * <li>Alters Parameters: <code>false</code></li>
499+ * </ul>
500+ * </p>
501+ *
475502 * @param array to convert
476503 * @return list with same length and content as array
477504 */
@@ -487,6 +514,15 @@ static List<java.lang.Byte> toList(byte[] array) {
487514 * Converts this object array to an primitives type array.
488515 * Will create a new array and not reuse the array reference.
489516 *
517+ * <p>
518+ * <strong>Analysis</strong>
519+ * <ul>
520+ * <li>Time Complexity: <code>O(n)</code></li>
521+ * <li>Space Complexity: <code>O(n)</code></li>
522+ * <li>Alters Parameters: <code>false</code></li>
523+ * </ul>
524+ * </p>
525+ *
490526 * @param objectArray to convert
491527 * @return new array
492528 */
@@ -502,13 +538,24 @@ static byte[] toPrimitiveArray(java.lang.Byte[] objectArray) {
502538 * Creates a byte array from given int array.
503539 * The resulting byte array will have length intArray * 4.
504540 *
541+ * <p>
542+ * <strong>Analysis</strong>
543+ * <ul>
544+ * <li>Time Complexity: <code>O(n)</code></li>
545+ * <li>Space Complexity: <code>O(n)</code></li>
546+ * <li>Alters Parameters: <code>false</code></li>
547+ * </ul>
548+ * </p>
549+ *
505550 * @param intArray to convert
506551 * @return resulting byte array
507552 */
508553 static byte [] toByteArray (int [] intArray ) {
509554 byte [] primitivesArray = new byte [intArray .length * 4 ];
555+ ByteBuffer buffer = ByteBuffer .allocate (4 );
510556 for (int i = 0 ; i < intArray .length ; i ++) {
511- byte [] intBytes = ByteBuffer .allocate (4 ).putInt (intArray [i ]).array ();
557+ buffer .clear ();
558+ byte [] intBytes = buffer .putInt (intArray [i ]).array ();
512559 System .arraycopy (intBytes , 0 , primitivesArray , (i * 4 ), intBytes .length );
513560 }
514561 return primitivesArray ;
@@ -518,13 +565,24 @@ static byte[] toByteArray(int[] intArray) {
518565 * Creates a byte array from given long array.
519566 * The resulting byte array will have length longArray * 8
520567 *
568+ * <p>
569+ * <strong>Analysis</strong>
570+ * <ul>
571+ * <li>Time Complexity: <code>O(n)</code></li>
572+ * <li>Space Complexity: <code>O(n)</code></li>
573+ * <li>Alters Parameters: <code>false</code></li>
574+ * </ul>
575+ * </p>
576+ *
521577 * @param longArray to convert
522578 * @return resulting byte array
523579 */
524580 static byte [] toByteArray (long [] longArray ) {
525581 byte [] primitivesArray = new byte [longArray .length * 8 ];
582+ ByteBuffer buffer = ByteBuffer .allocate (8 );
526583 for (int i = 0 ; i < longArray .length ; i ++) {
527- byte [] longBytes = ByteBuffer .allocate (8 ).putLong (longArray [i ]).array ();
584+ buffer .clear ();
585+ byte [] longBytes = buffer .putLong (longArray [i ]).array ();
528586 System .arraycopy (longBytes , 0 , primitivesArray , (i * 8 ), longBytes .length );
529587 }
530588 return primitivesArray ;
@@ -533,6 +591,15 @@ static byte[] toByteArray(long[] longArray) {
533591 /**
534592 * Converts a char array to a byte array with given charset and range
535593 *
594+ * <p>
595+ * <strong>Analysis</strong>
596+ * <ul>
597+ * <li>Time Complexity: <code>O(n)</code></li>
598+ * <li>Space Complexity: <code>O(n)</code></li>
599+ * <li>Alters Parameters: <code>false</code></li>
600+ * </ul>
601+ * </p>
602+ *
536603 * @param charArray to get the byte array from
537604 * @param charset charset to be used to decode the char array
538605 * @param offset to start reading the char array from (must be smaller than length and gt 0)
@@ -567,6 +634,15 @@ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int
567634 /**
568635 * Convert given byte array in given encoding to char array
569636 *
637+ * <p>
638+ * <strong>Analysis</strong>
639+ * <ul>
640+ * <li>Time Complexity: <code>O(n)</code></li>
641+ * <li>Space Complexity: <code>O(n)</code></li>
642+ * <li>Alters Parameters: <code>false</code></li>
643+ * </ul>
644+ * </p>
645+ *
570646 * @param bytes as data source
571647 * @param charset of the byte array
572648 * @param byteOrder the order of the bytes array
@@ -596,6 +672,15 @@ static char[] byteToCharArray(byte[] bytes, Charset charset, ByteOrder byteOrder
596672 * [b1, b2, b3, b4] = [int1]
597673 * </pre>
598674 *
675+ * <p>
676+ * <strong>Analysis</strong>
677+ * <ul>
678+ * <li>Time Complexity: <code>O(n)</code></li>
679+ * <li>Space Complexity: <code>O(n)</code></li>
680+ * <li>Alters Parameters: <code>false</code></li>
681+ * </ul>
682+ * </p>
683+ *
599684 * @param bytes to convert to int array, must be % 4 == 0 to work correctly
600685 * @param byteOrder of the byte array
601686 * @return int array
@@ -614,6 +699,15 @@ static int[] toIntArray(byte[] bytes, ByteOrder byteOrder) {
614699 * [b1, b2, b3, b4, b5, b6, b7, b8] = [long1]
615700 * </pre>
616701 *
702+ * <p>
703+ * <strong>Analysis</strong>
704+ * <ul>
705+ * <li>Time Complexity: <code>O(n)</code></li>
706+ * <li>Space Complexity: <code>O(n)</code></li>
707+ * <li>Alters Parameters: <code>false</code></li>
708+ * </ul>
709+ * </p>
710+ *
617711 * @param bytes to convert to long array, must be % 8 == 0 to work correctly
618712 * @param byteOrder of the byte array
619713 * @return long array
@@ -629,6 +723,15 @@ static long[] toLongArray(byte[] bytes, ByteOrder byteOrder) {
629723 * Convert UUID to a newly generated 16 byte long array representation. Puts the 8 byte most significant bits and
630724 * 8 byte least significant bits into an byte array.
631725 *
726+ * <p>
727+ * <strong>Analysis</strong>
728+ * <ul>
729+ * <li>Time Complexity: <code>O(1)</code></li>
730+ * <li>Space Complexity: <code>O(1)</code></li>
731+ * <li>Alters Parameters: <code>false</code></li>
732+ * </ul>
733+ * </p>
734+ *
632735 * @param uuid to convert to array
633736 * @return buffer containing the 16 bytes
634737 */
@@ -647,6 +750,25 @@ static final class Obj {
647750 private Obj () {
648751 }
649752
753+ /**
754+ * Equals method comparing 2 byte arrays.
755+ * This utilizes a quick return of the array differs on any given property so not suitable
756+ * for security relevant checks. See {@link Util.Byte#constantTimeEquals(byte[], byte[])}
757+ * for that.
758+ *
759+ * <p>
760+ * <strong>Analysis</strong>
761+ * <ul>
762+ * <li>Time Complexity: <code>O(n)</code></li>
763+ * <li>Space Complexity: <code>O(1)</code></li>
764+ * <li>Alters Parameters: <code>false</code></li>
765+ * </ul>
766+ * </p>
767+ *
768+ * @param obj subject a
769+ * @param anotherArray subject b to compare to a
770+ * @return if a.len == b.len and for every 0..len a[i] == b[i]
771+ */
650772 static boolean equals (byte [] obj , java .lang .Byte [] anotherArray ) {
651773 if (anotherArray == null ) return false ;
652774 if (obj .length != anotherArray .length ) return false ;
@@ -661,6 +783,15 @@ static boolean equals(byte[] obj, java.lang.Byte[] anotherArray) {
661783 /**
662784 * Hashcode implementation for a byte array and given byte order
663785 *
786+ * <p>
787+ * <strong>Analysis</strong>
788+ * <ul>
789+ * <li>Time Complexity: <code>O(n)</code></li>
790+ * <li>Space Complexity: <code>O(1)</code></li>
791+ * <li>Alters Parameters: <code>false</code></li>
792+ * </ul>
793+ * </p>
794+ *
664795 * @param byteArray to calculate hashCode of
665796 * @param byteOrder to calculate hashCode of
666797 * @return hashCode
@@ -674,6 +805,15 @@ static int hashCode(byte[] byteArray, ByteOrder byteOrder) {
674805 /**
675806 * Shows the length and a preview of max 8 bytes of the given byte
676807 *
808+ * <p>
809+ * <strong>Analysis</strong>
810+ * <ul>
811+ * <li>Time Complexity: <code>O(1)</code></li>
812+ * <li>Space Complexity: <code>O(1)</code></li>
813+ * <li>Alters Parameters: <code>false</code></li>
814+ * </ul>
815+ * </p>
816+ *
677817 * @param bytes to convert to string
678818 * @return string representation
679819 */
@@ -698,38 +838,66 @@ static final class Validation {
698838 private Validation () {
699839 }
700840
701- private static void checkFile (java .io .File file ) {
702- if (file == null || !file .exists () || !file .isFile ()) {
703- throw new IllegalArgumentException ("file must not be null, has to exist and must be a file (not a directory) " + file );
704- }
705- }
706-
841+ /**
842+ * Check if a length of an primitive (e.g. int = 4 byte) fits in given length from given start index.
843+ * Throws exception with descriptive exception message.
844+ *
845+ * @param length of the whole array
846+ * @param index to start from array length
847+ * @param primitiveLength length of the primitive type to check
848+ * @param type for easier debugging the human readable type of the checked primitive
849+ * to put in exception message
850+ * @throws IndexOutOfBoundsException if index + primitiveLength > length
851+ */
707852 static void checkIndexBounds (int length , int index , int primitiveLength , String type ) {
708853 if (index < 0 || index + primitiveLength > length ) {
709854 throw new IndexOutOfBoundsException ("cannot get " + type + " from index out of bounds: " + index );
710855 }
711856 }
712857
858+ /**
859+ * Check if given length is an expected length.
860+ * Throws exception with descriptive exception message.
861+ *
862+ * @param length of the whole array
863+ * @param expectedLength how length is expected
864+ * @param type for easier debugging the human readable type of the checked primitive
865+ * to put in exception message
866+ * @throws IllegalArgumentException if length != expectedLength
867+ */
713868 static void checkExactLength (int length , int expectedLength , String type ) {
714869 if (length != expectedLength ) {
715- throw new IllegalStateException ("cannot convert to " + type + " if length != " + expectedLength + " bytes (was " + length + ")" );
870+ throw new IllegalArgumentException ("cannot convert to " + type + " if length != " + expectedLength + " bytes (was " + length + ")" );
716871 }
717872 }
718873
719874 /**
720- * Checks if given length is divisable by mod factor (with zero rest).
721- * This can be used to check of a byte array can be convertet to an e.g. int array which is
875+ * Checks if given length is divisible by mod factor (with zero rest).
876+ * This can be used to check of a byte array can be converted to an e.g. int array which is
722877 * multiples of 4.
723878 *
724879 * @param length of the byte array
725880 * @param modFactor to divide the length
726881 * @param errorSubject human readable message of the exact error subject
882+ * @throws IllegalArgumentException if length % modFactor != 0
727883 */
728884 static void checkModLength (int length , int modFactor , String errorSubject ) {
729885 if (length % modFactor != 0 ) {
730886 throw new IllegalArgumentException ("Illegal length for " + errorSubject + ". Byte array length must be multiple of " + modFactor + ", length was " + length );
731887 }
732888 }
889+
890+ /**
891+ * Check if the file exists and is a file.
892+ *
893+ * @param file to check
894+ * @throws IllegalArgumentException if either file is null, does not exists or is not a file
895+ */
896+ private static void checkFileExists (java .io .File file ) {
897+ if (file == null || !file .exists () || !file .isFile ()) {
898+ throw new IllegalArgumentException ("file must not be null, has to exist and must be a file (not a directory) " + file );
899+ }
900+ }
733901 }
734902
735903 /**
@@ -803,7 +971,7 @@ static byte[] readFromDataInput(DataInput dataInput, int length) {
803971 * @return byte content
804972 */
805973 static byte [] readFromFile (java .io .File file ) {
806- Validation .checkFile (file );
974+ Validation .checkFileExists (file );
807975
808976 try {
809977 return Files .readAllBytes (file .toPath ());
@@ -821,7 +989,7 @@ static byte[] readFromFile(java.io.File file) {
821989 * @return byte array with length length
822990 */
823991 static byte [] readFromFile (java .io .File file , int offset , int length ) {
824- Validation .checkFile (file );
992+ Validation .checkFileExists (file );
825993 try (RandomAccessFile raf = new RandomAccessFile (file , "r" )) {
826994 raf .seek (offset );
827995 return readFromDataInput (raf , length );
0 commit comments