/**
* Copyright (c) 2011-2014, OpenIoT
*
* This file is part of OpenIoT.
*
* OpenIoT 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, version 3 of the License.
*
* OpenIoT 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 OpenIoT. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: OpenIoT mailto: info@openiot.eu
* @author Timotee Maret
*/
package org.openiot.gsn.http.datarequest;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ArrayBlockingQueue;
public class OutputInputStream {
private OISInputStream oisi = null;
private OISOutputStream oiso = null;
private boolean oisiClosed = false;
private boolean oisoClosed = false;
private ArrayBlockingQueue<Integer> circularBuffer = null;
public OutputInputStream (int bufferSize) {
circularBuffer = new ArrayBlockingQueue<Integer> (bufferSize) ;
}
public void close () throws IOException {
synchronized (this) {
if (oisi != null && ! oisiClosed) oisi.close();
if (oiso != null && ! oisoClosed) oiso.close();
circularBuffer = null;
// System.out.println("OutputInputStream >" + this + "< has been closed");
}
}
public InputStream getInputStream () {
if (oisi == null) oisi = new OISInputStream () ;
return oisi;
}
public OutputStream getOutputStream () {
if (oiso == null) oiso = new OISOutputStream () ;
return oiso;
}
private class OISOutputStream extends OutputStream {
@Override
public void write(int b) throws IOException {
if (oisoClosed) throw new IOException("Outputstream is closed");
try {
circularBuffer.put(b);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void close () throws IOException {
synchronized (OutputInputStream.this) {
oisoClosed = true;
// System.out.println("OISOutputStream >" + this + " has been closed<");
if (oisiClosed) OutputInputStream.this.close();
}
}
}
private class OISInputStream extends InputStream {
@Override
public int read() throws IOException {
if (oisiClosed) throw new IOException("InputStream has been closed");
int nextValue = -1;
try {
if ( ! oisoClosed) {
nextValue = circularBuffer.take();
}
else {
nextValue = available() > 0 ? circularBuffer.take() : -1 ;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return nextValue;
}
@Override
public int read (byte[] b) throws IOException {
if (oisiClosed) throw new IOException("InputStream has been closed");
if (b == null || b.length == 0) return 0;
int available = available () ;
if (available == 0) {
if (oisoClosed) return -1;
else {
try {
b[0] = circularBuffer.take().byteValue(); // TODO
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}
}
else {
int dataLength = Math.min(available, b.length);
for (int i = 0 ; i < dataLength ; i++) {
try {
b[i] = circularBuffer.take().byteValue(); // TODO
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return dataLength;
}
}
@Override
public void close() throws IOException {
synchronized (OutputInputStream.this) {
oisiClosed = true;
// System.out.println("OISInputStream >" + this + " has been closed<");
OutputInputStream.this.close();
}
}
@Override
public int available () {
int available = 0;
synchronized (circularBuffer) {
available = circularBuffer.size();
}
return available;
}
}
public static void main (String[] args) {
final OutputInputStream ois = new OutputInputStream (4) ;
new Thread(
new Runnable () {
public void run () {
try {
ois.getOutputStream().write("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes());
ois.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
).start();
InputStream is = ois.getInputStream();
int nextValue = -1;
try {
while ((nextValue = is.read()) != -1) {
System.out.println("read: " + nextValue);
}
ois.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}