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}