1717
1818package org .apache .commons .io ;
1919
20+ import static java .util .Objects .requireNonNull ;
21+
2022import java .io .BufferedInputStream ;
2123import java .io .BufferedOutputStream ;
2224import java .io .BufferedReader ;
@@ -244,7 +246,7 @@ public class IOUtils {
244246 public static BufferedInputStream buffer (final InputStream inputStream ) {
245247 // reject null early on rather than waiting for IO operation to fail
246248 // not checked by BufferedInputStream
247- Objects . requireNonNull (inputStream , "inputStream" );
249+ requireNonNull (inputStream , "inputStream" );
248250 return inputStream instanceof BufferedInputStream ?
249251 (BufferedInputStream ) inputStream : new BufferedInputStream (inputStream );
250252 }
@@ -263,7 +265,7 @@ public static BufferedInputStream buffer(final InputStream inputStream) {
263265 public static BufferedInputStream buffer (final InputStream inputStream , final int size ) {
264266 // reject null early on rather than waiting for IO operation to fail
265267 // not checked by BufferedInputStream
266- Objects . requireNonNull (inputStream , "inputStream" );
268+ requireNonNull (inputStream , "inputStream" );
267269 return inputStream instanceof BufferedInputStream ?
268270 (BufferedInputStream ) inputStream : new BufferedInputStream (inputStream , size );
269271 }
@@ -281,7 +283,7 @@ public static BufferedInputStream buffer(final InputStream inputStream, final in
281283 public static BufferedOutputStream buffer (final OutputStream outputStream ) {
282284 // reject null early on rather than waiting for IO operation to fail
283285 // not checked by BufferedInputStream
284- Objects . requireNonNull (outputStream , "outputStream" );
286+ requireNonNull (outputStream , "outputStream" );
285287 return outputStream instanceof BufferedOutputStream ?
286288 (BufferedOutputStream ) outputStream : new BufferedOutputStream (outputStream );
287289 }
@@ -300,7 +302,7 @@ public static BufferedOutputStream buffer(final OutputStream outputStream) {
300302 public static BufferedOutputStream buffer (final OutputStream outputStream , final int size ) {
301303 // reject null early on rather than waiting for IO operation to fail
302304 // not checked by BufferedInputStream
303- Objects . requireNonNull (outputStream , "outputStream" );
305+ requireNonNull (outputStream , "outputStream" );
304306 return outputStream instanceof BufferedOutputStream ?
305307 (BufferedOutputStream ) outputStream : new BufferedOutputStream (outputStream , size );
306308 }
@@ -407,35 +409,112 @@ private static char[] charArray(final int size) {
407409 }
408410
409411 /**
410- * Checks if the sub-range described by an offset and length is valid for an array of the given length.
412+ * Checks if the sub-range described by an offset and length is valid for the given array.
413+ *
414+ * <p>The range is valid if all of the following hold:</p>
415+ * <ul>
416+ * <li>{@code off >= 0}</li>
417+ * <li>{@code len >= 0}</li>
418+ * <li>{@code off + len <= array.length}</li>
419+ * </ul>
420+ *
421+ * <p>If the range is invalid, this method throws an
422+ * {@link IndexOutOfBoundsException} with a descriptive message.</p>
423+ *
424+ * @param array The array to be checked against
425+ * @param off The starting offset into the array
426+ * @param len The number of elements in the range
427+ * @throws NullPointerException If the array is null
428+ * @throws IndexOutOfBoundsException If the range {@code [off, off + len)} is out of bounds
429+ * @since 2.21.0
430+ */
431+ public static void checkFromIndexSize (final byte [] array , final int off , final int len ) {
432+ checkFromIndexSize (off , len , requireNonNull (array , "byte array" ).length );
433+ }
434+
435+ /**
436+ * Checks if the sub-range described by an offset and length is valid for the given array.
437+ *
438+ * <p>The range is valid if all of the following hold:</p>
439+ * <ul>
440+ * <li>{@code off >= 0}</li>
441+ * <li>{@code len >= 0}</li>
442+ * <li>{@code off + len <= array.length}</li>
443+ * </ul>
444+ *
445+ * <p>If the range is invalid, this method throws an
446+ * {@link IndexOutOfBoundsException} with a descriptive message.</p>
411447 *
412- * <p>This method is functionally equivalent to
413- * {@code java.util.Objects#checkFromIndexSize(int, int, int)} introduced in Java 9,
414- * but is provided here for use on Java 8.</p>
448+ * @param array The array to be checked against
449+ * @param off The starting offset into the array
450+ * @param len The number of elements in the range
451+ * @throws NullPointerException If the array is null
452+ * @throws IndexOutOfBoundsException If the range {@code [off, off + len)} is out of bounds
453+ * @since 2.21.0
454+ */
455+ public static void checkFromIndexSize (final char [] array , final int off , final int len ) {
456+ checkFromIndexSize (off , len , requireNonNull (array , "char array" ).length );
457+ }
458+
459+ /**
460+ * Checks if the sub-range described by an offset and length is valid for the given string.
415461 *
416462 * <p>The range is valid if all of the following hold:</p>
417463 * <ul>
418464 * <li>{@code off >= 0}</li>
419465 * <li>{@code len >= 0}</li>
420- * <li>{@code arrayLength >= 0}</li>
421- * <li>{@code off + len <= arrayLength}</li>
466+ * <li>{@code off + len <= array.length}</li>
422467 * </ul>
423468 *
424469 * <p>If the range is invalid, this method throws an
425470 * {@link IndexOutOfBoundsException} with a descriptive message.</p>
426471 *
427- * @param off the starting offset into the array
428- * @param len the number of elements in the range
429- * @param arrayLength the length of the array to be checked against
430- * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds
472+ * @param str The char sequence to be checked against
473+ * @param off The starting offset into the array
474+ * @param len The number of elements in the range
475+ * @throws NullPointerException If the array is null
476+ * @throws IndexOutOfBoundsException If the range {@code [off, off + len)} is out of bounds
431477 * @since 2.21.0
432478 */
433- public static void checkFromIndexSize (final int off , final int len , final int arrayLength ) {
479+ public static void checkFromIndexSize (final String str , final int off , final int len ) {
480+ checkFromIndexSize (off , len , requireNonNull (str , "str" ).length ());
481+ }
482+
483+ static void checkFromIndexSize (final int off , final int len , final int arrayLength ) {
434484 if ((off | len | arrayLength ) < 0 || arrayLength - len < off ) {
435485 throw new IndexOutOfBoundsException (String .format ("Range [%s, %<s + %s) out of bounds for length %s" , off , len , arrayLength ));
436486 }
437487 }
438488
489+ /**
490+ * Checks if the sub-sequence described by fromIndex (inclusive) and toIndex (exclusive) is valid for the given {@link CharSequence}.
491+ *
492+ * <p>The range is valid if all of the following hold:</p>
493+ * <ul>
494+ * <li>{@code fromIndex >= 0}</li>
495+ * <li>{@code fromIndex <= toIndex}</li>
496+ * <li>{@code toIndex <= seq.length()}</li>
497+ * </ul>
498+ *
499+ * <p>If the range is invalid, this method throws an {@link IndexOutOfBoundsException} with a descriptive message.</p>
500+ *
501+ * @param seq The char sequence to be checked against
502+ * @param fromIndex The starting index into the char sequence (inclusive)
503+ * @param toIndex The ending index into the char sequence (exclusive)
504+ * @throws NullPointerException If the char sequence is null
505+ * @throws IndexOutOfBoundsException If the range {@code [fromIndex, toIndex)} is out of bounds
506+ * @since 2.21.0
507+ */
508+ public static void checkFromToIndex (final CharSequence seq , int fromIndex , final int toIndex ) {
509+ checkFromToIndex (fromIndex , toIndex , requireNonNull (seq , "char sequence" ).length ());
510+ }
511+
512+ static void checkFromToIndex (final int fromIndex , final int toIndex , final int length ) {
513+ if (fromIndex < 0 | toIndex < fromIndex | length < toIndex ) {
514+ throw new IndexOutOfBoundsException (String .format ("Range [%s, %s) out of bounds for length %s" , fromIndex , toIndex , length ));
515+ }
516+ }
517+
439518 /**
440519 * Clears any state.
441520 * <ul>
@@ -1217,7 +1296,7 @@ public static void copy(final InputStream input, final Writer writer, final Stri
12171296 */
12181297 @ SuppressWarnings ("resource" ) // streams are closed by the caller.
12191298 public static QueueInputStream copy (final java .io .ByteArrayOutputStream outputStream ) throws IOException {
1220- Objects . requireNonNull (outputStream , "outputStream" );
1299+ requireNonNull (outputStream , "outputStream" );
12211300 final QueueInputStream in = new QueueInputStream ();
12221301 outputStream .writeTo (in .newQueueOutputStream ());
12231302 return in ;
@@ -1398,7 +1477,7 @@ public static int copy(final Reader reader, final Writer writer) throws IOExcept
13981477 * @since 2.9.0
13991478 */
14001479 public static long copy (final URL url , final File file ) throws IOException {
1401- try (OutputStream outputStream = Files .newOutputStream (Objects . requireNonNull (file , "file" ).toPath ())) {
1480+ try (OutputStream outputStream = Files .newOutputStream (requireNonNull (file , "file" ).toPath ())) {
14021481 return copy (url , outputStream );
14031482 }
14041483 }
@@ -1421,7 +1500,7 @@ public static long copy(final URL url, final File file) throws IOException {
14211500 * @since 2.9.0
14221501 */
14231502 public static long copy (final URL url , final OutputStream outputStream ) throws IOException {
1424- try (InputStream inputStream = Objects . requireNonNull (url , "url" ).openStream ()) {
1503+ try (InputStream inputStream = requireNonNull (url , "url" ).openStream ()) {
14251504 return copyLarge (inputStream , outputStream );
14261505 }
14271506 }
@@ -1470,8 +1549,8 @@ public static long copyLarge(final InputStream inputStream, final OutputStream o
14701549 @ SuppressWarnings ("resource" ) // streams are closed by the caller.
14711550 public static long copyLarge (final InputStream inputStream , final OutputStream outputStream , final byte [] buffer )
14721551 throws IOException {
1473- Objects . requireNonNull (inputStream , "inputStream" );
1474- Objects . requireNonNull (outputStream , "outputStream" );
1552+ requireNonNull (inputStream , "inputStream" );
1553+ requireNonNull (outputStream , "outputStream" );
14751554 long count = 0 ;
14761555 int n ;
14771556 while (EOF != (n = inputStream .read (buffer ))) {
@@ -2739,7 +2818,7 @@ public static byte[] toByteArray(final InputStream inputStream) throws IOExcepti
27392818 * @since 2.1
27402819 */
27412820 public static byte [] toByteArray (final InputStream input , final int size ) throws IOException {
2742- return toByteArray (Objects . requireNonNull (input , "input" )::read , size );
2821+ return toByteArray (requireNonNull (input , "input" )::read , size );
27432822 }
27442823
27452824 /**
@@ -2765,7 +2844,7 @@ public static byte[] toByteArray(final InputStream input, final int size) throws
27652844 * @since 2.21.0
27662845 */
27672846 public static byte [] toByteArray (final InputStream input , final int size , final int chunkSize ) throws IOException {
2768- Objects . requireNonNull (input , "input" );
2847+ requireNonNull (input , "input" );
27692848 if (chunkSize <= 0 ) {
27702849 throw new IllegalArgumentException ("Chunk size must be greater than zero: " + chunkSize );
27712850 }
@@ -3913,7 +3992,7 @@ public static void writeLines(final Collection<?> lines, String lineEnding, fina
39133992 * @since 2.7
39143993 */
39153994 public static Writer writer (final Appendable appendable ) {
3916- Objects . requireNonNull (appendable , "appendable" );
3995+ requireNonNull (appendable , "appendable" );
39173996 if (appendable instanceof Writer ) {
39183997 return (Writer ) appendable ;
39193998 }
0 commit comments