思特奇智慧酒店云平台 v0.0.5版本的 MD5 值为:dedb172bb322639d79d7e0e26262fb5c

以下内容为反编译后的 InBandBytestreamSession.java 源代码,内容仅作参考


package org.jivesoftware.smackx.bytestreams.ibb;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaError;
import org.jivesoftware.smack.util.stringencoder.Base64;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
public class InBandBytestreamSession implements BytestreamSession {
    public final Open byteStreamRequest;
    public final XMPPConnection connection;
    public IBBInputStream inputStream;
    public IBBOutputStream outputStream;
    public xw3 remoteJID;
    public boolean closeBothStreamsEnabled = false;
    public boolean isClosed = false;

    public static class AnonymousClass1 {
        public static final int[] $SwitchMap$org$jivesoftware$smackx$bytestreams$ibb$InBandBytestreamManager$StanzaType = new int[InBandBytestreamManager.StanzaType.values().length];

        static {
            try {
                $SwitchMap$org$jivesoftware$smackx$bytestreams$ibb$InBandBytestreamManager$StanzaType[InBandBytestreamManager.StanzaType.IQ.ordinal()] = 1;
            } catch (NoSuchFieldError unused) {
            }
            try {
                $SwitchMap$org$jivesoftware$smackx$bytestreams$ibb$InBandBytestreamManager$StanzaType[InBandBytestreamManager.StanzaType.MESSAGE.ordinal()] = 2;
            } catch (NoSuchFieldError unused2) {
            }
        }
    }

    public class IBBDataPacketFilter implements StanzaFilter {
        public IBBDataPacketFilter() {
        }

        @Override
        public boolean accept(Stanza stanza) {
            DataPacketExtension dataPacketExtension;
            if (stanza.getFrom().a((CharSequence) InBandBytestreamSession.this.remoteJID)) {
                if (stanza instanceof Data) {
                    dataPacketExtension = ((Data) stanza).getDataPacketExtension();
                } else {
                    dataPacketExtension = (DataPacketExtension) stanza.getExtension("data", "http://jabber.org/protocol/ibb");
                    if (dataPacketExtension == null) {
                        return false;
                    }
                }
                return dataPacketExtension.getSessionID().equals(InBandBytestreamSession.this.byteStreamRequest.getSessionID());
            }
            return false;
        }

        public IBBDataPacketFilter(InBandBytestreamSession inBandBytestreamSession, AnonymousClass1 anonymousClass1) {
            this();
        }
    }

    public abstract class IBBOutputStream extends OutputStream {
        public final byte[] buffer;
        public int bufferPointer;
        public boolean isClosed;
        public long seq;

        public IBBOutputStream(InBandBytestreamSession inBandBytestreamSession, AnonymousClass1 anonymousClass1) {
            this();
        }

        private synchronized void flushBuffer() throws IOException {
            if (this.bufferPointer == 0) {
                return;
            }
            try {
                writeToXML(new DataPacketExtension(InBandBytestreamSession.this.byteStreamRequest.getSessionID(), this.seq, Base64.encodeToString(this.buffer, 0, this.bufferPointer)));
                this.bufferPointer = 0;
                this.seq = this.seq + 1 == wh3.s ? 0L : this.seq + 1;
            } catch (InterruptedException | SmackException.NotConnectedException e) {
                IOException iOException = new IOException();
                iOException.initCause(e);
                throw iOException;
            }
        }

        private synchronized void writeOut(byte[] bArr, int i, int i2) throws IOException {
            if (!this.isClosed) {
                int i3 = 0;
                if (i2 > this.buffer.length - this.bufferPointer) {
                    i3 = this.buffer.length - this.bufferPointer;
                    System.arraycopy(bArr, i, this.buffer, this.bufferPointer, i3);
                    this.bufferPointer += i3;
                    flushBuffer();
                }
                int i4 = i2 - i3;
                System.arraycopy(bArr, i + i3, this.buffer, this.bufferPointer, i4);
                this.bufferPointer += i4;
            } else {
                throw new IOException("Stream is closed");
            }
        }

        @Override
        public void close() throws IOException {
            if (this.isClosed) {
                return;
            }
            InBandBytestreamSession.this.closeByLocal(false);
        }

        public void closeInternal(boolean z) {
            if (this.isClosed) {
                return;
            }
            this.isClosed = true;
            if (z) {
                try {
                    flushBuffer();
                } catch (IOException unused) {
                }
            }
        }

        @Override
        public synchronized void flush() throws IOException {
            if (!this.isClosed) {
                flushBuffer();
            } else {
                throw new IOException("Stream is closed");
            }
        }

        @Override
        public synchronized void write(int i) throws IOException {
            if (!this.isClosed) {
                if (this.bufferPointer >= this.buffer.length) {
                    flushBuffer();
                }
                byte[] bArr = this.buffer;
                int i2 = this.bufferPointer;
                this.bufferPointer = i2 + 1;
                bArr[i2] = (byte) i;
            } else {
                throw new IOException("Stream is closed");
            }
        }

        public abstract void writeToXML(DataPacketExtension dataPacketExtension) throws IOException, SmackException.NotConnectedException, InterruptedException;

        public IBBOutputStream() {
            this.bufferPointer = 0;
            this.seq = 0L;
            this.isClosed = false;
            this.buffer = new byte[InBandBytestreamSession.this.byteStreamRequest.getBlockSize()];
        }

        @Override
        public synchronized void write(byte[] bArr, int i, int i2) throws IOException {
            int i3;
            if (bArr != null) {
                if (i < 0 || i > bArr.length || i2 < 0 || (i3 = i + i2) > bArr.length || i3 < 0) {
                    throw new IndexOutOfBoundsException();
                }
                if (i2 == 0) {
                    return;
                }
                if (!this.isClosed) {
                    if (i2 >= this.buffer.length) {
                        writeOut(bArr, i, this.buffer.length);
                        write(bArr, i + this.buffer.length, i2 - this.buffer.length);
                    } else {
                        writeOut(bArr, i, i2);
                    }
                    return;
                }
                throw new IOException("Stream is closed");
            }
            throw new NullPointerException();
        }

        @Override
        public synchronized void write(byte[] bArr) throws IOException {
            write(bArr, 0, bArr.length);
        }
    }

    public class IQIBBInputStream extends IBBInputStream {
        public IQIBBInputStream() {
            super();
        }

        @Override
        public StanzaFilter getDataPacketFilter() {
            return new AndFilter(new StanzaTypeFilter(Data.class), new IBBDataPacketFilter(InBandBytestreamSession.this, null));
        }

        @Override
        public StanzaListener getDataPacketListener() {
            return new StanzaListener() {
                public long lastSequence = -1;

                @Override
                public void processStanza(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException {
                    DataPacketExtension dataPacketExtension = ((Data) stanza).getDataPacketExtension();
                    if (dataPacketExtension.getSeq() <= this.lastSequence) {
                        InBandBytestreamSession.this.connection.sendStanza(IQ.createErrorResponse((IQ) stanza, StanzaError.Condition.unexpected_request));
                    } else if (dataPacketExtension.getDecodedData() == null) {
                        InBandBytestreamSession.this.connection.sendStanza(IQ.createErrorResponse((IQ) stanza, StanzaError.Condition.bad_request));
                    } else {
                        IQIBBInputStream.this.dataQueue.offer(dataPacketExtension);
                        InBandBytestreamSession.this.connection.sendStanza(IQ.createResultIQ((IQ) stanza));
                        this.lastSequence = dataPacketExtension.getSeq();
                        if (this.lastSequence == wh3.s) {
                            this.lastSequence = -1L;
                        }
                    }
                }
            };
        }

        public IQIBBInputStream(InBandBytestreamSession inBandBytestreamSession, AnonymousClass1 anonymousClass1) {
            this();
        }
    }

    public class IQIBBOutputStream extends IBBOutputStream {
        public IQIBBOutputStream() {
            super(InBandBytestreamSession.this, null);
        }

        @Override
        public synchronized void writeToXML(DataPacketExtension dataPacketExtension) throws IOException {
            Data data = new Data(dataPacketExtension);
            data.setTo(InBandBytestreamSession.this.remoteJID);
            try {
                InBandBytestreamSession.this.connection.createStanzaCollectorAndSend(data).nextResultOrThrow();
            } catch (Exception e) {
                if (!this.isClosed) {
                    InBandBytestreamSession.this.close();
                    IOException iOException = new IOException();
                    iOException.initCause(e);
                    throw iOException;
                }
            }
        }

        public IQIBBOutputStream(InBandBytestreamSession inBandBytestreamSession, AnonymousClass1 anonymousClass1) {
            this();
        }
    }

    public class MessageIBBInputStream extends IBBInputStream {
        public MessageIBBInputStream() {
            super();
        }

        @Override
        public StanzaFilter getDataPacketFilter() {
            return new AndFilter(new StanzaTypeFilter(Message.class), new IBBDataPacketFilter(InBandBytestreamSession.this, null));
        }

        @Override
        public StanzaListener getDataPacketListener() {
            return new StanzaListener() {
                @Override
                public void processStanza(Stanza stanza) {
                    DataPacketExtension dataPacketExtension = (DataPacketExtension) stanza.getExtension("data", "http://jabber.org/protocol/ibb");
                    if (dataPacketExtension.getDecodedData() == null) {
                        return;
                    }
                    MessageIBBInputStream.this.dataQueue.offer(dataPacketExtension);
                }
            };
        }

        public MessageIBBInputStream(InBandBytestreamSession inBandBytestreamSession, AnonymousClass1 anonymousClass1) {
            this();
        }
    }

    public class MessageIBBOutputStream extends IBBOutputStream {
        public MessageIBBOutputStream() {
            super(InBandBytestreamSession.this, null);
        }

        @Override
        public synchronized void writeToXML(DataPacketExtension dataPacketExtension) throws SmackException.NotConnectedException, InterruptedException {
            Message message = new Message(InBandBytestreamSession.this.remoteJID);
            message.addExtension(dataPacketExtension);
            InBandBytestreamSession.this.connection.sendStanza(message);
        }

        public MessageIBBOutputStream(InBandBytestreamSession inBandBytestreamSession, AnonymousClass1 anonymousClass1) {
            this();
        }
    }

    public InBandBytestreamSession(XMPPConnection xMPPConnection, Open open, xw3 xw3Var) {
        this.connection = xMPPConnection;
        this.byteStreamRequest = open;
        this.remoteJID = xw3Var;
        int i = AnonymousClass1.$SwitchMap$org$jivesoftware$smackx$bytestreams$ibb$InBandBytestreamManager$StanzaType[open.getStanza().ordinal()];
        if (i == 1) {
            this.inputStream = new IQIBBInputStream(this, null);
            this.outputStream = new IQIBBOutputStream(this, null);
        } else if (i != 2) {
        } else {
            this.inputStream = new MessageIBBInputStream(this, null);
            this.outputStream = new MessageIBBOutputStream(this, null);
        }
    }

    @Override
    public void close() throws IOException {
        closeByLocal(true);
        closeByLocal(false);
    }

    public synchronized void closeByLocal(boolean z) throws IOException {
        if (this.isClosed) {
            return;
        }
        if (this.closeBothStreamsEnabled) {
            this.inputStream.closeInternal();
            this.outputStream.closeInternal(true);
        } else if (z) {
            this.inputStream.closeInternal();
        } else {
            this.outputStream.closeInternal(true);
        }
        if (this.inputStream.isClosed && this.outputStream.isClosed) {
            this.isClosed = true;
            Close close = new Close(this.byteStreamRequest.getSessionID());
            close.setTo(this.remoteJID);
            try {
                this.connection.createStanzaCollectorAndSend(close).nextResultOrThrow();
                this.inputStream.cleanup();
                InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(this.byteStreamRequest.getSessionID());
            } catch (Exception e) {
                IOException iOException = new IOException();
                iOException.initCause(e);
                throw iOException;
            }
        }
    }

    public void closeByPeer(Close close) throws SmackException.NotConnectedException, InterruptedException {
        this.inputStream.closeInternal();
        this.inputStream.cleanup();
        this.outputStream.closeInternal(false);
        this.connection.sendStanza(IQ.createResultIQ(close));
    }

    @Override
    public InputStream getInputStream() {
        return this.inputStream;
    }

    @Override
    public OutputStream getOutputStream() {
        return this.outputStream;
    }

    @Override
    public int getReadTimeout() {
        return this.inputStream.readTimeout;
    }

    public boolean isCloseBothStreamsEnabled() {
        return this.closeBothStreamsEnabled;
    }

