Package net.solosky.maplefetion.util

Source Code of net.solosky.maplefetion.util.SipcParser

/*
* 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.
*/

/**
* Project  : MapleFetion2
* Package  : net.solosky.net.maplefetion.client
* File     : SipcParser.java
* Author   : solosky < solosky772@qq.com >
* Created  : 2010-1-5
* License  : Apache License 2.0
*/
package net.solosky.maplefetion.util;

import net.solosky.maplefetion.FetionException;
import net.solosky.maplefetion.chain.AbstractProcessor;
import net.solosky.maplefetion.net.buffer.ByteArrayWriter;
import net.solosky.maplefetion.net.buffer.ByteReader;
import net.solosky.maplefetion.net.buffer.ByteWriter;
import net.solosky.maplefetion.sipc.SipcBody;
import net.solosky.maplefetion.sipc.SipcHeader;
import net.solosky.maplefetion.sipc.SipcInMessage;
import net.solosky.maplefetion.sipc.SipcMessage;
import net.solosky.maplefetion.sipc.SipcNotify;
import net.solosky.maplefetion.sipc.SipcOutMessage;
import net.solosky.maplefetion.sipc.SipcResponse;

/**
*
* 协议解析器
*
* @author solosky <solosky772@qq.com>
*/
public class SipcParser extends AbstractProcessor
{
 
  /**
   * 临时缓冲区
   */
  private ByteWriter byteWriter;
 
  /**
   * 字节缓冲区
   */
  private ByteReader byteReader;
 
  /**
   * 当前解码的消息
   */
  private SipcInMessage curMessage;
   
  /**
   * 消息体还需要读取的长度
   */
  private int contentLeft;
 
  /**
   * 读取一行时上一个字符
   */
  private int lineLast;
 
  /**
   * 上一次操作
   */
  private int lastAction;
 
  /**
   * 有效字符掩码
   */
  private static final int BYTE_MASK = 0x7FFFFFFF;
 
  /**
   * 操作常量
   */
  private static final int ACTION_NONE     = 0x00;
  private static final int ACTION_READ_RETURN   = 0x01;
  private static final int ACTION_READ_HEADER   = 0x02;
  private static final int ACTION_READ_CONTENT = 0x03;
 
 
 
  /**
   * 默认构造函数
   */
  public SipcParser()
  {
    this.byteWriter = new ByteArrayWriter();
    this.contentLeft = 0;
    this.lastAction = ACTION_NONE;
    this.lineLast = BYTE_MASK;
  }
 
 
  /**
   * 把发出信令转换为字节写对象
   * @return
   */
  public ByteWriter parseOutMessage(SipcOutMessage out)
  {
    ByteWriter writer = new ByteArrayWriter();
    byte[] bytes = ConvertHelper.string2Byte(out.toSendString());
    writer.write(bytes);
    return writer;
   
  }
 
  /**
   * 从buffer里解码SIP信令对象
   * @throws FetionException
   */
  public boolean parseInMessage() throws FetionException
  {
    switch (lastAction)
    {
    case ACTION_READ_RETURN:
    case ACTION_NONE:
      String headline = this.readLine();
      if (headline == null) {
        lastAction = ACTION_READ_RETURN;
        return false;
      }
      return this.readSipcMessage(headline);

    case ACTION_READ_HEADER:
      return this.readSipcHeaders() && this.readSipcBody();

    case ACTION_READ_CONTENT:
      return this.readSipcBody();

    default:
      return false;
    }
  }

   
    /**
     * 把当前对象刷新至下一个处理器
     * @throws FetionException
     */
    private void flushInMessage() throws FetionException
    {
      if(this.previousProcessor!=null)
        this.previousProcessor.processIncoming(this.curMessage);
     this.curMessage = null;
     this.lastAction = ACTION_NONE;
     this.lineLast = BYTE_MASK;
    }
   
    /**
     * 把字节写入对象刷新至下一个处理器 ,一般是Transfer
     * @param writer
     * @throws FetionException
     */
    private void flushOutMessage(ByteWriter writer) throws FetionException
    {
      if(this.nextProcessor!=null) {
        this.nextProcessor.processOutcoming(writer);
      }
    }
   
    /**
     * 读取SIP信令
     * @param buffer   缓存对象
     * @param head    首行信息
     */
    private boolean readSipcMessage(String headline)
    {
      if(headline.startsWith("SIP-C/")) {
        this.curMessage = new SipcResponse(headline)//SIP-C/2.0 200 OK
     }else {
       this.curMessage = new SipcNotify(headline);    //BN 685592830 SIP-C/2.0
     }

    if(this.readSipcHeaders()) {
      return this.readSipcBody();
    }else {
      return false;
    }
    }
   
   
    /**
     * 读取一行字符
     * @param buffer  缓存对象
     * @return      字符串不包含\r\n
     */
    public String readLine()
    {
      int cur  = BYTE_MASK;
      int last = BYTE_MASK;
      boolean end = false;
      if(lineLast==BYTE_MASK) {
        byteWriter.clear();
        }else {
          last = lineLast;
        }
     
      while(byteReader.hasRemaining()) {
        cur = byteReader.readByte();
        //0x0D 0x0A为行结束符
        if(last==0x0D && cur==0x0A) {
          end = true;
          break;
        }else if(last==BYTE_MASK) {
          last = cur;
        }else {
          byteWriter.writeByte(last);
          last = cur;
        }
      }
      if(end) {
        lineLast = BYTE_MASK;
        return ConvertHelper.byte2String(byteWriter.toByteArray());
      }else {
        lineLast = last;
        return null;
      }
     
    }
   
    /**
     * 读取所有消息头
     * @return        如果读取完毕返回true否则返回false
     */
    private boolean readSipcHeaders()
    {
      while(true) {
          String headline = this.readLine();
          if(headline==null) {
            lastAction = ACTION_READ_HEADER;
            return false;
          }else if(headline.length()==0) {
            lastAction = ACTION_NONE;
            return true;
          }else {
            curMessage.addHeader(new SipcHeader(headline));
          }
      }
    }
   
   
    /**
     * 读取消息体
     * @return    如果读取完毕返回true否则返回false
     */
    private boolean readSipcBody()
    {
      if(this.lastAction==ACTION_NONE) {
        if(this.curMessage.getContentLength()>0) {
          this.contentLeft = this.curMessage.getContentLength();
          this.byteWriter.clear();
        }else {
          lastAction = ACTION_NONE;
          return true;
        }
      }
     
      for(;byteReader.hasRemaining() && this.contentLeft>0; this.contentLeft--)
        this.byteWriter.writeByte((byteReader.readByte()));
      if(this.contentLeft==0) {
        this.curMessage.setBody(new SipcBody( ConvertHelper.byte2String(this.byteWriter.toByteArray())));
        this.lastAction = ACTION_NONE;
        return true;
      }else {
        this.lastAction = ACTION_READ_CONTENT;
        return false;
      }
    }
 
    /* (non-Javadoc)
     * @see net.solosky.net.maplefetion.chain.AbstractProcessor#processIncoming(java.lang.Object)
     */
    @Override
    public void processIncoming(Object o) throws FetionException
    {
      if(o instanceof ByteReader) {
        this.byteReader = (ByteReader) o;
        while(this.byteReader.hasRemaining()) {
          if(this.parseInMessage())
            this.flushInMessage();
        }
      }
    }

  /* (non-Javadoc)
     * @see net.solosky.net.maplefetion.chain.AbstractProcessor#processOutcoming(java.lang.Object)
     */
    @Override
    public void processOutcoming(Object o) throws FetionException
    {
    if(o instanceof SipcOutMessage) {
      SipcOutMessage out = (SipcOutMessage) o;
      this.flushOutMessage(this.parseOutMessage(out));
    }
    }
   
  @Override
    public String getProcessorName()
    {
      return "SipcParser";
    }

}
TOP

Related Classes of net.solosky.maplefetion.util.SipcParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.