Pack200Exception.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.commons.compress.harmony.pack200;
import java.util.function.Function;
import org.apache.commons.compress.CompressException;
import org.apache.commons.compress.MemoryLimitException;
import org.apache.commons.compress.archivers.ArchiveException;
/**
* Signals a problem with a Pack200 coding or decoding issue.
*
* @see <a href="https://docs.oracle.com/en/java/javase/13/docs/specs/pack-spec.html">Pack200: A Packed Class Deployment Format For Java Applications</a>
*/
public class Pack200Exception extends CompressException {
private static final Function<Throwable, Pack200Exception> E_FUNCTION = Pack200Exception::new;
private static final long serialVersionUID = 5168177401552611803L;
/**
* Delegates to {@link Math#addExact(int, int)} wrapping its {@link ArithmeticException} in our {@link ArchiveException}.
*
* @param x the first value.
* @param y the second value.
* @return the result.
* @throws Pack200Exception if the result or input overflows an {@code int}.
* @see Math#addExact(int, int)
* @since 1.29.0
*/
public static int addExact(final int x, final long y) throws Pack200Exception {
return addExact(x, y, E_FUNCTION);
}
/**
* Throws a MemoryLimitException if the request couldn't allocate an {@code int} array of the given size.
*
* @param size The requested array size.
* @return The request.
* @throws Pack200Exception Thrown if the request is greater than the max.
* @since 1.29.0
*/
public static int checkIntArray(final int size) throws Pack200Exception {
try {
MemoryLimitException.checkBytes(Math.multiplyExact(Integer.BYTES, size), Runtime.getRuntime().totalMemory());
return size;
} catch (final MemoryLimitException | ArithmeticException e) {
throw new Pack200Exception(e);
}
}
/**
* Throws a MemoryLimitException if the request couldn't allocate an {@code int} array of the given size.
*
* @param size The requested array size.
* @param count How many arrays to request.
* @return The input count.
* @throws Pack200Exception Thrown if the request is greater than the max.
* @since 1.29.0
*/
public static int checkIntArray(final int size, final int count) throws Pack200Exception {
try {
return checkIntArray(Math.multiplyExact(size, count));
} catch (final ArithmeticException e) {
throw new Pack200Exception("Can't allocate %,d int arrays of length %,d.", size, count);
}
}
/**
* Throws a MemoryLimitException if the request couldn't allocate an {@code Object} array of the given size.
*
* @param size The requested array size.
* @param objSize The object size.
* @return The array size.
* @throws Pack200Exception Thrown if the request is greater than the max.
* @since 1.29.0
*/
public static int checkObjectArray(final int size, final int objSize) throws Pack200Exception {
try {
MemoryLimitException.checkBytes(Math.multiplyExact(size, objSize), Runtime.getRuntime().freeMemory());
return size;
} catch (final MemoryLimitException | ArithmeticException e) {
throw new Pack200Exception("Can't allocate %,d Objects of size %,d.", size, objSize);
}
}
/**
* Throws a Pack200Exception if the given object is null.
*
* @param <T> The object type.
* @param obj The object to test.
* @param message The message format (which is saved for later retrieval by the {@link #getMessage()} method).
* @param args the format arguments to use.
* @return The given object.
* @throws Pack200Exception Thrown if {@code obj} is null.
* @since 1.29.0
*/
public static <T> T requireNonNull(final T obj, final String message, final Object... args) throws Pack200Exception {
if (obj == null) {
throw new Pack200Exception(message, args);
}
return obj;
}
/**
* Constructs an {@code Pack200Exception} with the specified detail message.
*
* @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method)
*/
public Pack200Exception(final String message) {
super(message);
}
/**
* Constructs a new exception with the specified detail message format and arguments. The cause is not initialized.
* <p>
* The arguments are used with {@link String#format(String, Object...)}.
* </p>
*
* @param message The message format (which is saved for later retrieval by the {@link #getMessage()} method).
* @param args the format arguments to use.
* @since 1.29.0
* @see String#format(String, Object...)
*/
public Pack200Exception(final String message, final Object... args) {
super(message, args);
}
/**
* Constructs an {@code Pack200Exception} with the specified detail message and cause.
* <p>
* Note that the detail message associated with {@code cause} is <i>not</i> automatically incorporated into this exception's detail message.
* </p>
*
* @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method)
*
* @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that the cause
* is nonexistent or unknown.)
*
* @since 1.28.0
*/
public Pack200Exception(final String message, final Throwable cause) {
super(message, cause);
}
/**
* Constructs a {@code Pack200Exception} with the specified cause and a detail message.
*
* @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that the cause
* is nonexistent or unknown.)
* @since 1.29.0
*/
public Pack200Exception(final Throwable cause) {
super(cause);
}
}