001/**
002 *
003 * Copyright 2018-2020 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack;
018
019import java.io.IOException;
020import java.nio.ByteBuffer;
021import java.security.cert.CertificateException;
022
023import org.jivesoftware.smack.SmackException.NoResponseException;
024
025public interface XmppInputOutputFilter {
026
027    /**
028     * The {@code outputData} argument may be a direct {@link ByteBuffer}. The filter has consume the data of the buffer
029     * completely.
030     *
031     * This method must return a {@link OutputResult}. Use {@link OutputResult#NO_OUTPUT} if there is no output.
032     *
033     * @param outputData the data this method needs to process.
034     * @param isFinalDataOfElement if this is the final data of the element.
035     * @param destinationAddressChanged if the destination address has changed.
036     * @param moreDataAvailable if more data is available.
037     * @return a output result.
038     * @throws IOException in case an I/O exception occurs.
039     */
040    OutputResult output(ByteBuffer outputData, boolean isFinalDataOfElement, boolean destinationAddressChanged,
041                    boolean moreDataAvailable) throws IOException;
042
043    class OutputResult {
044        public static final OutputResult NO_OUTPUT = new OutputResult(false, null);
045
046        public final boolean pendingFilterData;
047        public final ByteBuffer filteredOutputData;
048
049        public OutputResult(ByteBuffer filteredOutputData) {
050            this(false, filteredOutputData);
051        }
052
053        public OutputResult(boolean pendingFilterData, ByteBuffer filteredOutputData) {
054            this.pendingFilterData = pendingFilterData;
055            this.filteredOutputData = filteredOutputData;
056        }
057    }
058
059    /**
060     * The returned {@link ByteBuffer} is going to get fliped by the caller. The callee must not flip the buffer.
061     * @param inputData the data this methods needs to process.
062     * @return a {@link ByteBuffer} or {@code null} if no data could be produced.
063     * @throws IOException in case an I/O exception occurs.
064     */
065    ByteBuffer input(ByteBuffer inputData) throws IOException;
066
067    default void closeInputOutput() {
068    }
069
070    default void waitUntilInputOutputClosed() throws IOException, NoResponseException, CertificateException,
071                    InterruptedException, SmackException, XMPPException {
072    }
073
074    Object getStats();
075
076    String getFilterName();
077}