com.aoindustries.aoserv.client.NestedInputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aoserv-client Show documentation
Show all versions of aoserv-client Show documentation
Java client for the AOServ Platform.
/*
* aoserv-client - Java client for the AOServ Platform.
* Copyright (C) 2002-2009, 2016, 2017, 2018, 2019, 2020 AO Industries, Inc.
* [email protected]
* 7262 Bull Pen Cir
* Mobile, AL 36695
*
* This file is part of aoserv-client.
*
* aoserv-client is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* aoserv-client 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with aoserv-client. If not, see .
*/
package com.aoindustries.aoserv.client;
import com.aoindustries.aoserv.client.schema.AoservProtocol;
import com.aoindustries.io.stream.StreamableInput;
import com.aoindustries.util.BufferManager;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
/**
* A NestedInputStream
reads data from
* within a StreamableInput
as if it were
* a separate stream. The underlying StreamableInput
* is never closed, allowing it to be used for multiple
* nested streams.
*
* @author AO Industries, Inc.
*/
public final class NestedInputStream extends InputStream {
final private StreamableInput in;
private boolean isDone=false;
private byte[] buffer=BufferManager.getBytes();
private int bufferFilled=0;
private int bufferRead=0;
public NestedInputStream(StreamableInput in) {
this.in=in;
}
@Override
synchronized public int available() {
return bufferRead-bufferFilled;
}
private void loadNextBlock() throws IOException {
// Load the next block, if needed
while(!isDone && bufferRead>=bufferFilled) {
int code=in.read();
if(code==AoservProtocol.NEXT) {
bufferFilled=in.readShort();
in.readFully(buffer, 0, bufferFilled);
bufferRead=0;
} else {
isDone=true;
bufferFilled=bufferRead=0;
try {
AoservProtocol.checkResult(code, in);
} catch(SQLException err) {
throw new IOException(err.toString());
}
}
}
}
@Override
synchronized public void close() throws IOException {
if(!isDone) {
// Read the rest of the underlying stream
int code;
while((code=in.read())==AoservProtocol.NEXT) {
int len=in.readShort();
while(len>0) {
int skipped=(int)in.skip(len);
len-=skipped;
}
}
isDone=true;
bufferFilled=bufferRead=0;
if(buffer!=null) {
BufferManager.release(buffer, false);
buffer=null;
}
try {
AoservProtocol.checkResult(code, in);
} catch(SQLException err) {
throw new IOException(err.toString());
}
}
}
@Override
synchronized public int read() throws IOException {
if(isDone) return -1;
loadNextBlock();
if(isDone) return -1;
return ((int)buffer[bufferRead++])&0xff;
}
@Override
synchronized public int read(byte[] b, int off, int len) throws IOException {
if(isDone) return -1;
loadNextBlock();
if(isDone) return -1;
int bufferLeft=bufferFilled-bufferRead;
if(bufferLeft>len) bufferLeft=len;
System.arraycopy(buffer, bufferRead, b, off, bufferLeft);
bufferRead+=bufferLeft;
return bufferLeft;
}
@Override
synchronized public long skip(long n) throws IOException {
if(isDone) return -1;
loadNextBlock();
if(isDone) return -1;
int bufferLeft=bufferFilled-bufferRead;
if(bufferLeft>n) bufferLeft=(int)n;
bufferRead+=bufferLeft;
return bufferLeft;
}
/**
* @deprecated The finalization mechanism is inherently problematic.
*/
@Deprecated // Java 9: (since="9")
@Override
protected void finalize() throws Throwable {
if(buffer!=null) {
BufferManager.release(buffer, false);
buffer=null;
}
super.finalize();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy