1. 程式人生 > >Mina自定義文字編解碼

Mina自定義文字編解碼

package com.boonya.protocol.codec.self;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
 
public class MyTextLineCodecDecoder implements ProtocolDecoder {

    private Charset charset; // 編碼格式
 
    private String delimiter; // 文字分隔符

    private IoBuffer delimBuf; // 文字分割符匹配的變數
 

    // 定義常量值,作為每個IoSession中儲存解碼任務的key值
    private static String CONTEXT = MyTextLineCodecDecoder.class.getName()+ ".context";

 
    // 建構函式,必須指定Charset和文字分隔符
    public MyTextLineCodecDecoder(Charset charset, String delimiter) {

        this.charset = charset;

        this.delimiter = delimiter;

    }


    public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)

            throws Exception {

        Context ctx = getContext(session);

        if (delimiter == null || "".equals(delimiter)) { // 如果文字換行符未指定,使用預設值

            delimiter = "\r\n";

        }

        if (charset == null) {

            charset = Charset.forName("utf-8");

        }

        decodeNormal(ctx, in, out);

    }

 

    // 從IoSession中獲取Context物件
    private Context getContext(IoSession session) {

        Context ctx;

        ctx = (Context) session.getAttribute(CONTEXT);

        if (ctx == null) {

            ctx = new Context();

            session.setAttribute(CONTEXT, ctx);

        }

        return ctx;

    }

 

    // 解碼
    private void decodeNormal(Context ctx, IoBuffer in,

            ProtocolDecoderOutput out) throws CharacterCodingException {

        // 取出未完成任務中已經匹配的文字換行符的個數

        int matchCount = ctx.getMatchCount();

 

        // 設定匹配文字換行符的IoBuffer變數

        if (delimBuf == null) {

            IoBuffer tmp = IoBuffer.allocate(2).setAutoExpand(true);

            tmp.putString(delimiter, charset.newEncoder());

            tmp.flip();

            delimBuf = tmp;

        }

        int oldPos = in.position(); // 解碼的IoBuffer中資料的原始資訊

        int oldLimit = in.limit();

        while (in.hasRemaining()) { // 變數解碼的IoBuffer

            byte b = in.get();

            if (delimBuf.get(matchCount) == b) { // 匹配第matchCount位換行符成功

                matchCount++;

                if (matchCount == delimBuf.limit()) { // 當前匹配到位元組個數與文字換行符位元組個數相同,匹配結束

                    int pos = in.position(); // 獲得當前匹配到的position(position前所有資料有效)
                    in.limit(pos);
                    in.position(oldPos); // position回到原始位置
 

                    ctx.append(in); // 追加到Context物件未完成資料後面

                    in.limit(oldLimit); // in中匹配結束後剩餘資料
                    in.position(pos);

 

                    IoBuffer buf = ctx.getBuf();
                    buf.flip();
                    buf.limit(buf.limit() - matchCount);// 去掉匹配資料中的文字換行符
                    try {
                        out.write(buf.getString(ctx.getDecoder())); // 輸出解碼內容
                    } finally {
                        buf.clear(); // 釋放快取空間

                    }

                    oldPos = pos;

                    matchCount = 0;

                }

            } else {

                // 如果matchCount==0,則繼續匹配

                // 如果matchCount>0,說明沒有匹配到文字換行符的中的前一個匹配成功位元組的下一個位元組,

                // 跳轉到匹配失敗字元處,並置matchCount=0,繼續匹配

                in.position(in.position() - matchCount);

                matchCount = 0; // 匹配成功後,matchCount置空

            }

        }
 
        // 把in中未解碼內容放回buf中
        in.position(oldPos);

        ctx.append(in);

        ctx.setMatchCount(matchCount);

    }

    public void dispose(IoSession session) throws Exception {


    }

    public void finishDecode(IoSession session, ProtocolDecoderOutput out)

            throws Exception {

    }


    // 內部類,儲存IoSession解碼時未完成的任務
    private class Context {

        private CharsetDecoder decoder;

        private IoBuffer buf; // 儲存真實解碼內容

        private int matchCount = 0; // 匹配到的文字換行符個數

 

        private Context() {

            decoder = charset.newDecoder();

            buf = IoBuffer.allocate(80).setAutoExpand(true);

        }

 

        // 重置
        @SuppressWarnings("unused")

        public void reset() {

            matchCount = 0;

            decoder.reset();

        }

 

        // 追加資料
        public void append(IoBuffer in) {

            getBuf().put(in);

        }

 
        // ======get/set方法=====================
        public CharsetDecoder getDecoder() {

            return decoder;

        }

 
        public IoBuffer getBuf() {

            return buf;

        }

 

        public int getMatchCount() {

            return matchCount;

        }

 

        public void setMatchCount(int matchCount) {

            this.matchCount = matchCount;

        }

    } // end class Context;

}

相關推薦

Mina定義文字解碼

package com.boonya.protocol.codec.self; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetD

mina定義解碼器接收處理byte陣列(同時解決資料傳輸中的粘包、缺包問題)

我們在自定義傳輸協議時,通常都是採用位元組陣列的方式進行傳送,如何正確接收和解碼byte陣列? 假設我們自定義了傳輸協議: 位元組陣列的前4個位元組是要傳輸的資料長度,後面跟資料。我們用mina可以這樣處理 1.自定義編碼器ByteArrayEncoder.java imp

【APACHE MINA2.0開發之二】定義實現SERVER/CLIENT端的解碼工廠(定義編碼與解碼器)!

