com.mysql.cj.protocol.x.ContinuousInputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mysql-connector-j Show documentation
Show all versions of mysql-connector-j Show documentation
JDBC Type 4 driver for MySQL.
The newest version!
/*
* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by
* the Free Software Foundation.
*
* This program is designed to work with certain software that is licensed under separate terms, as designated in a particular file or component or in
* included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the
* separately licensed software that they have either included with the program or referenced in the documentation.
*
* Without limiting anything contained in the foregoing, this file, which is part of MySQL Connector/J, is also subject to the Universal FOSS Exception,
* version 1.0, a copy of which can be found at http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.mysql.cj.protocol.x;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Queue;
/**
* An {@link InputStream} wrapper that reads from a queue of underlying {@link InputStream}s, giving the impression that all data is coming from a single,
* continuous, source.
*/
public class ContinuousInputStream extends FilterInputStream {
private Queue inputStreams = new LinkedList<>();
private boolean closed = false;
protected ContinuousInputStream(InputStream in) {
super(in);
}
/**
* Returns the number of bytes available in the active underlying {@link InputStream}.
*
* @return the number of bytes available.
* @see FilterInputStream#available()
*/
@Override
public int available() throws IOException {
ensureOpen();
int available = super.available();
if (available == 0 && nextInLine()) {
return available();
}
return available;
}
/**
* Closes this stream and all underlying {@link InputStream}s.
*
* @see FilterInputStream#close()
*/
@Override
public void close() throws IOException {
if (!this.closed) {
this.closed = true;
super.close();
for (InputStream is : this.inputStreams) {
is.close();
}
}
}
/**
* Reads one byte from the underlying {@link InputStream}. When EOF is reached, then reads from the next {@link InputStream} in the queue.
*
* @see FilterInputStream#read()
*/
@Override
public int read() throws IOException {
ensureOpen();
int read = super.read();
if (read >= 0) {
return read;
}
if (nextInLine()) {
return read();
}
return read;
}
/**
* Forwards the read to {@link #read(byte[], int, int)}.
*
* @see FilterInputStream#read(byte[])
*/
@Override
public int read(byte[] b) throws IOException {
ensureOpen();
return read(b, 0, b.length);
}
/**
* Reads bytes from the underlying {@link InputStream}. When EOF is reached, then reads from the next {@link InputStream} in the queue.
*
* @see FilterInputStream#read(byte[], int, int)
*/
@Override
public int read(byte[] b, int off, int len) throws IOException {
ensureOpen();
int toRead = Math.min(len, available());
int read = super.read(b, off, toRead);
if (read > 0) {
return read;
}
if (nextInLine()) {
return read(b, off, len);
}
return read;
}
/**
* Adds another {@link InputStream} to the {@link InputStream}s queue.
*
* @param newIn
* the {@link InputStream} to add.
* @return
* true
if the element was added to the {@link InputStream}s queue.
*/
protected boolean addInputStream(InputStream newIn) {
return this.inputStreams.offer(newIn);
}
/**
* Closes the currently active {@link InputStream} and replaces it by the the head of the {@link InputStream}s queue.
*
* @return
* true
if the currently active {@link InputStream} was replaced by a new one.
* @throws IOException
* if errors occur while closing the currently active {@link InputStream}.
*/
private boolean nextInLine() throws IOException {
InputStream nextInputStream = this.inputStreams.poll();
if (nextInputStream != null) {
super.close();
this.in = nextInputStream;
return true;
}
return false;
}
/**
* Ensures that this {@link InputStream} wasn't closed yet.
*
* @throws IOException
* if this {@link InputStream} was closed.
*/
private void ensureOpen() throws IOException {
if (this.closed) {
throw new IOException("Stream closed");
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy