com.distrimind.util.io.RandomByteArrayOutputStream.java Source code

Java tutorial

Introduction

Here is the source code for com.distrimind.util.io.RandomByteArrayOutputStream.java

Source

/*
 * MadKitLanEdition (created by Jason MAHDJOUB (jason.mahdjoub@distri-mind.fr)) Copyright (c)
 * 2015 is a fork of MadKit and MadKitGroupExtension. 
 * 
 * Copyright or  or Copr. Jason Mahdjoub, Fabien Michel, Olivier Gutknecht, Jacques Ferber (1997)
 * 
 * jason.mahdjoub@distri-mind.fr
 * fmichel@lirmm.fr
 * olg@no-distance.net
 * ferber@lirmm.fr
 * 
 * This software is a computer program whose purpose is to
 * provide a lightweight Java library for designing and simulating Multi-Agent Systems (MAS).
 * This software is governed by the CeCILL-C license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL-C
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 * 
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL-C license and that you accept its terms.
 */
package com.distrimind.util.io;

import org.bouncycastle.util.Arrays;

import java.io.IOException;

/**
 * 
 * @author Jason Mahdjoub
 * @version 1.0
 * @since Utils 3.27.0
 */
public class RandomByteArrayOutputStream extends RandomOutputStream {
    byte[] bytes;
    private int current_pos;
    int length;
    static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    public RandomByteArrayOutputStream(byte[] _bytes) {
        bytes = _bytes;
        current_pos = 0;
        length = _bytes.length;
    }

    public RandomByteArrayOutputStream() {
        bytes = new byte[0];
        current_pos = 0;
        length = 0;
    }

    public RandomByteArrayOutputStream(int length) {
        if (length < 0)
            throw new IllegalArgumentException("length must can't be negative");
        bytes = new byte[length];
        current_pos = 0;
        this.length = length;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public void write(int b) throws IOException {
        if (current_pos == -1)
            throw new IOException("The current RandomByteArrayOutputStream is closed !");
        ensureAdditionalLength(1);
        bytes[current_pos++] = (byte) b;
        length = Math.max(length, current_pos);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public void write(byte[] _bytes) throws IOException {
        write(_bytes, 0, _bytes.length);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public void write(byte[] _bytes, int _offset, int _length) throws IOException {
        if (current_pos == -1)
            throw new IOException("The current RandomByteArrayOutputStream is closed !");
        if (_bytes == null)
            throw new NullPointerException("_bytes");
        if (_length > _bytes.length)
            throw new IllegalArgumentException("_length must be greater than _bytes.length !");
        ensureAdditionalLength(_length);
        System.arraycopy(_bytes, _offset, bytes, current_pos, _length);
        current_pos += _length;
        length = Math.max(length, current_pos);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public long length() throws IOException {
        if (current_pos == -1)
            throw new IOException("The current RandomByteArrayOutputStream is closed !");
        return length;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public void setLength(long _length) throws IOException {
        if (current_pos == -1)
            throw new IOException("The current RandomByteArrayOutputStream is closed !");

        if (_length < 0 || _length > MAX_ARRAY_SIZE)
            throw new IllegalArgumentException("invalid length : " + _length);
        int length = (int) _length;
        if (bytes.length < length || bytes.length > _length * 3) {
            byte[] prev = bytes;
            bytes = new byte[length];
            if (this.length != 0) {
                System.arraycopy(prev, 0, bytes, 0, Math.min(this.length, length));
            }
        }

        this.length = length;
        current_pos = Math.min(length, current_pos);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public void seek(long _pos) throws IOException {
        if (current_pos == -1)
            throw new IOException("The current RandomByteArrayOutputStream is closed !");
        if (_pos < 0 || _pos > length())
            throw new IllegalArgumentException("" + _pos + " is not in [0," + length() + "]");

        current_pos = (int) _pos;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public long currentPosition() {
        return current_pos;
    }

    @Override
    public boolean isClosed() {
        return current_pos == -1;
    }

    @Override
    protected RandomByteArrayInputStream getRandomInputStreamImpl() {
        return new RandomByteArrayInputStream(this);
    }

    public byte[] getBytes() {
        return Arrays.copyOf(bytes, length);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public void close() {
        current_pos = -1;
    }

    private void ensureAdditionalLength(int l) throws IOException {
        l = this.current_pos + l;
        if (l > MAX_ARRAY_SIZE)
            throw new IOException("invalid length : " + length);

        if (bytes.length < l) {
            int length = (int) Math.min(2L * l, MAX_ARRAY_SIZE);
            byte[] prev = bytes;
            bytes = new byte[length];
            if (this.length != 0) {
                System.arraycopy(prev, 0, bytes, 0, this.length);
            }
        }
    }

}