All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.imaging.common.Allocator Maven / Gradle / Ivy

/*
 * 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
 *
 *      http://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.imaging.common;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.function.IntFunction;

/**
 * Checks inputs for meeting allocation limits and allocates arrays.
 */
public class Allocator {

    private static final String CANONICAL_NAME = Allocator.class.getCanonicalName();

    /** One GB. */
    private static final int DEFAULT = 1_073_741_824;
    private static final int LIMIT;

    static {
        LIMIT = Integer.getInteger(CANONICAL_NAME, DEFAULT);
    }

    /**
     * Allocates an Object of type T of the requested size.
     *
     * @param      The return array type
     * @param request The requested size.
     * @param factory The array factory.
     * @return a new byte array.
     * @throws AllocationRequestException Thrown when the request exceeds the limit.
     * @see #check(int)
     */
    public static  T apply(final int request, final IntFunction factory) {
        return factory.apply(check(request));
    }

    /**
     * Allocates an array of type T of the requested size.
     *
     * @param                 The return array type
     * @param request            The requested size.
     * @param factory            The array factory.
     * @param eltShallowByteSize The shallow byte size of an element.
     * @return a new byte array.
     * @throws AllocationRequestException Thrown when the request exceeds the limit.
     * @see #check(int)
     */
    public static  T[] array(final int request, final IntFunction factory, final int eltShallowByteSize) {
        check(request * eltShallowByteSize);
        return factory.apply(request);
    }

    /**
     * Allocates an Object array of type T of the requested size.
     *
     * @param      The return array type
     * @param request The requested size.
     * @return a new byte array.
     * @throws AllocationRequestException Thrown when the request exceeds the limit.
     * @see #check(int)
     */
    public static  ArrayList arrayList(final int request) {
        check(24 + request * 4); // 4 bytes per element
        return apply(request, ArrayList::new);
    }

    /**
     * Allocates a byte array of the requested size.
     *
     * @param request The requested size.
     * @return a new byte array.
     * @throws AllocationRequestException Thrown when the request exceeds the limit.
     * @see #check(int, int)
     */
    public static byte[] byteArray(final int request) {
        return new byte[checkByteArray(request)];
    }

    /**
     * Allocates a byte array of the requested size.
     *
     * @param request The requested size is cast down to an int.
     * @return a new byte array.
     * @throws AllocationRequestException Thrown when the request exceeds the limit.
     * @see #check(int, int)
     */
    public static byte[] byteArray(final long request) {
        return new byte[check(request, Byte.BYTES)];
    }

    /**
     * Allocates a char array of the requested size.
     *
     * @param request The requested size.
     * @return a new char array.
     * @throws AllocationRequestException Thrown when the request exceeds the limit.
     * @see #check(int, int)
     */
    public static char[] charArray(final int request) {
        return new char[check(request, Character.BYTES)];
    }

    /**
     * Checks a request for meeting allocation limits.
     * 

* The default limit is {@value #DEFAULT}, override with the system property "org.apache.commons.imaging.common.mylzw.AllocationChecker". *

* * @param request an allocation request. * @return the request. * @throws AllocationRequestException Thrown when the request exceeds the limit. */ public static int check(final int request) { if (request > LIMIT) { throw new AllocationRequestException(LIMIT, request); } return request; } /** * Checks a request for meeting allocation limits. *

* The default limit is {@value #DEFAULT}, override with the system property "org.apache.commons.imaging.common.mylzw.AllocationChecker". *

* * @param request an allocation request count. * @param elementSize The element size. * @return the request. * @throws AllocationRequestException Thrown when the request exceeds the limit. */ public static int check(final int request, final int elementSize) { int multiplyExact; try { multiplyExact = Math.multiplyExact(request, elementSize); } catch (final ArithmeticException e) { throw new AllocationRequestException(LIMIT, BigInteger.valueOf(request).multiply(BigInteger.valueOf(elementSize)), e); } if (multiplyExact > LIMIT) { throw new AllocationRequestException(LIMIT, request); } return request; } /** * Checks a request for meeting allocation limits. *

* The default limit is {@value #DEFAULT}, override with the system property "org.apache.commons.imaging.common.mylzw.AllocationChecker". *

* * @param request an allocation request count is cast down to an int. * @param elementSize The element size. * @return the request. * @throws AllocationRequestException Thrown when the request exceeds the limit. */ public static int check(final long request, final int elementSize) { try { return check(Math.toIntExact(request), elementSize); } catch (final ArithmeticException e) { throw new AllocationRequestException(LIMIT, request, e); } } /** * Checks that allocating a byte array of the requested size is within the limit. * * @param request The byte array size. * @return The input request. */ public static int checkByteArray(final int request) { return check(request, Byte.BYTES); } /** * Allocates a double array of the requested size. * * @param request The requested size. * @return a new double array. * @throws AllocationRequestException Thrown when the request exceeds the limit. * @see #check(int, int) */ public static double[] doubleArray(final int request) { return new double[check(request, Double.BYTES)]; } /** * Allocates a float array of the requested size. * * @param request The requested size. * @return a new float array. * @throws AllocationRequestException Thrown when the request exceeds the limit. * @see #check(int, int) */ public static float[] floatArray(final int request) { return new float[check(request, Float.BYTES)]; } /** * Allocates a int array of the requested size. * * @param request The requested size. * @return a new int array. * @throws AllocationRequestException Thrown when the request exceeds the limit. * @see #check(int, int) */ public static int[] intArray(final int request) { return new int[check(request, Integer.BYTES)]; } /** * Allocates a long array of the requested size. * * @param request The requested size. * @return a new long array. * @throws AllocationRequestException Thrown when the request exceeds the limit. * @see #check(int, int) */ public static long[] longArray(final int request) { return new long[check(request, Long.BYTES)]; } /** * Allocates a short array of the requested size. * * @param request The requested size. * @return a new short array. * @throws AllocationRequestException Thrown when the request exceeds the limit. * @see #check(int, int) */ public static short[] shortArray(final int request) { return new short[check(request, Short.BYTES)]; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy