Home | History | Annotate | Download | only in conscrypt
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package org.conscrypt;
     18 
     19 /**
     20  * Static convenience methods that help a method or constructor check whether it was invoked
     21  * correctly (that is, whether its <i>preconditions</i> were met).
     22  */
     23 final class Preconditions {
     24     private Preconditions() {}
     25 
     26     /**
     27      * Ensures that an object reference passed as a parameter to the calling method is not null.
     28      *
     29      * @param reference an object reference
     30      * @param errorMessage the exception message to use if the check fails.
     31      * @return the non-null reference that was validated
     32      * @throws NullPointerException if {@code reference} is null
     33      */
     34     static <T> T checkNotNull(T reference, String errorMessage) {
     35         if (reference == null) {
     36             throw new NullPointerException(errorMessage);
     37         }
     38         return reference;
     39     }
     40 
     41     /**
     42      * Ensures the truth of an expression involving one or more parameters to the calling method.
     43      *
     44      * @param condition to condition to be tested
     45      * @param errorMessage the exception message to use if the check fails.
     46      * @throws IllegalArgumentException if the condition is {@code false}
     47      */
     48     static void checkArgument(boolean condition, String errorMessage) {
     49         if (!condition) {
     50             throw new IllegalArgumentException(errorMessage);
     51         }
     52     }
     53 
     54     /**
     55      * Ensures the truth of an expression involving one or more parameters to the calling method.
     56      *
     57      * @param condition to condition to be tested
     58      * @param errorMessageTemplate the format string to be passed to {@link String#format(String,
     59      * Object...)}
     60      * @param arg the format argument to be passed to {@link String#format(String, Object...)}
     61      * @throws IllegalArgumentException if the condition is {@code false}
     62      */
     63     static void checkArgument(boolean condition, String errorMessageTemplate, Object arg) {
     64         if (!condition) {
     65             throw new IllegalArgumentException(String.format(errorMessageTemplate, arg));
     66         }
     67     }
     68 
     69     /**
     70      * Ensures that {@code start} and {@code end} specify a valid <i>positions</i> in an array, list
     71      * or string of size {@code size}, and are in order. A position index may range from zero to
     72      * {@code size}, inclusive.
     73      *
     74      * @param start a user-supplied index identifying a starting position in an array, list or string
     75      * @param end a user-supplied index identifying a ending position in an array, list or string
     76      * @param size the size of that array, list or string
     77      * @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size},
     78      *     or if {@code end} is less than {@code start}
     79      * @throws IllegalArgumentException if {@code size} is negative
     80      */
     81     static void checkPositionIndexes(int start, int end, int size) {
     82         // Carefully optimized for execution by hotspot (explanatory comment above)
     83         if (start < 0 || end < start || end > size) {
     84             throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
     85         }
     86     }
     87 
     88     private static String badPositionIndexes(int start, int end, int size) {
     89         if (start < 0 || start > size) {
     90             return badPositionIndex(start, size, "start index");
     91         }
     92         if (end < 0 || end > size) {
     93             return badPositionIndex(end, size, "end index");
     94         }
     95         // end < start
     96         return String.format("end index (%s) must not be less than start index (%s)", end, start);
     97     }
     98 
     99     private static String badPositionIndex(int index, int size, String desc) {
    100         if (index < 0) {
    101             return String.format("%s (%s) must not be negative", desc, index);
    102         } else if (size < 0) {
    103             throw new IllegalArgumentException("negative size: " + size);
    104         } else { // index > size
    105             return String.format("%s (%s) must not be greater than size (%s)", desc, index, size);
    106         }
    107     }
    108 }
    109