/* * 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(); } } }