354 lines
11 KiB
Java
354 lines
11 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*/
|
|
package com.tridium.fox.session;
|
|
|
|
import com.tridium.fox.message.FoxMessage;
|
|
import com.tridium.fox.message.MessageReader;
|
|
import com.tridium.fox.message.MessageWriter;
|
|
import com.tridium.fox.session.Fox;
|
|
import com.tridium.fox.session.FoxAsyncCallbacks;
|
|
import com.tridium.fox.session.FoxRequest;
|
|
import com.tridium.fox.session.FoxSession;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InterruptedIOException;
|
|
import java.io.OutputStream;
|
|
|
|
public class FoxCircuit {
|
|
private static final boolean TRACE = false;
|
|
public final int id;
|
|
public final String channel;
|
|
public final String command;
|
|
boolean open = true;
|
|
FoxSession session;
|
|
CircuitOutputStream out;
|
|
CircuitInputStream in;
|
|
Object outgoingLock = new Object();
|
|
byte[] outgoing = new byte[Fox.circuitChunkSize];
|
|
int nOutgoing;
|
|
Object incomingLock = new Object();
|
|
BufferEntry incomingHead = null;
|
|
BufferEntry incomingTail = null;
|
|
int nIncoming;
|
|
|
|
FoxCircuit(int n, FoxSession foxSession, String string, String string2) {
|
|
this.id = n;
|
|
this.session = foxSession;
|
|
this.channel = string;
|
|
this.command = string2;
|
|
this.out = new CircuitOutputStream();
|
|
this.in = new CircuitInputStream();
|
|
}
|
|
|
|
public boolean isOpen() {
|
|
return this.open;
|
|
}
|
|
|
|
public FoxSession session() {
|
|
return this.session;
|
|
}
|
|
|
|
public InputStream getInputStream() {
|
|
return this.in;
|
|
}
|
|
|
|
public OutputStream getOutputStream() {
|
|
return this.out;
|
|
}
|
|
|
|
public FoxMessage readMessage() throws Exception {
|
|
MessageReader messageReader = new MessageReader(this.in);
|
|
FoxMessage foxMessage = new FoxMessage();
|
|
foxMessage.readValue(messageReader);
|
|
return foxMessage;
|
|
}
|
|
|
|
public void writeMessage(FoxMessage foxMessage) throws Exception {
|
|
MessageWriter messageWriter = new MessageWriter(this.out);
|
|
foxMessage.writeValue(messageWriter);
|
|
messageWriter.flush();
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public FoxMessage write(byte[] byArray, int n, int n2, FoxAsyncCallbacks foxAsyncCallbacks) throws Exception {
|
|
if (foxAsyncCallbacks == null) {
|
|
this.out.write(byArray, n, n2);
|
|
return null;
|
|
}
|
|
Object object = this.outgoingLock;
|
|
synchronized (object) {
|
|
int n3;
|
|
this.flush();
|
|
byte[] byArray2 = new byte[n2];
|
|
System.arraycopy(byArray, n, byArray2, 0, n2);
|
|
FoxRequest foxRequest = null;
|
|
int n4 = n2;
|
|
for (int i = 0; i != n4; i += n3) {
|
|
int n5 = n4 - i;
|
|
foxRequest = this.sendStream(byArray2, i, n3, (n3 = Math.min(Fox.circuitChunkSize, n5)) == n5 ? foxAsyncCallbacks : null);
|
|
}
|
|
return foxRequest;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public void close() {
|
|
if (!this.open) {
|
|
return;
|
|
}
|
|
try {
|
|
this.flush();
|
|
}
|
|
catch (IOException iOException) {
|
|
// empty catch block
|
|
}
|
|
this.session.closeCircuit(this);
|
|
this.open = false;
|
|
Object object = this.incomingLock;
|
|
synchronized (object) {
|
|
this.incomingLock.notifyAll();
|
|
}
|
|
object = this.outgoingLock;
|
|
synchronized (object) {
|
|
this.outgoingLock.notifyAll();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
void writeOut(byte[] byArray, int n, int n2) throws IOException {
|
|
this.assertOpen();
|
|
Object object = this.outgoingLock;
|
|
synchronized (object) {
|
|
while (this.open && n2 > 0) {
|
|
int n3 = Math.min(this.outgoing.length - this.nOutgoing, n2);
|
|
System.arraycopy(byArray, n, this.outgoing, this.nOutgoing, n3);
|
|
this.nOutgoing += n3;
|
|
n += n3;
|
|
n2 -= n3;
|
|
if (this.nOutgoing < this.outgoing.length) continue;
|
|
this.flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
public void flush() throws IOException {
|
|
Object object = this.outgoingLock;
|
|
synchronized (object) {
|
|
if (this.open && this.nOutgoing > 0) {
|
|
try {
|
|
this.sendStream(this.outgoing, this.nOutgoing);
|
|
this.outgoing = new byte[Fox.circuitChunkSize];
|
|
this.nOutgoing = 0;
|
|
}
|
|
catch (IOException iOException) {
|
|
throw iOException;
|
|
}
|
|
catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
throw new IOException(exception.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
void pushIn(byte[] byArray) throws InterruptedException {
|
|
if (byArray.length == 0) {
|
|
return;
|
|
}
|
|
Object object = this.incomingLock;
|
|
synchronized (object) {
|
|
while (this.open && this.incomingHead != null && this.nIncoming + byArray.length > Fox.circuitMaxReceiveBuffer) {
|
|
this.incomingLock.wait();
|
|
}
|
|
BufferEntry bufferEntry = new BufferEntry(byArray);
|
|
if (this.incomingHead == null) {
|
|
this.incomingHead = bufferEntry;
|
|
}
|
|
if (this.incomingTail != null) {
|
|
this.incomingTail.next = bufferEntry;
|
|
}
|
|
this.incomingTail = bufferEntry;
|
|
this.nIncoming += byArray.length;
|
|
this.incomingLock.notifyAll();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* WARNING - Removed try catching itself - possible behaviour change.
|
|
*/
|
|
int pullIn(byte[] byArray, int n, int n2) throws IOException {
|
|
Object object = this.incomingLock;
|
|
synchronized (object) {
|
|
BufferEntry bufferEntry;
|
|
while (this.nIncoming <= 0) {
|
|
if (!this.open) {
|
|
return -1;
|
|
}
|
|
try {
|
|
this.incomingLock.wait();
|
|
}
|
|
catch (InterruptedException interruptedException) {
|
|
throw new InterruptedIOException();
|
|
}
|
|
}
|
|
int n3 = 0;
|
|
while (n2 > 0 && (bufferEntry = this.incomingHead) != null) {
|
|
int n4 = Math.min(bufferEntry.avail, n2);
|
|
System.arraycopy(bufferEntry.data, bufferEntry.data.length - bufferEntry.avail, byArray, n, n4);
|
|
n3 += n4;
|
|
n += n4;
|
|
n2 -= n4;
|
|
bufferEntry.avail -= n4;
|
|
if (bufferEntry.avail > 0) continue;
|
|
this.incomingHead = bufferEntry.next;
|
|
if (this.incomingTail == bufferEntry) {
|
|
this.incomingTail = null;
|
|
}
|
|
bufferEntry.next = null;
|
|
}
|
|
this.nIncoming -= n3;
|
|
this.incomingLock.notifyAll();
|
|
return n3;
|
|
}
|
|
}
|
|
|
|
private void assertOpen() throws IOException {
|
|
if (!this.open) {
|
|
throw new IOException("circuit closed");
|
|
}
|
|
}
|
|
|
|
void sendOpen() throws Exception {
|
|
FoxRequest foxRequest = new FoxRequest("circuit", "open");
|
|
foxRequest.add("id", this.id);
|
|
foxRequest.add("channel", this.channel);
|
|
foxRequest.add("command", this.command);
|
|
this.session.sendAsync(foxRequest);
|
|
}
|
|
|
|
void sendStream(byte[] byArray, int n) throws Exception {
|
|
FoxRequest foxRequest = new FoxRequest("circuit", "stream");
|
|
foxRequest.add("id", this.id);
|
|
foxRequest.add("data", byArray, n);
|
|
this.session.sendAsync(foxRequest);
|
|
}
|
|
|
|
FoxRequest sendStream(byte[] byArray, int n, int n2, FoxAsyncCallbacks foxAsyncCallbacks) throws Exception {
|
|
FoxRequest foxRequest = new FoxRequest("circuit", "stream");
|
|
foxRequest.add("id", this.id);
|
|
foxRequest.add("data", byArray, n, n2);
|
|
this.session.sendAsync(foxRequest, foxAsyncCallbacks);
|
|
return foxRequest;
|
|
}
|
|
|
|
void sendClose() throws Exception {
|
|
if (this.open && !this.session.isClosed()) {
|
|
FoxRequest foxRequest = new FoxRequest("circuit", "close");
|
|
foxRequest.add("id", this.id);
|
|
this.session.sendAsync(foxRequest);
|
|
}
|
|
}
|
|
|
|
public String toString() {
|
|
return "Circuit [" + this.session.getId() + "] " + this.channel + "." + this.command + " out=" + this.nOutgoing + " in=" + this.nIncoming + " open=" + this.open;
|
|
}
|
|
|
|
public void dumpIncomingList() {
|
|
System.out.println("Incoming List:");
|
|
System.out.println(" head=" + this.incomingHead);
|
|
System.out.println(" tail=" + this.incomingTail);
|
|
System.out.println(" chain=");
|
|
BufferEntry bufferEntry = this.incomingHead;
|
|
while (bufferEntry != null) {
|
|
System.out.println(" " + bufferEntry);
|
|
bufferEntry = bufferEntry.next;
|
|
}
|
|
}
|
|
|
|
private static void trace(String string) {
|
|
System.out.println(string);
|
|
}
|
|
|
|
static class BufferEntry {
|
|
byte[] data;
|
|
int avail;
|
|
BufferEntry next;
|
|
|
|
BufferEntry(byte[] byArray) {
|
|
this.data = byArray;
|
|
this.avail = byArray.length;
|
|
}
|
|
|
|
public String toString() {
|
|
return Integer.toString(System.identityHashCode(this), 36) + " avail=" + this.avail + " length=" + this.data.length;
|
|
}
|
|
}
|
|
|
|
class CircuitInputStream
|
|
extends InputStream {
|
|
byte[] temp = new byte[1];
|
|
|
|
CircuitInputStream() {
|
|
}
|
|
|
|
public int read() throws IOException {
|
|
return this.read(this.temp, 0, 1) <= 0 ? -1 : this.temp[0] & 0xFF;
|
|
}
|
|
|
|
public int read(byte[] byArray) throws IOException {
|
|
return this.read(byArray, 0, byArray.length);
|
|
}
|
|
|
|
public int read(byte[] byArray, int n, int n2) throws IOException {
|
|
return FoxCircuit.this.pullIn(byArray, n, n2);
|
|
}
|
|
|
|
public void close() throws IOException {
|
|
FoxCircuit.this.close();
|
|
}
|
|
}
|
|
|
|
class CircuitOutputStream
|
|
extends OutputStream {
|
|
byte[] temp = new byte[1];
|
|
|
|
CircuitOutputStream() {
|
|
}
|
|
|
|
public void write(int n) throws IOException {
|
|
this.temp[0] = (byte)n;
|
|
this.write(this.temp, 0, 1);
|
|
}
|
|
|
|
public void write(byte[] byArray) throws IOException {
|
|
this.write(byArray, 0, byArray.length);
|
|
}
|
|
|
|
public void write(byte[] byArray, int n, int n2) throws IOException {
|
|
FoxCircuit.this.writeOut(byArray, n, n2);
|
|
}
|
|
|
|
public void flush() throws IOException {
|
|
FoxCircuit.this.flush();
|
|
}
|
|
|
|
public void close() {
|
|
FoxCircuit.this.close();
|
|
}
|
|
}
|
|
}
|
|
|