⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iobufferdecoder.java

📁 mina是以Java实现的一个开源的网络程序框架
💻 JAVA
字号:
/* *  Licensed to the Apache Software Foundation (ASF) under one *  or more contributor license agreements.  See the NOTICE file *  distributed with this work for additional information *  regarding copyright ownership.  The ASF licenses this file *  to you under the Apache License, Version 2.0 (the *  "License"); you may not use this file except in compliance *  with the License.  You may obtain a copy of the License at * *    http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, *  software distributed under the License is distributed on an *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *  KIND, either express or implied.  See the License for the *  specific language governing permissions and limitations *  under the License. * */package org.apache.mina.proxy.utils;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.textline.LineDelimiter;/** * IoBufferDecoder.java - Handles an {@link IoBuffer} decoder which supports two methods :  * - dynamic delimiter decoding * - fixed length content reading *  * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev: 685703 $, $Date: 2008-08-14 00:14:47 +0200 (Thu, 14 Aug 2008) $ * @since MINA 2.0.0-M3 */public class IoBufferDecoder {    public class DecodingContext {        private IoBuffer decodedBuffer;        private IoBuffer delimiter;        private int contentLength = -1;        private int matchCount = 0;        public void clean() {            contentLength = -1;            matchCount = 0;            decodedBuffer = null;        }        public int getContentLength() {            return contentLength;        }        public void setContentLength(int contentLength) {            this.contentLength = contentLength;        }        public int getMatchCount() {            return matchCount;        }        public void setMatchCount(int matchCount) {            this.matchCount = matchCount;        }        public IoBuffer getDecodedBuffer() {            return decodedBuffer;        }        public void setDecodedBuffer(IoBuffer decodedBuffer) {            this.decodedBuffer = decodedBuffer;        }        public IoBuffer getDelimiter() {            return delimiter;        }        public void setDelimiter(IoBuffer delimiter) {            this.delimiter = delimiter;        }    }    private DecodingContext ctx = new DecodingContext();    /**     * Creates a new instance that uses specified <tt>delimiter</tt> byte array as a     * message delimiter.     */    public IoBufferDecoder(byte[] delimiter) {        setDelimiter(delimiter, true);    }    /**     * Creates a new instance that will read messages of <tt>contentLength</tt> bytes.     */    public IoBufferDecoder(int contentLength) {        setContentLength(contentLength, false);    }    /**     * Sets the the length of the content line to be decoded.     * When set, it overrides the dynamic delimiter setting. The default value is <tt>-1</tt>.     * Content length method will be used for decoding on the next decodeOnce call.      * Delimiter matching is reset only if <tt>resetMatchCount</tt> is true.     */    public void setContentLength(int contentLength, boolean resetMatchCount) {        if (contentLength <= 0) {            throw new IllegalArgumentException("contentLength: "                    + contentLength);        }        ctx.setContentLength(contentLength);        if (resetMatchCount) {            ctx.setMatchCount(0);        }    }    /**     * Dynamically sets a new delimiter. Next time      * {@link IoBufferDecoder#decodeOnce(IoSession, int) } will be called it will use the new      * delimiter. Delimiter matching is reset only if <tt>resetMatchCount</tt> is true but      * decoding will continue from current position.     *      * NB : Delimiter {@link LineDelimiter#AUTO} is not allowed.      */    public void setDelimiter(byte[] delim, boolean resetMatchCount) {        if (delim == null) {            throw new NullPointerException("Null delimiter not allowed");        }        // Convert delimiter to IoBuffer.        IoBuffer delimiter = IoBuffer.allocate(delim.length);        delimiter.put(delim);        delimiter.flip();        ctx.setDelimiter(delimiter);        ctx.setContentLength(-1);        if (resetMatchCount) {            ctx.setMatchCount(0);        }    }    /**     * Will return null unless it has enough data to decode. If <code>contentLength</code>     * is set then it tries to retrieve <code>contentLength</code> bytes from the buffer     * otherwise it will scan the buffer to find the data <code>delimiter</code> and return     * all the data and the trailing delimiter.     */    public IoBuffer decodeFully(IoBuffer in) {        int contentLength = ctx.getContentLength();        IoBuffer decodedBuffer = ctx.getDecodedBuffer();        int oldLimit = in.limit();        // Retrieve fixed length content        if (contentLength > -1) {            if (decodedBuffer == null) {                decodedBuffer = IoBuffer.allocate(contentLength).setAutoExpand(                        true);            }            if (in.remaining() < contentLength) {                int readBytes = in.remaining();                decodedBuffer.put(in);                ctx.setDecodedBuffer(decodedBuffer);                ctx.setContentLength(contentLength - readBytes);                return null;            } else {                int newLimit = in.position() + contentLength;                in.limit(newLimit);                decodedBuffer.put(in);                decodedBuffer.flip();                in.limit(oldLimit);                ctx.clean();                return decodedBuffer;            }        }        // Not a fixed length matching so try to find a delimiter match        int oldPos = in.position();        int matchCount = ctx.getMatchCount();        IoBuffer delimiter = ctx.getDelimiter();        while (in.hasRemaining()) {            byte b = in.get();            if (delimiter.get(matchCount) == b) {                matchCount++;                if (matchCount == delimiter.limit()) {                    // Found a match.                    int pos = in.position();                    in.position(oldPos);                    in.limit(pos);                    if (decodedBuffer == null) {                        decodedBuffer = IoBuffer.allocate(in.remaining())                                .setAutoExpand(true);                    }                    decodedBuffer.put(in);                    decodedBuffer.flip();                    in.limit(oldLimit);                    ctx.clean();                    return decodedBuffer;                }            } else {                in.position(Math.max(0, in.position() - matchCount));                matchCount = 0;            }        }        // Copy remainder from buf.        if (in.remaining() > 0) {            in.position(oldPos);            decodedBuffer.put(in);            in.position(in.limit());        }        // Save decoding state        ctx.setMatchCount(matchCount);        ctx.setDecodedBuffer(decodedBuffer);        return decodedBuffer;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -