java flash tcp字节流通信(一)-flash as3 协议(4)

1.数据包头

package com.net.tcp
{
 /**
  * 数据包头
  **/
 public class DataHead
 {
  /**包头长度*/
  public static const DATA_HEAD_LEN:uint = 4;
  
  private var _len:uint;
  public function DataHead()
  {
  }

  public function get len():uint
  {
   return _len;
  }

  public function set len(value:uint):void
  {
   _len = value;
  }

 }
}

2.数据内容

package com.net.tcp
{
 import flash.utils.ByteArray;
 import flash.utils.Proxy;
 import flash.utils.flash_proxy;

 /**
  * 数据内容
  **/
 public class DataContent extends ByteArray
 {
  public function rewind():void{
   this.position = 0;
  }
 }
}

 

3.完整数据包

package com.net.tcp
{
 import avmplus.getQualifiedClassName;
 
 import com.commons.utils.ClassUtils;
 import com.commons.utils.Map;
 
 import flash.utils.describeType;
 import flash.utils.getDefinitionByName;

 /**
  * 通信数据包
  **/
 public class DataPack
 {
  private var _head:DataHead;
  private var _content:DataContent;
  
  public function DataPack(content:DataContent = null, head:DataHead = null)
  {
   if(head == null){
    _head = new DataHead();
   }else{
    _head = head;
   }
   if(content == null){
    this.content = new DataContent();
   }else{
    this.content = content;
   }
  }
  
  public function get head():DataHead
  {
   return _head;
  }
  
  public function set content(value:DataContent):void
  {
   _content = value;
   _content.rewind();
   _head.len = _content.bytesAvailable;
  }
  
  public function get content():DataContent
  {
   return _content;
  }

  
  private function readType():int{
   return _content.readShort();
  }
  private function readValue(t:int = -1):*{
   var len:int = 0;
   var index:int = 0;
   var type:int = t == DataType.TYPE_ALL ? this.readType() : t;
   var f:String = null;
   var fv:Object = null;
   switch(type){
    case DataType.TYPE_NULL:
     return null;
    case DataType.TYPE_BYTE:
     return _content.readByte();
    case DataType.TYPE_SHORT:
     return _content.readShort();
    case DataType.TYPE_INT:
     return _content.readInt();
    case DataType.TYPE_DOUBLE:
     return _content.readDouble();
    case DataType.TYPE_BOOL:
     return _content.readBoolean();
    case DataType.TYPE_STRING:
     len = _content.readInt();
     return _content.readUTFBytes(len);
    case DataType.TYPE_STREAM_OBJECT:
     var so:StreamObject = StreamObject(StreamObjectManager.getObjectByClassName(this.readValue(DataType.TYPE_STRING)));
     so.decode(this);
     return so;
    case DataType.TYPE_ARRAY:
     len = _content.readInt();
     var array:Array = new Array();
     if(len > 0){
      var type1:int = this.readType();
      if(type1 == DataType.TYPE_STREAM_OBJECT){
       var name:String = this.readValue(DataType.TYPE_STRING);
       for(index = 0; index < len; index++){
        var item:StreamObject = StreamObject(StreamObjectManager.getObjectByClassName(name));
        item.decode(this);
        array.push(item);
       }
      }else{
       for(index = 0; index < len; index++){
        array.push(this.readValue(type1));
       }
      }
     }
     return array;
    case DataType.TYPE_MAP:
     len = _content.readInt();
     var map:Map = new Map();
     if(len > 0){
      for(index = 0; index < len; index++){
       f = this.readValue(DataType.TYPE_STRING);
       fv = this.readValue();
       map.put(f, fv);
      }
     }
     return map;
    case DataType.TYPE_OBJECT:
     len = _content.readInt();
     var object:Object = new Object();
     if(len > 0){
      for(index = 0; index < len; index++){
       f = this.readValue(DataType.TYPE_STRING);
       fv = this.readValue();
       object[f] = fv;
      }
     }
     return object;
    default:
     throw new Error("找不到解析类型...");
   }
  }
  
  public function readObject(t:int = -1):*{
   return this.readValue(t);
  }
  
  private function writeType(type:int):void{
   this.writeValue(type, false, [DataType.TYPE_SHORT]);
  }
  private function writeValue(value:Object, writeType:Boolean = false, types:Array = null):void{
   if(value == null){
    if(writeType){
     this.writeType(DataType.TYPE_NULL);
    }
   }else if(value is Number){
    if(writeType){
     this.writeType(types[0]);
    }
    var number:Number = Number(value);
    if(isNaN(number)){
     number = 0;
    }
    switch(types[0]){
     case DataType.TYPE_BYTE:
      _content.writeByte(number);
      break;
     case DataType.TYPE_SHORT:
      _content.writeShort(number);
      break;
     case DataType.TYPE_INT:
      _content.writeInt(number);
      break;
     case DataType.TYPE_DOUBLE:
      _content.writeDouble(number);
      break;
    }
   }else if(value is Boolean){
    if(writeType){
     this.writeType(DataType.TYPE_BOOL);
    }
    if(value)
     this.writeValue(1, false, [DataType.TYPE_BYTE]);
    else
     this.writeValue(0, false, [DataType.TYPE_BYTE]);
   }else if(value is String){
    if(writeType){
     this.writeType(DataType.TYPE_STRING);
    }
    var begin:uint = _content.position;
    this.writeValue(0, false, [DataType.TYPE_INT]);
    _content.writeUTFBytes(String(value));
    var end:uint = _content.position;
    _content.position = begin;
    this.writeValue(end - begin - 4, false, [DataType.TYPE_INT]);
    _content.position = end;
   }else if(value is StreamObject){
    if(writeType){
     this.writeType(DataType.TYPE_STREAM_OBJECT);
     this.writeValue(ClassUtils.getSimpleNameByObject(value), false, [DataType.TYPE_STRING]);
    }
    var so : StreamObject = value as StreamObject;
    so.encode(this);
   }else if(value is Array){
    if(writeType){
     this.writeType(DataType.TYPE_ARRAY);
    }
    var array:Array = value as Array;
    var len:int = array.length;
    this.writeValue(len, false, [DataType.TYPE_INT]);
    if(len > 0){
     if(value[0] is StreamObject){
      this.writeType(DataType.TYPE_STREAM_OBJECT);
      this.writeValue(ClassUtils.getSimpleNameByObject(value), false, [DataType.TYPE_STRING]);
      
     }else{
      if(types.length >= 1){
       this.writeType(types[1]);
      }else{
       if(value[0] is Number){
        this.writeType(DataType.TYPE_DOUBLE);
       }else if(value[0] is Array){
        this.writeType(DataType.TYPE_ARRAY);
       }else{
        this.writeType(DataType.TYPE_OBJECT);
       }
      }
     }
     var index:int = 0;
     var types1:Array = types.slice(1, types.length);
     for(index = 0; index < len; index++){
      this.writeValue(value[index], false, types1);
     }
    }
   }else if(value is Map){
    if(writeType){
     this.writeType(DataType.TYPE_MAP);
    }
    var map:Map = value as Map;
    this.writeValue(map.keys().length, false,  [DataType.TYPE_INT]);
    var v:Object = null;
    for each(var key:Object in map.keys()){
     v = map.get(key);
     this.writeValue(String(key), false,  [DataType.TYPE_STRING]);
     this.writeValue(v, true,  [DataType.getNumberTypeByObject(v)]);
    }
   }else{
    if(writeType){
     this.writeType(DataType.TYPE_OBJECT);
    }
    var size:int = 0;
    for(var f:String in value){
     size++;
    }
    this.writeValue(size, false, [DataType.TYPE_INT]);
    for(var name:String in value){
     this.writeValue(name, false, [DataType.TYPE_STRING]);
     this.writeValue(value[name], true, [DataType.getNumberTypeByObject(value[name])]);
    }
   }
  }
  
  private function validateObjectType(value:Object, type:int):Boolean{
   if(DataType.isNumberType(type)){
    if(!DataType.isNumberType(DataType.getNumberTypeByObject(value))){
     return false;
    }
    return true;
   }
   return true;
  }
  
  public function writeObject(value:Object, ...types):void{
   if(!this.validateObjectType(value, types[0])){
    throw new Error("解析对象类型和传入的对象类型不匹配...");
   }
   this.writeValue(value, true, types);
  }
  
  public function rewind():void{
   this.content.rewind();
   this.head.len = this.content.bytesAvailable;
  }
 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值