001/**
002 *   Copyright (C) 2015 Typesafe Inc. <http://typesafe.com>
003 */
004package com.typesafe.config;
005
006import java.math.BigInteger;
007
008/**
009 * An immutable class representing an amount of memory.  Use
010 * static factory methods such as {@link
011 * ConfigMemorySize#ofBytes(BigInteger)} to create instances.
012 *
013 * @since 1.3.0
014 */
015public final class ConfigMemorySize {
016
017    private BigInteger bytes;
018
019    private ConfigMemorySize(BigInteger bytes) {
020        if (bytes.signum() < 0)
021            throw new IllegalArgumentException("Attempt to construct ConfigMemorySize with negative number: " + bytes);
022        this.bytes = bytes;
023    }
024
025    /**
026     * Constructs a ConfigMemorySize representing the given
027     * number of bytes.
028     * @since 1.3.0
029     * @param bytes a number of bytes
030     * @return an instance representing the number of bytes
031     */
032    public static ConfigMemorySize ofBytes(BigInteger bytes) {
033        return new ConfigMemorySize(bytes);
034    }
035
036    /**
037     * Constructs a ConfigMemorySize representing the given
038     * number of bytes.
039     * @param bytes a number of bytes
040     * @return an instance representing the number of bytes
041     */
042    public static ConfigMemorySize ofBytes(long bytes) {
043        return new ConfigMemorySize(BigInteger.valueOf(bytes));
044    }
045
046    /**
047     * Gets the size in bytes.
048     *
049     * @since 1.3.0
050     * @return how many bytes
051     * @exception IllegalArgumentException when memory value
052     * in bytes doesn't fit in a long value. Consider using
053     * {@link #toBytesBigInteger} in this case.
054     */
055    public long toBytes() {
056        if (bytes.bitLength() < 64)
057            return bytes.longValue();
058        else
059            throw new IllegalArgumentException(
060                "size-in-bytes value is out of range for a 64-bit long: '" + bytes + "'");
061    }
062
063    /**
064     * Gets the size in bytes. The behavior of this method
065     * is the same as that of the {@link #toBytes()} method,
066     * except that the number of bytes returned as a
067     * BigInteger value. Use it when memory value in bytes
068     * doesn't fit in a long value.
069     * @return how many bytes
070     */
071    public BigInteger toBytesBigInteger() {
072        return bytes;
073    }
074
075    @Override
076    public String toString() {
077        return "ConfigMemorySize(" + bytes + ")";
078    }
079
080    @Override
081    public boolean equals(Object other) {
082        if (other instanceof ConfigMemorySize) {
083            return ((ConfigMemorySize)other).bytes.equals(this.bytes);
084        } else {
085            return false;
086        }
087    }
088
089    @Override
090    public int hashCode() {
091        // in Java 8 this can become Long.hashCode(bytes)
092        return bytes.hashCode();
093    }
094
095}
096