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

com.helger.commons.io.stream.NonBlockingByteArrayInputStream Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014-2024 Philip Helger (www.helger.com)
 * philip[at]helger[dot]com
 *
 * Licensed 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 com.helger.commons.io.stream;

import java.io.InputStream;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.collection.ArrayHelper;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
 * A non-synchronized copy of the class {@link java.io.ByteArrayInputStream}.
 *
 * @author Philip Helger
 * @see java.io.ByteArrayInputStream
 */
public class NonBlockingByteArrayInputStream extends InputStream
{
  public static final boolean DEFAULT_COPY_NEEDED = false;

  /**
   * An array of bytes that was provided by the creator of the stream. Elements
   * buf[0] through buf[count-1] are the only bytes
   * that can ever be read from the stream; element buf[pos] is the
   * next byte to be read.
   */
  protected byte [] m_aBuf;

  /**
   * The index of the next character to read from the input stream buffer. This
   * value should always be nonnegative and not larger than the value of
   * count. The next byte to be read from the input stream buffer
   * will be buf[pos].
   */
  protected int m_nPos;

  /**
   * The currently marked position in the stream.
   * NonBlockingByteArrayInputStream objects are marked at position zero by
   * default when constructed. They may be marked at another position within the
   * buffer by the mark() method. The current buffer position is
   * set to this point by the reset() method.
   * 

* If no mark has been set, then the value of mark is the offset passed to the * constructor (or 0 if the offset was not supplied). */ protected int m_nMark; /** * The index one greater than the last valid character in the input stream * buffer. This value should always be nonnegative and not larger than the * length of buf. It is one greater than the position of the last * byte within buf that can ever be read from the input stream * buffer. */ protected int m_nCount; private final boolean m_bIsCopy; /** * Creates a NonBlockingByteArrayInputStream so that it uses * buf as its buffer array. The buffer array is not copied. The * initial value of pos is 0 and the initial value * of count is the length of buf. * * @param aBuf * the input buffer. */ public NonBlockingByteArrayInputStream (@Nonnull final byte [] aBuf) { this (aBuf, 0, aBuf.length, DEFAULT_COPY_NEEDED); } /** * Creates a NonBlockingByteArrayInputStream so that it uses * buf as its buffer array. The buffer array is not copied. The * initial value of pos is 0 and the initial value * of count is the length of buf. * * @param aBuf * the input buffer. * @param bIsCopyNeeded * true if the array should be copied, false * if not. */ public NonBlockingByteArrayInputStream (@Nonnull final byte [] aBuf, final boolean bIsCopyNeeded) { this (aBuf, 0, aBuf.length, bIsCopyNeeded); } /** * Creates NonBlockingByteArrayInputStream that uses * aBuf as its buffer array. The initial value of * nOfs is offset and the initial value of * m_nCount is the minimum of nOfs+nLen and * aBuf.length. The buffer array is not copied. The buffer's mark * is set to the specified offset. * * @param aBuf * the input buffer. * @param nOfs * the offset in the buffer of the first byte to read. * @param nLen * the maximum number of bytes to read from the buffer. */ public NonBlockingByteArrayInputStream (@Nonnull final byte [] aBuf, @Nonnegative final int nOfs, @Nonnegative final int nLen) { this (aBuf, nOfs, nLen, DEFAULT_COPY_NEEDED); } /** * Creates NonBlockingByteArrayInputStream that uses * aBuf as its buffer array. The initial value of * nOfs is offset and the initial value of * m_nCount is the minimum of nOfs+nLen and * aBuf.length. The buffer's mark is set to the specified offset. * * @param aBuf * the input buffer. * @param nOfs * the offset in the buffer of the first byte to read. * @param nLen * the maximum number of bytes to read from the buffer. * @param bIsCopyNeeded * true if the provided byte array needs to be copied, * false if not. */ @SuppressFBWarnings ({ "EI_EXPOSE_REP2" }) public NonBlockingByteArrayInputStream (@Nonnull final byte [] aBuf, @Nonnegative final int nOfs, @Nonnegative final int nLen, final boolean bIsCopyNeeded) { ValueEnforcer.isArrayOfsLen (aBuf, nOfs, nLen); m_aBuf = bIsCopyNeeded ? ArrayHelper.getCopy (aBuf, nOfs, nLen) : aBuf; m_nPos = bIsCopyNeeded ? 0 : nOfs; m_nCount = bIsCopyNeeded ? nLen : Math.min (nOfs + nLen, aBuf.length); m_nMark = m_nPos; m_bIsCopy = bIsCopyNeeded; } public final boolean isCopy () { return m_bIsCopy; } /** * Reads the next byte of data from this input stream. The value byte is * returned as an int in the range 0 to * 255. If no byte is available because the end of the stream has * been reached, the value -1 is returned. *

* This read method cannot block. * * @return the next byte of data, or -1 if the end of the stream * has been reached. */ @Override public int read () { if (m_nPos >= m_nCount) return -1; final int ret = m_aBuf[m_nPos] & 0xff; m_nPos++; return ret; } /** * Reads up to len bytes of data into an array of bytes from this * input stream. If pos equals count, then * -1 is returned to indicate end of file. Otherwise, the number * k of bytes read is equal to the smaller of len * and count-pos. If k is positive, then bytes * buf[pos] through buf[pos+k-1] are copied into * b[off] through b[off+k-1] in the manner performed * by System.arraycopy. The value k is added into * pos and k is returned. *

* This read method cannot block. * * @param aBuf * the buffer into which the data is read. * @param nOfs * the start offset in the destination array b * @param nLen * the maximum number of bytes read. * @return the total number of bytes read into the buffer, or -1 * if there is no more data because the end of the stream has been * reached. */ @Override public int read (final byte [] aBuf, final int nOfs, final int nLen) { ValueEnforcer.isArrayOfsLen (aBuf, nOfs, nLen); if (m_nPos >= m_nCount) return -1; final int nRealLen = m_nPos + nLen > m_nCount ? m_nCount - m_nPos : nLen; if (nRealLen <= 0) return 0; System.arraycopy (m_aBuf, m_nPos, aBuf, nOfs, nRealLen); m_nPos += nRealLen; return nRealLen; } /** * Skips n bytes of input from this input stream. Fewer bytes * might be skipped if the end of the input stream is reached. The actual * number k of bytes to be skipped is equal to the smaller of * n and count-pos. The value k is * added into pos and k is returned. * * @param n * the number of bytes to be skipped. * @return the actual number of bytes skipped. */ @Override public long skip (final long n) { final long nSkip = m_nPos + n > m_nCount ? m_nCount - m_nPos : n; if (nSkip <= 0) return 0; m_nPos += (int) nSkip; return nSkip; } /** * Returns the number of remaining bytes that can be read (or skipped over) * from this input stream. *

* The value returned is count - pos, which is the number of * bytes remaining to be read from the input buffer. * * @return the number of remaining bytes that can be read (or skipped over) * from this input stream without blocking. */ @Override public int available () { return m_nCount - m_nPos; } /** * Tests if this InputStream supports mark/reset. The * markSupported method of * NonBlockingByteArrayInputStream always returns * true. * * @return Always true */ @Override public boolean markSupported () { return true; } /** * Set the current marked position in the stream. * NonBlockingByteArrayInputStream objects are marked at position zero by * default when constructed. They may be marked at another position within the * buffer by this method. *

* If no mark has been set, then the value of the mark is the offset passed to * the constructor (or 0 if the offset was not supplied). *

* Note: The readAheadLimit for this class has no meaning. */ @SuppressWarnings ("sync-override") @Override public void mark (final int readAheadLimit) { m_nMark = m_nPos; } /** * Resets the buffer to the marked position. The marked position is 0 unless * another position was marked or an offset was specified in the constructor. */ @SuppressWarnings ("sync-override") @Override public void reset () { m_nPos = m_nMark; } /** * Closing a NonBlockingByteArrayInputStream has no effect. The * methods in this class can be called after the stream has been closed * without generating an IOException. */ @Override public void close () {} /** * @return The position where we are in the stream. */ @Nonnegative public int getPosition () { return m_nPos; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy