java 自定义解码_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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值