Package com.subgraph.orchid.circuits

Source Code of com.subgraph.orchid.circuits.TorOutputStream

package com.subgraph.orchid.circuits;

import java.io.IOException;
import java.io.OutputStream;

import com.subgraph.orchid.RelayCell;
import com.subgraph.orchid.circuits.cells.RelayCellImpl;

public class TorOutputStream extends OutputStream {

  private final StreamImpl stream;
  private RelayCell currentOutputCell;
  private volatile boolean isClosed;
  private long bytesSent;

  TorOutputStream(StreamImpl stream) {
    this.stream = stream;
    this.bytesSent = 0;
  }

  private void flushCurrentOutputCell() {
    if(currentOutputCell != null && currentOutputCell.cellBytesConsumed() > RelayCell.HEADER_SIZE) {
      stream.waitForSendWindowAndDecrement();
      stream.getCircuit().sendRelayCell(currentOutputCell);
      bytesSent += (currentOutputCell.cellBytesConsumed() - RelayCell.HEADER_SIZE);
    }

    currentOutputCell = new RelayCellImpl(stream.getTargetNode(), stream.getCircuit().getCircuitId(),
        stream.getStreamId(), RelayCell.RELAY_DATA);
  }

  long getBytesSent() {
    return bytesSent;
  }

  @Override
  public synchronized void write(int b) throws IOException {
    checkOpen();
    if(currentOutputCell == null || currentOutputCell.cellBytesRemaining() == 0)
      flushCurrentOutputCell();
    currentOutputCell.putByte(b);   
  }

  public synchronized void write(byte[] data, int offset, int length) throws IOException {
    checkOpen();
    if(currentOutputCell == null || currentOutputCell.cellBytesRemaining() == 0)
      flushCurrentOutputCell();

    while(length > 0) {
      if(length < currentOutputCell.cellBytesRemaining()) {
        currentOutputCell.putByteArray(data, offset, length);
        return;
      }
      final int writeCount = currentOutputCell.cellBytesRemaining();
      currentOutputCell.putByteArray(data, offset, writeCount);
      flushCurrentOutputCell();
      offset += writeCount;
      length -= writeCount;
    }
  }

  private void checkOpen() throws IOException {
    if(isClosed)
      throw new IOException("Output stream is closed");
  }

  public synchronized void flush() {
    if(isClosed)
      return;
    flushCurrentOutputCell();
  }

  public synchronized void close() {
    if(isClosed)
      return;
    flush();
    isClosed = true;
    currentOutputCell = null;
    stream.close();
  }

  public String toString() {
    return "TorOutputStream stream="+ stream.getStreamId() +" node="+ stream.getTargetNode();
  }
}
TOP

Related Classes of com.subgraph.orchid.circuits.TorOutputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.