    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 */
    019package org.apache.commons.compress;
    020
    021/**
    022 * If a stream checks for estimated memory allocation, and the estimate goes above the memory limit, this is thrown. This can also be thrown if a stream tries
    023 * to allocate a byte array that is larger than the allowable limit.
    024 *
    025 * @since 1.14
    026 */
    027public class MemoryLimitException extends CompressException {
    028
    029    private static final long serialVersionUID = 1L;
    030
    031    private static String buildMessage(final long memoryNeededInKb, final int memoryLimitInKb) {
    032        return String.format("%,d KiB of memory would be needed; limit was %,d KiB. If the file is not corrupt, consider increasing the memory limit.",
    033                memoryNeededInKb, memoryLimitInKb);
    034    }
    035
    036    /** A long instead of int to account for overflow for corrupt files. */
    037    private final long memoryNeededKiB;
    038    private final int memoryLimitKiB;
    039
    040    /**
    041     * Constructs a new instance.
    042     *
    043     * @param memoryNeededKiB The memory needed in kibibytes (KiB).
    044     * @param memoryLimitKiB  The memory limit in kibibytes (KiB).
    045     */
    046    public MemoryLimitException(final long memoryNeededKiB, final int memoryLimitKiB) {
    047        super(buildMessage(memoryNeededKiB, memoryLimitKiB));
    048        this.memoryNeededKiB = memoryNeededKiB;
    049        this.memoryLimitKiB = memoryLimitKiB;
    050    }
    051
    052    /**
    053     * Constructs a new instance.
    054     *
    055     * @param memoryNeededKiB The memory needed in kibibytes (KiB).
    056     * @param memoryLimitKiB  The memory limit in kibibytes (KiB).
    057     * @param cause            The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that
    058     *                         the cause is nonexistent or unknown.)
    059     * @deprecated Use {@link #MemoryLimitException(long, int, Throwable)}.
    060     */
    061    @Deprecated
    062    public MemoryLimitException(final long memoryNeededKiB, final int memoryLimitKiB, final Exception cause) {
    063        super(buildMessage(memoryNeededKiB, memoryLimitKiB), cause);
    064        this.memoryNeededKiB = memoryNeededKiB;
    065        this.memoryLimitKiB = memoryLimitKiB;
    066    }
    067
    068    /**
    069     * Constructs a new instance.
    070     *
    071     * @param memoryNeededKiB The memory needed in kibibytes (KiB).
    072     * @param memoryLimitKiB  The memory limit in kibibytes (KiB).
    073     * @param cause            The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that
    074     *                         the cause is nonexistent or unknown.)
    075     */
    076    public MemoryLimitException(final long memoryNeededKiB, final int memoryLimitKiB, final Throwable cause) {
    077        super(buildMessage(memoryNeededKiB, memoryLimitKiB), cause);
    078        this.memoryNeededKiB = memoryNeededKiB;
    079        this.memoryLimitKiB = memoryLimitKiB;
    080    }
    081
    082    /**
    083     * Gets the memory limit in kibibytes (KiB).
    084     *
    085     * @return the memory limit in kibibytes (KiB).
    086     */
    087    public int getMemoryLimitInKb() {
    088        return memoryLimitKiB;
    089    }
    090
    091    /**
    092     * Gets the memory needed in kibibytes (KiB).
    093     *
    094     * @return the memory needed in kibibytes (KiB).
    095     */
    096    public long getMemoryNeededInKb() {
    097        return memoryNeededKiB;
    098    }
    099}