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