    public void processIQPacket(Data data) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException {
        this.inputStream.dataPacketListener.processStanza(data);
    }

    public void setCloseBothStreamsEnabled(boolean z) {
        this.closeBothStreamsEnabled = z;
    }

    @Override
    public void setReadTimeout(int i) {
        if (i >= 0) {
            this.inputStream.readTimeout = i;
            return;
        }
        throw new IllegalArgumentException("Timeout must be >= 0");
    }

    public abstract class IBBInputStream extends InputStream {
        public byte[] buffer;
        public final BlockingQueue<DataPacketExtension> dataQueue = new LinkedBlockingQueue();
        public int bufferPointer = -1;
        public long seq = -1;
        public boolean isClosed = false;
        public boolean closeInvoked = false;
        public int readTimeout = 0;
        public final StanzaListener dataPacketListener = getDataPacketListener();

        public IBBInputStream() {
            InBandBytestreamSession.this.connection.addSyncStanzaListener(this.dataPacketListener, getDataPacketFilter());
        }

        private void checkClosed() throws IOException {
            if (this.closeInvoked) {
                this.dataQueue.clear();
                throw new IOException("Stream is closed");
            }
        }

        public void cleanup() {
            InBandBytestreamSession.this.connection.removeSyncStanzaListener(this.dataPacketListener);
        }

        public void closeInternal() {
            if (this.isClosed) {
                return;
            }
            this.isClosed = true;
        }

        private synchronized boolean loadBuffer() throws IOException {
            DataPacketExtension dataPacketExtension = null;
            try {
                if (this.readTimeout == 0) {
                    while (dataPacketExtension == null) {
                        if (this.isClosed && this.dataQueue.isEmpty()) {
                            return false;
                        }
                        dataPacketExtension = this.dataQueue.poll(1000L, TimeUnit.MILLISECONDS);
                    }
                } else {
                    dataPacketExtension = this.dataQueue.poll(this.readTimeout, TimeUnit.MILLISECONDS);
                    if (dataPacketExtension == null) {
                        throw new SocketTimeoutException();
                    }
                }
                if (this.seq == wh3.s) {
                    this.seq = -1L;
                }
                long seq = dataPacketExtension.getSeq();
                if (seq - 1 == this.seq) {
                    this.seq = seq;
                    this.buffer = dataPacketExtension.getDecodedData();
                    this.bufferPointer = 0;
                    return true;
                }
                InBandBytestreamSession.this.close();
                throw new IOException("Packets out of sequence");
            } catch (InterruptedException unused) {
                Thread.currentThread().interrupt();
                return false;
            }
        }

        @Override
        public void close() throws IOException {
            if (this.closeInvoked) {
                return;
            }
            this.closeInvoked = true;
            InBandBytestreamSession.this.closeByLocal(true);
        }

        public abstract StanzaFilter getDataPacketFilter();

        public abstract StanzaListener getDataPacketListener();

        @Override
        public boolean markSupported() {
            return false;
        }

        @Override
        public synchronized int read() throws IOException {
            checkClosed();
            if ((this.bufferPointer == -1 || this.bufferPointer >= this.buffer.length) && !loadBuffer()) {
                return -1;
            }
            byte[] bArr = this.buffer;
            int i = this.bufferPointer;
            this.bufferPointer = i + 1;
            return bArr[i] & 255;
        }

        @Override
        public synchronized int read(byte[] bArr, int i, int i2) throws IOException {
            int i3;
            if (bArr != null) {
                if (i < 0 || i > bArr.length || i2 < 0 || (i3 = i + i2) > bArr.length || i3 < 0) {
                    throw new IndexOutOfBoundsException();
                }
                if (i2 == 0) {
                    return 0;
                }
                checkClosed();
                if ((this.bufferPointer == -1 || this.bufferPointer >= this.buffer.length) && !loadBuffer()) {
                    return -1;
                }
                int length = this.buffer.length - this.bufferPointer;
                if (i2 > length) {
                    i2 = length;
                }
                System.arraycopy(this.buffer, this.bufferPointer, bArr, i, i2);
                this.bufferPointer += i2;
                return i2;
            }
            throw new NullPointerException();
        }

        @Override
        public synchronized int read(byte[] bArr) throws IOException {
            return read(bArr, 0, bArr.length);
        }
    }
}