com.unboundid.scim.marshal.BulkInputStreamWrapper Maven / Gradle / Ivy
/*
* Copyright 2012-2019 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.scim.marshal;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicLong;
/**
* This class is a wrapper around an input stream that allows us to determine
* how many bytes have been read from the stream.
*/
public class BulkInputStreamWrapper extends FilterInputStream
{
// The number of bytes read from the stream.
private final AtomicLong bytesRead;
/**
* Creates a new instance of this input stream that wraps the provided
* stream.
*
* @param s The input stream to be wrapped.
*/
public BulkInputStreamWrapper(final InputStream s)
{
super(s);
bytesRead = new AtomicLong(0L);
}
/**
* Reads the next byte of data from the 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 method blocks
* until input data is available, the end of the stream is detected, or an
* exception is thrown.
*
* A subclass must provide an implementation of this method.
*
* @return the next byte of data, or -1
if the end of the stream
* is reached.
*
* @throws java.io.IOException if an I/O error occurs.
*/
@Override
public int read() throws IOException
{
int c = in.read();
if (c != -1)
{
bytesRead.incrementAndGet();
}
return c;
}
/**
* Reads some number of bytes from the input stream and stores them into the
* buffer array b
. The number of bytes actually read is returned
* as an integer. This method blocks until input data is available, end of
* file is detected, or an exception is thrown.
*
*
If the length of b
is zero, then no bytes are read and
* 0
is returned; otherwise, there is an attempt to read at least
* one byte. If no byte is available because the stream is at the end of the
* file, the value -1
is returned; otherwise, at least one byte
* is read and stored into b
.
*
*
The first byte read is stored into element b[0]
, the next
* one into b[1]
, and so on. The number of bytes read is, at
* most, equal to the length of b
. Let k be the number of
* bytes actually read; these bytes will be stored in elements
* b[0]
through b[
k-1]
, leaving
* elements b[
k]
through
* b[b.length-1]
unaffected.
*
*
The read(b)
method for class InputStream
* has the same effect as:
read(b, 0, b.length)
*
* @param b the buffer into which the data is read.
*
* @return the total number of bytes read into the buffer, or -1
* is there is no more data because the end of the stream has been
* reached.
*
* @throws java.io.IOException If the first byte cannot be read for any
* reason other than the end of the file, if the
* input stream has been closed, or if some other
* I/O error occurs.
* @see java.io.InputStream#read(byte[], int, int)
*/
@Override
public int read(final byte[] b) throws IOException
{
int n = in.read(b);
if (n != -1)
{
bytesRead.addAndGet(n);
}
return n;
}
/**
* Reads up to len
bytes of data from the input stream into an
* array of bytes. An attempt is made to read as many as len
* bytes, but a smaller number may be read. The number of bytes actually read
* is returned as an integer.
*
* This method blocks until input data is available, end of file is
* detected, or an exception is thrown.
*=
*
If len
is zero, then no bytes are read and 0
* is returned; otherwise, there is an attempt to read at least one byte. If
* no byte is available because the stream is at end of file, the value
* -1
is returned; otherwise, at least one byte is read and
* stored into b
.
*
*
The first byte read is stored into element b[off]
, the
* next one into b[off+1]
, and so on. The number of bytes read
* is, at most, equal to len
. Let k be the number of bytes
* actually read; these bytes will be stored in elements b[off]
* through b[off+
k-1]
, leaving elements
* b[off+
k]
through b[off+len-1]
* unaffected.
*
*
In every case, elements b[0]
through b[off]
* and elements b[off+len]
through b[b.length-1]
are
* unaffected.
*
*
The read(b,
off,
len)
method for
* class InputStream
simply calls the method read()
* repeatedly. If the first such call results in an IOException
,
* that exception is returned from the call to the read(b,
* off,
len)
method. If any subsequent call to
* read()
results in a IOException
, the exception is
* caught and treated as if it were end of file; the bytes read up to that
* point are stored into b
and the number of bytes read before
* the exception occurred is returned. The default implementation of this
* method blocks until the requested amount of input data len
has
* been read, end of file is detected, or an exception is thrown. Subclasses
* are encouraged to provide a more efficient implementation of this method.
*
* @param b the buffer into which the data is read.
* @param off the start offset in array b
at which the data is
* written.
* @param len the maximum number of bytes to 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.
*
* @throws java.io.IOException If the first byte cannot be read for any
* reason other than end of file, or if the
* input stream has been closed, or if some
* other I/O error occurs.
* @see java.io.InputStream#read()
*/
@Override
public int read(final byte[] b, final int off, final int len)
throws IOException
{
int n = in.read(b, off, len);
if (n != -1)
{
bytesRead.addAndGet(n);
}
return n;
}
/**
* Skips over and discards n
bytes of data from this input
* stream.
* The skip
method may, for a variety of reasons, end up skipping
* over some smaller number of bytes, possibly 0
. This may result
* from any of a number of conditions; reaching end of file before
* n
bytes have been skipped is only one possibility. The actual
* number of bytes skipped is returned. If n
is negative, no
* bytes are skipped.
*
*
* @param n the number of bytes to be skipped.
*
* @return the actual number of bytes skipped.
*
* @throws java.io.IOException if the stream does not support seek, or if some
* other I/O error occurs.
*/
@Override
public long skip(final long n) throws IOException
{
long skipped = in.skip(n);
bytesRead.addAndGet(skipped);
return n;
}
/**
* Retrieves the number of bytes read through this input stream.
*
* @return The number of bytes read through this input stream.
*/
public long getBytesRead()
{
return bytesRead.get();
}
}