    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 *  Unless required by applicable law or agreed to in writing, software
    012 *  distributed under the License is distributed on an "AS IS" BASIS,
    013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 *  See the License for the specific language governing permissions and
    015 *  limitations under the License.
    016 */
    017
    018package org.apache.bcel.util;
    019
    020import org.apache.bcel.Const;
    021import org.apache.bcel.classfile.ClassFormatException;
    022
    023/**
    024 * Argument validation.
    025 *
    026 * @since 6.7.0
    027 */
    028public class Args {
    029
    030    /**
    031     * Requires a specific value.
    032     *
    033     * @param value    The value to test.
    034     * @param required The required value.
    035     * @param message  The message prefix
    036     * @return The value to test.
    037     */
    038    public static int require(final int value, final int required, final String message) {
    039        if (value != required) {
    040            throw new ClassFormatException(String.format("%s [Value must be 0: %,d]", message, value));
    041        }
    042        return value;
    043    }
    044
    045    /**
    046     * Requires a 0 value.
    047     *
    048     * @param value   The value to test.
    049     * @param message The message prefix
    050     * @return The value to test.
    051     */
    052    public static int require0(final int value, final String message) {
    053        return require(value, 0, message);
    054    }
    055
    056    /**
    057     * Requires a u1 value.
    058     *
    059     * @param value   The value to test.
    060     * @param message The message prefix
    061     * @return The value to test.
    062     */
    063    public static int requireU1(final int value, final String message) {
    064        if (value < 0 || value > Const.MAX_BYTE) {
    065            throw new ClassFormatException(String.format("%s [Value out of range (0 - %,d) for type u1: %,d]", message, Const.MAX_BYTE, value));
    066        }
    067        return value;
    068    }
    069
    070    /**
    071     * Requires a u2 value of at least {@code min} and not above {@code max}.
    072     *
    073     * @param value   The value to test.
    074     * @param min     The minimum required u2 value.
    075     * @param max     The maximum required u2 value.
    076     * @param message The message prefix
    077     * @return The value to test.
    078     */
    079    public static int requireU2(final int value, final int min, final int max, final String message) {
    080        if (max > Const.MAX_SHORT) {
    081            throw new IllegalArgumentException(String.format("%s programming error: max %,d > %,d", message, max, Const.MAX_SHORT));
    082        }
    083        if (min < 0) {
    084            throw new IllegalArgumentException(String.format("%s programming error: min %,d < 0", message, min));
    085        }
    086        if (value < min || value > max) {
    087            throw new ClassFormatException(String.format("%s [Value out of range (%,d - %,d) for type u2: %,d]", message, min, Const.MAX_SHORT, value));
    088        }
    089        return value;
    090    }
    091
    092    /**
    093     * Requires a u2 value of at least {@code min}.
    094     *
    095     * @param value   The value to test.
    096     * @param min     The minimum required value.
    097     * @param message The message prefix
    098     * @return The value to test.
    099     */
    100    public static int requireU2(final int value, final int min, final String message) {
    101        return requireU2(value, min, Const.MAX_SHORT, message);
    102    }
    103
    104    /**
    105     * Requires a u2 value.
    106     *
    107     * @param value   The value to test.
    108     * @param message The message prefix
    109     * @return The value to test.
    110     */
    111    public static int requireU2(final int value, final String message) {
    112        return requireU2(value, 0, message);
    113    }
    114
    115    /**
    116     * Requires a u4 value of at least {@code min}.
    117     *
    118     * @param value   The value to test.
    119     * @param min     The minimum required value.
    120     * @param message The message prefix
    121     * @return The value to test.
    122     */
    123    public static int requireU4(final int value, final int min, final String message) {
    124        if (min < 0) {
    125            throw new IllegalArgumentException(String.format("%s programming error: min %,d < 0", message, min));
    126        }
    127        if (value < min) {
    128            throw new ClassFormatException(
    129                    String.format("%s [Value out of range (%,d - %,d) for type u2: %,d]", message, min, Integer.MAX_VALUE, value & 0xFFFFFFFFL));
    130        }
    131        return value;
    132    }
    133
    134    /**
    135     * Requires a u4 value.
    136     *
    137     * @param value   The value to test.
    138     * @param message The message prefix
    139     * @return The value to test.
    140     */
    141    public static int requireU4(final int value, final String message) {
    142        return requireU4(value, 0, message);
    143    }
    144}