在上一篇博文中已經簡單介紹過“過濾器”的概念,那麼在Mina 中的協議編解碼器通過過濾器 ProtocolCodecFilter 構造,這個過濾器的構造方法需 要一個 ProtocolCodecFactory,這從前面註冊 TextLineCodecFactory 的程式碼就可以看出來。 Protoc

Delphi如何在Form的標題欄繪制定義文字

windows消息 特定 pri draw window raw win ont ext Delphi中Form窗體的標題被設計成繪制在系統菜單的旁邊,如果你想要在標題欄繪制自定義文本又不想改變Caption屬性,你需要處理特定的Windows消息:WM_NCPAIN

css定義滾動條樣式,定義文字選擇樣式,設置文字不被選擇

sed 分享 play gpo radi https cal hid 右移 ::-webkit-scrollbar 滾動條整體部分 ::-webkit-scrollbar-thumb 滾動條裏面的小方塊,能向上向下移動(或往左往右移動,取決於是垂直滾動條還是水平滾動條)

TabTopAutoTextSizeLayout【定義文字字號區域(動態選項卡數據且可滑動)】

標題 unit near cnblogs 重新 auto target 類文件 fault 版權聲明:本文為HaiyuKing原創文章,轉載請註明出處! 前言 自定義頂部選項卡布局LinearLayout類,實現可滑動效果。【實際情況中建議使用RecyclerView】

android 定義文字字型

@SuppressLint("AppCompatCustomView") public class TypefaceTextView extends TextView { //字型檔案放在assets檔案中 // fongUrl是自定義字型分類的名稱 private static S

[Xcode10 實際操作]四、常用控制元件-(5)UILabel文字標籤定義文字樣式

本文將演示給標籤物件新增描邊效果,在專案資料夾上,點選滑鼠右鍵選單, 選擇【Create File】->【Cocoa Touch Class】->【Next】-> 【Class】:MyLabel 【Subclass of 】:UILabel 【Language】:Swift -&g

CAD編輯器中怎麼定義文字屬性樣式

想問一下大家在編輯圖紙的時候有沒有遇到過這樣的問題,就是在CAD繪圖的時候,要給編輯的圖紙中做一下特別的說明,但是CAD編輯器中原有的文字樣式部署那麼的符合,拿在CAD編輯器中怎麼自定義文字屬性樣式?具體要怎麼來進行操作?下面小編就來教教大傢俱體的操作,有興趣的朋友可以來看看。 第一步:首先,開啟電腦,看一

CAD編輯器中怎麽定義文字屬性樣式

ado 小夥伴 操作 新版本 e30 ces images 新版 fff 想問一下大家在編輯圖紙的時候有沒有遇到過這樣的問題,就是在CAD繪圖的時候,要給編輯的圖紙中做一下特別的說明,但是CAD編輯器中原有的文字樣式部署那麽的符合,拿在CAD編輯器中怎麽自定義文字屬性樣式?

android定義文字框,後面帶清空按鈕

class MyEditText extends EditText { private final String TAG = "MyEditText"; private Drawable dRight; private Rect rBounds; // 構造器 public MyEditText(Conte

DEVEXPRESS gridview手動新增行和刪除行定義序號、定義文字

新增行和刪除   #region 事件_新增行按鈕         private void buttonAdd_Click(object sender, EventArgs e)         {                             this.gri

JavaScript jqGrid定義表格底部導航+定義文字搜尋框實現

本文討論jqGrid如何實現自定義底部導航,在自定義底部導航中如何實現文字框搜尋,其中涉及的jqGrid資料載入、方法擴充套件本文不再贅述。簡單起見先看個案例。 1、頁面截圖 2、頁面程式碼 <!DOCTYPE html> <html> <he

Perl一行式:文字解碼、替換

文字大小寫轉換 全部字元轉換成大寫或小寫,有幾種方式: # 轉大寫 $ perl -nle 'print uc' file.log $ perl -ple '$_ = uc' file.log $ perl -nle 'print "\U$_"' file.log # 轉小寫 $ perl -nle '

Android定義文字選中模式(全選、複製,剪下,粘帖)

為了方便操作,在PC端我們常用的Ctrl+A(全選)/Ctrl+C(複製)/Ctrl+X(剪下)/Ctrl+V(粘帖)提高了我們的辦公效率。然後在手機端怎麼實現呢?我花了一天的時間研究了一下。 首先說一下TextView的選中,要想選中TextV

Android定義文字閃爍漸變色的跑馬燈

最近因為專案需要,一直都在尋找比較貼合專案主題的跑馬燈,但是寫的demo都是可以執行的,但是整合到專案中的時候就不起作用了,看了許多的資料,最後總結這都是執行緒的問題,後來各種搗騰,終於寫出了一個比較合適的跑馬燈,整合到專案中也是可以執行的,希望大神能多多指點 自定義一個控

mina 定義包的解析

首先定義自動定義的包類 package com.lianshang.findme.common.message; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charse

Java 定義文字圖片

package com.study.util;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;import java.io.*;public class Te

NSMutableAttributedString 定義文字內容的樣式 間距,對其 方向 間隔之類

UIFont *contentLabelfont = [UIFont systemFontOfSize:KFONT_T9]; CGSize contentLabelsize = CGSizeMake(WIDTH_OF_SCREEN - 12 - 12,2000);

Android帶硬解碼器MediaCodec使用必看

一、背景隨著Android系統手機效能的不斷提升,現階段大部分手機都自帶GPU(承擔圖形顯示的專門硬體),大幅度提高手機顯示效能,在視訊顯示、遊戲畫面重新整理,和高分辨影象顯示方面必須使用GPU。GOOGLE在API 16 -4.1版本中增加MediaCodec類,專用於編解