/**
* OnionCoffee - Anonymous Communication through TOR Network
* Copyright (C) 2005-2007 RWTH Aachen University, Informatik IV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package TorJava;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import TorJava.Common.Encoding;
/**
*
* @author Lexi Pimenidis
*/
class TCPStreamOutputStream extends OutputStream {
TCPStream stream;
PipedOutputStream sout; // read from this, and forward to tor
PipedInputStream fromjava; // private end of this pipe
boolean stopped; // as stop() is depreacated we use this toggle variable
byte[] buffer;
int bufferFilled;
TCPStreamOutputStream(TCPStream stream) {
this.stream = stream;
buffer = new byte[CellRelay.RELAY_DATA_SIZE];
bufferFilled = 0;
try {
sout = new PipedOutputStream();
fromjava = new PipedInputStream(sout);
} catch (IOException e) {
Logger.logStream(Logger.ERROR,
"TCPStreamThreadJava2Tor: caught IOException "
+ e.getMessage());
}
}
public void close() {
this.stopped = true;
}
public void write(int b)
throws IOException
{
write(Encoding.intToNByteArray(b,4));
}
public synchronized void flush()
throws IOException
{
if (stopped)
throw new IOException("TCPStreamOutputStream.flush(): output closed");
if (bufferFilled<1) return;
if (bufferFilled>buffer.length)
throw new IOException("TCPStreamOutputStream.flush(): there must be an error somewhere else");
CellRelayData cell = new CellRelayData(stream);
cell.length = bufferFilled;
if (cell.length > cell.data.length)
cell.length = cell.data.length;
System.arraycopy(buffer,0, cell.data,0, bufferFilled);
stream.send_cell(cell);
bufferFilled=0;
}
public void write(byte[] b,int off,int len)
throws IOException
{
if (len==0) return;
/*if (len<0) throw new IOException("TCPStreamOutputStream.write(): len = "+len);
if (bufferFilled > buffer.length) throw new IOException("TCPStreamOutputStream.write(): filled = "+bufferFilled); */
int bytesFree = buffer.length;
if (bufferFilled == buffer.length)
flush();
else
bytesFree = buffer.length-bufferFilled;
if(len>bytesFree) {
write(b,off,bytesFree);
write(b,off+bytesFree,len-bytesFree);
} else {
System.arraycopy(b,off, buffer, bufferFilled,len);
bufferFilled+=len;
if (bufferFilled==buffer.length) flush();
};
}
public void write(byte[] b)
throws IOException
{
write(b,0,b.length);
}
}